Skip to content

Commit 4b4ab1b

Browse files
Merge pull request #523 from mloit/feature/transaction-metadata
2 parents ff7ba8f + 11b8260 commit 4b4ab1b

File tree

5 files changed

+70
-22
lines changed

5 files changed

+70
-22
lines changed

Sources/web3swift/Transaction/EIP1559Envelope.swift

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
4141
public var maxFeePerGas: BigUInt
4242
public var accessList: [AccessListEntry] // from EIP-2930
4343

44-
/// EIP-1159 trnsactions do not have a gasPrice parameter
45-
/// However, it appears that some nodes report a gasPrice, even for EIP-1159 transactions
46-
/// thus for a temporary workaround we capture and store gasPrice if initialized from a JSON transaction
47-
/// decided form a node. This is currently needed for Oracle to work
48-
private var gasPrice: BigUInt = 0
49-
5044
// for CustomStringConvertible
5145
public var description: String {
5246
var toReturn = ""
@@ -76,9 +70,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
7670
value: value,
7771
data: data,
7872
gasLimit: gasLimit,
79-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
80-
gasPrice: gasPrice,
81-
8273
maxFeePerGas: maxFeePerGas,
8374
maxPriorityFeePerGas: maxPriorityFeePerGas,
8475
accessList: accessList
@@ -94,8 +85,6 @@ public struct EIP1559Envelope: EIP2718Envelope {
9485
maxFeePerGas = val.maxFeePerGas ?? maxFeePerGas
9586
maxPriorityFeePerGas = val.maxPriorityFeePerGas ?? maxPriorityFeePerGas
9687
accessList = val.accessList ?? accessList
97-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
98-
gasPrice = val.gasPrice ?? gasPrice
9988
}
10089
}
10190

@@ -117,8 +106,6 @@ extension EIP1559Envelope {
117106
case v
118107
case r
119108
case s
120-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
121-
case gasPrice
122109
}
123110

124111
public init?(from decoder: Decoder) throws {
@@ -147,9 +134,6 @@ extension EIP1559Envelope {
147134
self.to = ethAddr
148135
}
149136

150-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
151-
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice) ?? 5000000000
152-
153137
self.value = try container.decodeHexIfPresent(BigUInt.self, forKey: .value) ?? 0
154138
self.maxPriorityFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxPriorityFeePerGas) ?? 0
155139
self.maxFeePerGas = try container.decodeHexIfPresent(BigUInt.self, forKey: .maxFeePerGas) ?? 0
@@ -212,7 +196,7 @@ extension EIP1559Envelope {
212196

213197
// swiftlint:disable force_unwrapping
214198
switch rlpItem[RlpKey.destination.rawValue]!.content {
215-
// swiftlint:enable force_unwrapping
199+
// swiftlint:enable force_unwrapping
216200
case .noItem:
217201
self.to = EthereumAddress.contractDeploymentAddress()
218202
case .data(let addressData):
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Package: web3swift
2+
// Created by Alex Vlasov.
3+
// Copyright © 2018 Alex Vlasov. All rights reserved.
4+
//
5+
// Additions for metadata by Mark Loit 2022
6+
7+
import Foundation
8+
import BigInt
9+
10+
/// This structure holds additional data
11+
/// returned by nodes when reading a transaction
12+
/// from the blockchain. The data here is not
13+
/// part of the transaction itself
14+
public struct EthereumMetadata {
15+
16+
/// hash for the block that contains this transaction on chain
17+
var blockHash: Data?
18+
19+
/// block number for the block containing this transaction on chain
20+
var blockNumber: BigUInt?
21+
22+
/// index for this transaction within the containing block
23+
var transactionIndex: UInt?
24+
25+
/// hash for this transaction as returned by the node [not computed]
26+
/// this can be used for validation against the computed hash returned
27+
/// by the transaction envelope.
28+
var transactionHash: Data?
29+
30+
/// gasPrice value returned by the node
31+
/// note this is a duplicate value for legacy and EIP-2930 transaction types
32+
/// but is included here since EIP-1559 does not contain a `gasPrice`, but
33+
/// nodes still report the value.
34+
var gasPrice: BigUInt?
35+
}
36+
37+
public extension EthereumMetadata {
38+
private enum CodingKeys: String, CodingKey {
39+
case blockHash
40+
case blockNumber
41+
case transactionIndex
42+
case transactionHash
43+
case gasPrice
44+
}
45+
46+
/// since metadata realistically can only come when a transaction is created from
47+
/// JSON returned by a node, we only provide an intializer from JSON
48+
init(from decoder: Decoder) throws {
49+
let container = try decoder.container(keyedBy: CodingKeys.self)
50+
51+
self.blockHash = try container.decodeHexIfPresent(Data.self, forKey: .blockHash)
52+
self.transactionHash = try container.decodeHexIfPresent(Data.self, forKey: .transactionHash)
53+
self.transactionIndex = try container.decodeHexIfPresent(UInt.self, forKey: .transactionIndex)
54+
self.blockNumber = try container.decodeHexIfPresent(BigUInt.self, forKey: .blockNumber)
55+
self.gasPrice = try container.decodeHexIfPresent(BigUInt.self, forKey: .gasPrice)
56+
}
57+
}

Sources/web3swift/Transaction/EthereumTransaction.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public struct EthereumTransaction: CustomStringConvertible {
1414
/// and type specific implementation
1515
internal var envelope: AbstractEnvelope
1616

17+
/// storage container for additional metadata returned by the node
18+
/// when a transaction is decoded form a JSON stream
19+
public var meta: EthereumMetadata?
20+
1721
// convenience accessors to the common envelope fields
1822
// everything else should come from getOpts/setOpts
1923
/// The type of the transacton being represented, see TransactionType enum
@@ -227,6 +231,8 @@ extension EthereumTransaction: Decodable {
227231
public init(from decoder: Decoder) throws {
228232
guard let env = try EnvelopeFactory.createEnvelope(from: decoder) else { throw Web3Error.dataError }
229233
self.envelope = env
234+
// capture any metadata that might be present
235+
self.meta = try EthereumMetadata(from: decoder)
230236
}
231237
}
232238

@@ -330,10 +336,7 @@ extension EthereumTransaction {
330336
guard let env = self.envelope as? EIP2930Envelope else { preconditionFailure("Unable to downcast to EIP2930Envelope") }
331337
return env.parameters.gasPrice ?? 0
332338
case .eip1559:
333-
// MARK: workaround for gasPrice coming from nodes for EIP-1159 - this allows Oracle to work for now
334-
guard let env = self.envelope as? EIP1559Envelope else { preconditionFailure("Unable to downcast to EIP1559Envelope") }
335-
return env.parameters.gasPrice ?? 0
336-
// preconditionFailure("EIP1559Envelope has no member gasPrice")
339+
preconditionFailure("EIP1559Envelope has no member gasPrice")
337340
}
338341
}
339342
set(value) {

Sources/web3swift/Web3/Web3+GasOracle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ extension Web3 {
139139
return transaction
140140
}
141141
}
142-
.map { $0.gasPrice }
142+
.map { $0.meta?.gasPrice ?? 0 }
143143

144144
return calculatePercentiles(for: lastNthBlockGasPrice)
145145
}

web3swift.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
6049F416280616FC00DFE624 /* LegacyEnvelope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */; };
203203
6049F4182806171300DFE624 /* Web3+Signing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049F4172806171300DFE624 /* Web3+Signing.swift */; };
204204
604FA4FF27ECBDC80021108F /* DataConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604FA4FE27ECBDC80021108F /* DataConversionTests.swift */; };
205+
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */; };
205206
CB50A52827060BD600D7E39B /* EIP712Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB50A52727060BD600D7E39B /* EIP712Tests.swift */; };
206207
D606A56B279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */; };
207208
D6A3D9B827F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A3D9B727F1E785009E3BCF /* ABIEncoderSoliditySha3Test.swift */; };
@@ -433,6 +434,7 @@
433434
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyEnvelope.swift; sourceTree = "<group>"; };
434435
6049F4172806171300DFE624 /* Web3+Signing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Web3+Signing.swift"; sourceTree = "<group>"; };
435436
604FA4FE27ECBDC80021108F /* DataConversionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataConversionTests.swift; sourceTree = "<group>"; };
437+
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumMetadata.swift; sourceTree = "<group>"; };
436438
CB50A52727060BD600D7E39B /* EIP712Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712Tests.swift; sourceTree = "<group>"; };
437439
CB50A52927060C5300D7E39B /* EIP712.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP712.swift; sourceTree = "<group>"; };
438440
D606A56A279F5D59003643ED /* web3swiftDecodeSolidityErrorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = web3swiftDecodeSolidityErrorType.swift; sourceTree = "<group>"; };
@@ -720,6 +722,7 @@
720722
6049F40F280616FC00DFE624 /* LegacyEnvelope.swift */,
721723
3AA8153D2276E44100F5DB52 /* BloomFilter.swift */,
722724
3AA8153F2276E44100F5DB52 /* EthereumTransaction.swift */,
725+
60C1786D2809BA0C0083F064 /* EthereumMetadata.swift */,
723726
);
724727
path = Transaction;
725728
sourceTree = "<group>";
@@ -1349,6 +1352,7 @@
13491352
3AA815C12276E44100F5DB52 /* Web3+BrowserFunctions.swift in Sources */,
13501353
3AA815E82276E44100F5DB52 /* Extensions.swift in Sources */,
13511354
3AA815FE2276E44100F5DB52 /* Web3+ERC820.swift in Sources */,
1355+
60C1786E2809BA0C0083F064 /* EthereumMetadata.swift in Sources */,
13521356
3AA815DB2276E44100F5DB52 /* Web3+TxPool.swift in Sources */,
13531357
3AA8160A2276E44100F5DB52 /* Web3+ERC1594.swift in Sources */,
13541358
3AA815FB2276E44100F5DB52 /* Promise+Web3+Personal+UnlockAccount.swift in Sources */,

0 commit comments

Comments
 (0)