Skip to content

Commit

Permalink
Merge pull request #797 from JeneaVranceanu/feat/transaction-awaiting
Browse files Browse the repository at this point in the history
feat: transaction polling task
  • Loading branch information
JeneaVranceanu authored Mar 13, 2023
2 parents fd931fa + 28b1334 commit f909499
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
66 changes: 66 additions & 0 deletions Sources/web3swift/Transaction/TransactionPollingTask.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// TransactionPollingTask.swift
//
// Created by JeneaVranceanu on 10.03.2023.
//

import Foundation
import Web3Core

/// Monitors a transaction's state on blockchain until transaction is completed successfully or not.
final public class TransactionPollingTask {

private enum DelayUnit: UInt64 {
case shortest = 1
case medium = 5
case longest = 60

func shouldIncreaseDelay(_ startTime: Date) -> Bool {
let timePassed = Date().timeIntervalSince1970 - startTime.timeIntervalSince1970
switch self {
case .shortest:
return timePassed > 10
case .medium:
return timePassed > 120
case .longest:
return false
}
}

var nextDelayUnit: DelayUnit {
switch self {
case .shortest:
return .medium
case .medium, .longest:
return .longest
}
}
}

public let transactionHash: Data

private let web3Instance: Web3
private var delayUnit: DelayUnit = .shortest

public init(transactionHash: Data, web3Instance: Web3) {
self.transactionHash = transactionHash
self.web3Instance = web3Instance
}

public func wait() async throws -> TransactionReceipt {
let startTime = Date()
while true {
let transactionReceipt = try await web3Instance.eth.transactionReceipt(transactionHash)

if transactionReceipt.status != .notYetProcessed {
return transactionReceipt
}

if delayUnit.shouldIncreaseDelay(startTime) {
delayUnit = delayUnit.nextDelayUnit
}

try await Task.sleep(nanoseconds: delayUnit.rawValue)
}
}
}
33 changes: 33 additions & 0 deletions Tests/web3swiftTests/localTests/TransactionPollingTaskTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// TransactionPollingTaskTest.swift
//
// Created by JeneaVranceanu on 10.03.2023.
//

import XCTest
import Foundation
@testable import web3swift
@testable import Web3Core

class TransactionPollingTaskTest: LocalTestCase {

func testTransactionPolling() async throws {
let web3 = try await Web3.new(LocalTestCase.url)
let sendToAddress = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")!
let allAddresses = try await web3.eth.ownedAccounts()
let contract = web3.contract(Web3.Utils.coldWalletABI, at: sendToAddress)
let writeTX = contract!.createWriteOperation("fallback")!
writeTX.transaction.from = allAddresses[0]
writeTX.transaction.value = 1

let policies = Policies(gasLimitPolicy: .automatic)
let result = try await writeTX.writeToChain(password: "", policies: policies, sendRaw: false)

let txHash = Data.fromHex(result.hash.stripHexPrefix())!

let transactionReceipt = try await TransactionPollingTask(transactionHash: txHash, web3Instance: web3).wait()

XCTAssertEqual(transactionReceipt.status, .ok)
}

}

0 comments on commit f909499

Please sign in to comment.