Skip to content

Commit f909499

Browse files
Merge pull request #797 from JeneaVranceanu/feat/transaction-awaiting
feat: transaction polling task
2 parents fd931fa + 28b1334 commit f909499

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// TransactionPollingTask.swift
3+
//
4+
// Created by JeneaVranceanu on 10.03.2023.
5+
//
6+
7+
import Foundation
8+
import Web3Core
9+
10+
/// Monitors a transaction's state on blockchain until transaction is completed successfully or not.
11+
final public class TransactionPollingTask {
12+
13+
private enum DelayUnit: UInt64 {
14+
case shortest = 1
15+
case medium = 5
16+
case longest = 60
17+
18+
func shouldIncreaseDelay(_ startTime: Date) -> Bool {
19+
let timePassed = Date().timeIntervalSince1970 - startTime.timeIntervalSince1970
20+
switch self {
21+
case .shortest:
22+
return timePassed > 10
23+
case .medium:
24+
return timePassed > 120
25+
case .longest:
26+
return false
27+
}
28+
}
29+
30+
var nextDelayUnit: DelayUnit {
31+
switch self {
32+
case .shortest:
33+
return .medium
34+
case .medium, .longest:
35+
return .longest
36+
}
37+
}
38+
}
39+
40+
public let transactionHash: Data
41+
42+
private let web3Instance: Web3
43+
private var delayUnit: DelayUnit = .shortest
44+
45+
public init(transactionHash: Data, web3Instance: Web3) {
46+
self.transactionHash = transactionHash
47+
self.web3Instance = web3Instance
48+
}
49+
50+
public func wait() async throws -> TransactionReceipt {
51+
let startTime = Date()
52+
while true {
53+
let transactionReceipt = try await web3Instance.eth.transactionReceipt(transactionHash)
54+
55+
if transactionReceipt.status != .notYetProcessed {
56+
return transactionReceipt
57+
}
58+
59+
if delayUnit.shouldIncreaseDelay(startTime) {
60+
delayUnit = delayUnit.nextDelayUnit
61+
}
62+
63+
try await Task.sleep(nanoseconds: delayUnit.rawValue)
64+
}
65+
}
66+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//
2+
// TransactionPollingTaskTest.swift
3+
//
4+
// Created by JeneaVranceanu on 10.03.2023.
5+
//
6+
7+
import XCTest
8+
import Foundation
9+
@testable import web3swift
10+
@testable import Web3Core
11+
12+
class TransactionPollingTaskTest: LocalTestCase {
13+
14+
func testTransactionPolling() async throws {
15+
let web3 = try await Web3.new(LocalTestCase.url)
16+
let sendToAddress = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")!
17+
let allAddresses = try await web3.eth.ownedAccounts()
18+
let contract = web3.contract(Web3.Utils.coldWalletABI, at: sendToAddress)
19+
let writeTX = contract!.createWriteOperation("fallback")!
20+
writeTX.transaction.from = allAddresses[0]
21+
writeTX.transaction.value = 1
22+
23+
let policies = Policies(gasLimitPolicy: .automatic)
24+
let result = try await writeTX.writeToChain(password: "", policies: policies, sendRaw: false)
25+
26+
let txHash = Data.fromHex(result.hash.stripHexPrefix())!
27+
28+
let transactionReceipt = try await TransactionPollingTask(transactionHash: txHash, web3Instance: web3).wait()
29+
30+
XCTAssertEqual(transactionReceipt.status, .ok)
31+
}
32+
33+
}

0 commit comments

Comments
 (0)