Skip to content

Commit 7b5284c

Browse files
Working with resolving all policies on transaction send.
1 parent 6c9321d commit 7b5284c

File tree

5 files changed

+79
-119
lines changed

5 files changed

+79
-119
lines changed

Sources/Core/Transaction/CodableTransaction.swift

Lines changed: 45 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public protocol CodableTransactionInheritable {
1616
/// while all fields in this struct are optional, they are not necessarily
1717
/// optional for the type of transaction they apply to.
1818
public struct CodableTransaction {
19+
public typealias NoncePolicy = BlockNumber
1920
/// internal acccess only. The transaction envelope object itself that contains all the transaction data
2021
/// and type specific implementation
2122
internal var envelope: AbstractEnvelope
@@ -45,12 +46,6 @@ public struct CodableTransaction {
4546
/// this should always be set to give an idea of what other fields to expect
4647
public var type: TransactionType { return envelope.type }
4748

48-
/// the nonce for the transaction
49-
public var nonce: BigUInt {
50-
get { return envelope.nonce }
51-
set { envelope.nonce = newValue }
52-
}
53-
5449
/// the chainId that transaction is targeted for
5550
/// should be set for all types, except some Legacy transactions (Pre EIP-155)
5651
/// will not have this set
@@ -71,21 +66,27 @@ public struct CodableTransaction {
7166

7267
// MARK: - Properties transaction type related either sends to a node if exist
7368

69+
/// the nonce for the transaction
70+
public internal (set) var nonce: BigUInt {
71+
get { return envelope.nonce }
72+
set { envelope.nonce = newValue }
73+
}
74+
7475
/// the max number of gas units allowed to process this transaction
75-
public var gasLimit: BigUInt {
76+
public internal (set) var gasLimit: BigUInt {
7677
get { return envelope.gasLimit }
7778
set { return envelope.gasLimit = newValue }
7879
}
7980

8081
/// the price per gas unit for the tranaction (Legacy and EIP-2930 only)
81-
public var gasPrice: BigUInt?
82+
public internal (set) var gasPrice: BigUInt?
8283

8384
/// the max base fee per gas unit (EIP-1559 only)
8485
/// this value must be >= baseFee + maxPriorityFeePerGas
85-
public var maxFeePerGas: BigUInt?
86+
public internal (set) var maxFeePerGas: BigUInt?
8687

8788
/// the maximum tip to pay the miner (EIP-1559 only)
88-
public var maxPriorityFeePerGas: BigUInt?
89+
public internal (set) var maxPriorityFeePerGas: BigUInt?
8990

9091
public var callOnBlock: BlockNumber?
9192

@@ -109,10 +110,8 @@ public struct CodableTransaction {
109110
return hash
110111
}
111112

112-
// FIXME: This should made private up to release
113113
private init() { preconditionFailure("Memberwise not supported") } // disable the memberwise initializer
114114

115-
116115
/// - Returns: a hash of the transaction suitable for signing
117116
public func hashForSignature() -> Data? {
118117
guard let encoded = self.envelope.encode(for: .signature) else { return nil }
@@ -135,6 +134,8 @@ public struct CodableTransaction {
135134
}
136135

137136
/// Signs the transaction
137+
///
138+
/// This method signs transaction iteself and not related to contract call data signing.
138139
/// - Parameters:
139140
/// - privateKey: the private key to use for signing
140141
/// - useExtraEntropy: boolean whether to use extra entropy when signing (default false)
@@ -164,49 +165,43 @@ public struct CodableTransaction {
164165
self.envelope.clearSignatureData()
165166
}
166167

167-
/// Descriptionconverts transaction to the new selected type
168-
/// - Parameter to: TransactionType to select what transaction type to convert to
169-
public mutating func migrate(to type: TransactionType) {
170-
if self.type == type { return }
171-
172-
// FIXME: Move it back
173-
// let newEnvelope = EnvelopeFactory.createEnvelope(type: type, to: self.envelope.to,
174-
// nonce: self.envelope.nonce)
175-
// self.envelope = newEnvelope
176-
}
177-
178168
/// Create a new CodableTransaction from a raw stream of bytes from the blockchain
179169
public init?(rawValue: Data) {
180170
guard let env = EnvelopeFactory.createEnvelope(rawValue: rawValue) else { return nil }
181171
self.envelope = env
182172
// FIXME: This is duplication and should be fixed.
183173
data = Data()
174+
noncePolicy = .latest
175+
gasLimitPolicy = .automatic
176+
gasPricePolicy = .automatic
177+
maxFeePerGasPolicy = .automatic
178+
maxPriorityFeePerGasPolicy = .automatic
184179
}
185180

186181
/// - Returns: a raw bytestream of the transaction, encoded according to the transactionType
187182
public func encode(for type: EncodeType = .transaction) -> Data? {
188183
return self.envelope.encode(for: type)
189184
}
190185

191-
public mutating func applyOptions(_ options: CodableTransaction) {
192-
// type cannot be changed here, and is ignored
193-
// FIXME: Add appropiate values of resolveAny
194-
self.nonce = options.resolveNonce(nonce)
195-
self.gasPrice = options.resolveGasPrice(gasPrice ?? 0)
196-
self.gasLimit = options.resolveGasLimit(gasLimit)
197-
self.maxFeePerGas = options.resolveMaxFeePerGas(maxFeePerGas ?? 0)
198-
self.maxPriorityFeePerGas = options.resolveMaxPriorityFeePerGas(maxPriorityFeePerGas ?? 0)
199-
self.value = options.value ?? value
200-
self.from = options.from
201-
self.to = options.to ?? to
202-
self.accessList = options.accessList
203-
}
204-
205-
public var noncePolicy: NoncePolicy?
206-
public var maxFeePerGasPolicy: FeePerGasPolicy?
207-
public var maxPriorityFeePerGasPolicy: FeePerGasPolicy?
208-
public var gasPricePolicy: GasPricePolicy?
209-
public var gasLimitPolicy: GasLimitPolicy?
186+
// public mutating func resolve() {
187+
// // type cannot be changed here, and is ignored
188+
// // FIXME: Add appropiate values of resolveAny
189+
// self.nonce = options.resolveNonce(nonce)
190+
// self.gasPrice = options.resolveGasPrice(gasPrice ?? 0)
191+
// self.gasLimit = options.resolveGasLimit(gasLimit)
192+
// self.maxFeePerGas = options.resolveMaxFeePerGas(maxFeePerGas ?? 0)
193+
// self.maxPriorityFeePerGas = options.resolveMaxPriorityFeePerGas(maxPriorityFeePerGas ?? 0)
194+
// self.value = options.value ?? value
195+
// self.from = options.from
196+
// self.to = options.to ?? to
197+
// self.accessList = options.accessList
198+
// }
199+
200+
public var noncePolicy: NoncePolicy
201+
public var maxFeePerGasPolicy: FeePerGasPolicy
202+
public var maxPriorityFeePerGasPolicy: FeePerGasPolicy
203+
public var gasPricePolicy: GasPricePolicy
204+
public var gasLimitPolicy: GasLimitPolicy
210205

211206
public static var emptyTransaction = CodableTransaction(to: EthereumAddress.contractDeploymentAddress())
212207
}
@@ -235,6 +230,12 @@ extension CodableTransaction: Codable {
235230
// FIXME: This is duplication and should be fixed.
236231
data = Data()
237232

233+
noncePolicy = .latest
234+
gasLimitPolicy = .automatic
235+
gasPricePolicy = .automatic
236+
maxFeePerGasPolicy = .automatic
237+
maxPriorityFeePerGasPolicy = .automatic
238+
238239
// capture any metadata that might be present
239240
self.meta = try EthereumMetadata(from: decoder)
240241
}
@@ -303,24 +304,16 @@ extension CodableTransaction {
303304
case manual(BigUInt)
304305
}
305306

306-
public enum NoncePolicy {
307-
case pending
308-
case latest
309-
case manual(BigUInt)
310-
}
311-
312307
public func resolveNonce(_ suggestedByNode: BigUInt) -> BigUInt {
313-
guard let noncePolicy = self.noncePolicy else { return suggestedByNode }
314308
switch noncePolicy {
315-
case .pending, .latest:
309+
case .pending, .latest, .earliest:
316310
return suggestedByNode
317-
case .manual(let value):
311+
case .exact(let value):
318312
return value
319313
}
320314
}
321315

322316
public func resolveGasPrice(_ suggestedByNode: BigUInt) -> BigUInt {
323-
guard let gasPricePolicy = self.gasPricePolicy else { return suggestedByNode }
324317
switch gasPricePolicy {
325318
case .automatic, .withMargin:
326319
return suggestedByNode
@@ -330,7 +323,6 @@ extension CodableTransaction {
330323
}
331324

332325
public func resolveGasLimit(_ suggestedByNode: BigUInt) -> BigUInt {
333-
guard let gasLimitPolicy = self.gasLimitPolicy else { return suggestedByNode }
334326
switch gasLimitPolicy {
335327
case .automatic, .withMargin:
336328
return suggestedByNode
@@ -346,7 +338,6 @@ extension CodableTransaction {
346338
}
347339

348340
public func resolveMaxFeePerGas(_ suggestedByNode: BigUInt) -> BigUInt {
349-
guard let maxFeePerGasPolicy = self.maxFeePerGasPolicy else { return suggestedByNode }
350341
switch maxFeePerGasPolicy {
351342
case .automatic:
352343
return suggestedByNode
@@ -356,42 +347,13 @@ extension CodableTransaction {
356347
}
357348

358349
public func resolveMaxPriorityFeePerGas(_ suggestedByNode: BigUInt) -> BigUInt {
359-
guard let maxPriorityFeePerGasPolicy = self.maxPriorityFeePerGasPolicy else { return suggestedByNode }
360350
switch maxPriorityFeePerGasPolicy {
361351
case .automatic:
362352
return suggestedByNode
363353
case .manual(let value):
364354
return value
365355
}
366356
}
367-
368-
public func merge(_ otherOptions: CodableTransaction?) -> CodableTransaction {
369-
guard let other = otherOptions else { return self }
370-
var opts = CodableTransaction.emptyTransaction
371-
// opts.type = mergeIfNotNil(first: self.type, second: other.type)
372-
373-
opts.from = mergeIfNotNil(first: self.from, second: other.from)
374-
opts.chainID = mergeIfNotNil(first: self.chainID, second: other.chainID)
375-
opts.gasLimitPolicy = mergeIfNotNil(first: self.gasLimitPolicy, second: other.gasLimitPolicy)
376-
opts.gasPricePolicy = mergeIfNotNil(first: self.gasPricePolicy, second: other.gasPricePolicy)
377-
opts.maxFeePerGasPolicy = mergeIfNotNil(first: self.maxFeePerGasPolicy, second: other.maxFeePerGasPolicy)
378-
opts.maxPriorityFeePerGasPolicy = mergeIfNotNil(first: self.maxPriorityFeePerGasPolicy, second: other.maxPriorityFeePerGasPolicy)
379-
// opts.value = mergeIfNotNil(first: self.value, second: other.value)
380-
opts.noncePolicy = mergeIfNotNil(first: self.noncePolicy, second: other.noncePolicy)
381-
opts.callOnBlock = mergeIfNotNil(first: self.callOnBlock, second: other.callOnBlock)
382-
return opts
383-
}
384-
385-
/// Merges two sets of options by overriding the parameters from the first set by parameters from the second
386-
/// set if those are not nil.
387-
///
388-
/// Returns default options if both parameters are nil.
389-
public static func merge(_ options: CodableTransaction?, with other: CodableTransaction?) -> CodableTransaction? {
390-
var newOptions = CodableTransaction.emptyTransaction // default has lowest priority
391-
newOptions = newOptions.merge(options)
392-
newOptions = newOptions.merge(other) // other has highest priority
393-
return newOptions
394-
}
395357
}
396358

397359

Sources/web3swift/EthereumAPICalls/Ethereum/Eth+EstimateGas.swift

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@ extension web3.Eth {
1212
public func estimateGas(for transaction: CodableTransaction, onBlock: BlockNumber = .latest) async throws -> BigUInt {
1313
let request: APIRequest = .estimateGas(transaction, onBlock)
1414
let response: APIResponse<BigUInt> = try await APIRequest.sendRequest(with: provider, for: request)
15-
16-
if let policy = transaction.gasLimitPolicy {
17-
switch policy {
18-
case .automatic:
19-
return response.result
20-
case .limited(let limitValue):
21-
return limitValue < response.result ? limitValue: response.result
22-
case .manual(let exactValue):
23-
return exactValue
24-
case .withMargin:
25-
// MARK: - update value according margin
26-
return response.result
27-
}
28-
} else {
15+
16+
switch transaction.gasLimitPolicy {
17+
case .automatic:
18+
return response.result
19+
case .limited(let limitValue):
20+
return limitValue < response.result ? limitValue: response.result
21+
case .manual(let exactValue):
22+
return exactValue
23+
case .withMargin:
24+
// MARK: - update value according margin
2925
return response.result
3026
}
3127
}

Sources/web3swift/HookedFunctions/Web3+BrowserFunctions.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,26 +121,26 @@ extension web3.BrowserFunctions {
121121
// return (nil, nil)
122122
// }
123123
// }
124-
125-
// FIXME: Rewrite this to CodableTransaction
126-
public func prepareTxForApproval(_ trans: CodableTransaction, options opts: CodableTransaction) async throws -> (transaction: CodableTransaction?, options: CodableTransaction?) {
127-
do {
128-
var transaction = trans
129-
var options = opts
130-
guard let _ = options.from else {return (nil, nil)}
131-
let gasPrice = try await self.web3.eth.gasPrice()
132-
transaction.gasPrice = gasPrice
133-
options.gasPricePolicy = .manual(gasPrice)
134-
guard let gasEstimate = await self.estimateGas(transaction) else {return (nil, nil)}
135-
transaction.gasLimit = gasEstimate
136-
137-
options.gasLimitPolicy = .limited(gasEstimate)
138-
print(transaction)
139-
return (transaction, options)
140-
} catch {
141-
return (nil, nil)
142-
}
143-
}
124+
//
125+
// // FIXME: Rewrite this to CodableTransaction
126+
// public func prepareTxForApproval(_ trans: CodableTransaction, options opts: CodableTransaction) async throws -> (transaction: CodableTransaction?, options: CodableTransaction?) {
127+
// do {
128+
// var transaction = trans
129+
// var options = opts
130+
// guard let _ = options.from else {return (nil, nil)}
131+
// let gasPrice = try await self.web3.eth.gasPrice()
132+
// transaction.gasPrice = gasPrice
133+
// options.gasPricePolicy = .manual(gasPrice)
134+
// guard let gasEstimate = await self.estimateGas(transaction) else {return (nil, nil)}
135+
// transaction.gasLimit = gasEstimate
136+
//
137+
// options.gasLimitPolicy = .limited(gasEstimate)
138+
// print(transaction)
139+
// return (transaction, options)
140+
// } catch {
141+
// return (nil, nil)
142+
// }
143+
// }
144144

145145
// // FIXME: Rewrite this to CodableTransaction
146146
// public func signTransaction(_ transactionJSON: [String: Any], password: String ) async -> String? {

Sources/web3swift/Operations/WriteOperation.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ public class WriteOperation: ReadOperation {
3636
return try await self.web3.eth.getTransactionCount(for: from, onBlock: .latest)
3737
case .pending:
3838
return try await self.web3.eth.getTransactionCount(for: from, onBlock: .pending)
39-
case .manual(let nonce):
39+
case .earliest:
40+
return try await self.web3.eth.getTransactionCount(for: from, onBlock: .earliest)
41+
case .exact(let nonce):
4042
return nonce
4143
}
4244
}

Sources/web3swift/Utils/Hooks/NonceMiddleware.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extension Web3.Utils {
6666
// var modifiedTX = tx
6767
// modifiedTX.nonce = newNonce
6868
var newOptions = transactionOptions
69-
newOptions.noncePolicy = .manual(newNonce)
69+
newOptions.noncePolicy = .exact(newNonce)
7070
return (tx, contract, newOptions, true)
7171
}
7272

0 commit comments

Comments
 (0)