Skip to content

Commit 06d0361

Browse files
Make TestBlockGasLimit working
- Change verifyGasLimit method API - Change verifyEip1559Block method API - Change calcBaseFee method API - Implement ChainVersion enum for mainnet and made it Comparable - Implement getChainVersion(of:) method - Add chainVersion for Block struct
1 parent ce9837e commit 06d0361

File tree

3 files changed

+118
-44
lines changed

3 files changed

+118
-44
lines changed

Sources/web3swift/Web3/Web3+EIP1559.swift

Lines changed: 94 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,18 @@ import BigInt
1515
///
1616
/// Additional info about base fee options: https://ethereum.org/en/developers/docs/gas/#post-london
1717
public extension Web3 {
18-
func verifyGasLimit(parentGasLimit: BigUInt, currentGasLimit: BigUInt) throws -> Bool {
18+
func verifyGasLimit(parentGasLimit: BigUInt, currentGasLimit: BigUInt) -> Bool {
1919
var diff = BigInt(parentGasLimit) - BigInt(currentGasLimit)
2020

21-
if diff < 0 { diff *= -1 }
21+
diff = diff < 0 ? diff * -1 : diff
2222

2323
let limit = parentGasLimit / Web3.GasLimitBoundDivisor
2424

25-
// TODO: Make error more descriptiove
26-
// "invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1)
27-
if BigUInt(diff) >= limit { throw Web3Error.unknownError }
25+
// Check that gas limit below upper bound
26+
if BigUInt(diff) >= limit { return false }
2827

29-
// TODO: Make error more descriptiove
30-
// return errors.New("invalid gas limit below 5000")
31-
if currentGasLimit < Web3.MinGasLimit { throw Web3Error.unknownError }
28+
// Check that gas limit above lower bound
29+
if currentGasLimit < Web3.MinGasLimit { return false }
3230

3331
return true
3432
}
@@ -38,29 +36,29 @@ public extension Web3 {
3836
/// - basefee check
3937
/// This function make checks that this given block is valid post EIP-1559 block and returns true if it is
4038
/// and thors an error if it isn't.
41-
func verifyEip1559Block(chain version: ChainVersion, parent: Block, current: Block) throws -> Bool {
39+
func verifyEip1559Block(parent: Block, current: Block) -> Bool {
4240
var parentGasLimit = parent.gasLimit
43-
if version != .London {
41+
if parent.chainVersion != .London {
4442
parentGasLimit = parent.gasLimit * Web3.ElasticityMultiplier
4543
}
4644

47-
_ = try verifyGasLimit(parentGasLimit: parentGasLimit, currentGasLimit: current.gasLimit)
45+
guard verifyGasLimit(parentGasLimit: parentGasLimit, currentGasLimit: current.gasLimit) else { return false }
4846

4947
// ??? In go implementation this field is optional
5048
// if current.baseFeePerGas == nil { throw Web3Error.unknownError }
5149

52-
let expectedBaseFeePerGas = self.calcBaseFee(chain: version, parent: parent)
50+
let expectedBaseFeePerGas = self.calcBaseFee(parent)
5351

5452
// TODO: Make all errors trows more descriptive errors
5553
// ("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d", expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed)
56-
guard expectedBaseFeePerGas == current.baseFeePerGas else { throw Web3Error.unknownError }
54+
guard expectedBaseFeePerGas == current.baseFeePerGas else { return false }
5755

5856
return true
5957
}
6058

61-
func calcBaseFee(chain version: ChainVersion, parent: Block) -> BigUInt {
59+
func calcBaseFee(_ parent: Block) -> BigUInt {
6260
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
63-
guard version == .London else { return Web3.InitialBaseFee }
61+
guard parent.chainVersion == .London else { return Web3.InitialBaseFee }
6462

6563
let parentGasTarget = parent.gasLimit / Web3.ElasticityMultiplier
6664

@@ -87,24 +85,95 @@ public extension Web3 {
8785
}
8886

8987
public extension Web3 {
90-
enum ChainVersion {
91-
/// Byzantium switch block
88+
enum ChainVersion: BigUInt {
89+
/// Byzantium switch block
90+
///
91+
/// Date: 16.10.2017
92+
///
93+
/// Block number: 4_370_000
9294
case Byzantium
93-
/// Constantinople switch block
95+
/// Constantinople switch block
96+
///
97+
/// Date: 27.11.2019
98+
///
99+
/// Block number: 7_280_000
94100
case Constantinople
95-
/// Petersburg switch block
101+
/// Petersburg switch block
102+
///
103+
/// Date: 27.11.2019
104+
///
105+
/// Block number: 7_280_000
96106
case Petersburg
97-
/// Istanbul switch block
107+
/// Istanbul switch block
108+
///
109+
/// Date: 07.12.2019
110+
///
111+
/// Block number: 9_069_000
98112
case Istanbul
99-
/// Eip-2384 (bomb delay) switch block
113+
/// Eip-2384 (bomb delay) switch block
114+
///
115+
/// Date: 01.01.2020
116+
///
117+
/// Block number: 9_200_000
100118
case MuirGlacier
101-
/// Berlin switch block
119+
/// Berlin switch block
120+
///
121+
/// Date: 15.04.2021
122+
///
123+
/// Block number: 12_244_000
102124
case Berlin
103-
/// London switch block
125+
/// London switch block
126+
///
127+
/// Date: 05.08.2021
128+
///
129+
/// Block number: 12_965_000
104130
case London
105-
/// Eip-4345 (bomb delay) switch block
131+
/// Eip-4345 (bomb delay) switch block
132+
///
133+
/// Date: 09.12.2021
134+
///
135+
/// Block number: 13_773_000
106136
case ArrowGlacier
107-
case MergeFork
137+
138+
var blockNumber: BigUInt {
139+
switch self {
140+
case .Byzantium: return 4_370_000
141+
case .Constantinople: return 7_280_000
142+
case .Petersburg: return 7_280_000
143+
case .Istanbul: return 9_069_000
144+
case .MuirGlacier: return 9_200_000
145+
case .Berlin: return 12_244_000
146+
case .London: return 12_965_000
147+
case .ArrowGlacier: return 13_773_000
148+
}
149+
}
150+
}
151+
152+
static func getChainVersion(of block: BigUInt) -> ChainVersion {
153+
// Iterate given block number over each ChainVersion block numbers
154+
// to get the block's ChainVersion.
155+
if block < ChainVersion.Constantinople.blockNumber {
156+
return .Byzantium
157+
// ~= means included in a given range
158+
} else if ChainVersion.Constantinople.blockNumber..<ChainVersion.Istanbul.blockNumber ~= block {
159+
return .Constantinople
160+
} else if ChainVersion.Istanbul.blockNumber..<ChainVersion.MuirGlacier.blockNumber ~= block {
161+
return .Istanbul
162+
} else if ChainVersion.MuirGlacier.blockNumber..<ChainVersion.Berlin.blockNumber ~= block {
163+
return .MuirGlacier
164+
} else if ChainVersion.Berlin.blockNumber..<ChainVersion.London.blockNumber ~= block {
165+
return .Berlin
166+
} else if ChainVersion.London.blockNumber..<ChainVersion.ArrowGlacier.blockNumber ~= block {
167+
return .London
168+
} else if block >= ChainVersion.ArrowGlacier.blockNumber {
169+
// Pass to the default return.
170+
}
171+
return .ArrowGlacier
108172
}
109173
}
110174

175+
extension Web3.ChainVersion: Comparable {
176+
public static func < (lhs: Web3.ChainVersion, rhs: Web3.ChainVersion) -> Bool { return lhs.blockNumber < rhs.blockNumber }
177+
178+
public static func <= (lhs: Web3.ChainVersion, rhs: Web3.ChainVersion) -> Bool { return lhs.blockNumber <= rhs.blockNumber }
179+
}

Sources/web3swift/Web3/Web3+Structures.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ public struct Block: Decodable {
368368
case transactions
369369
case uncles
370370
}
371+
372+
/// Returns chain version of mainnet block with such number
373+
var chainVersion: Web3.ChainVersion { Web3.getChainVersion(of: number) }
371374
}
372375

373376
extension Block {

Tests/web3swiftTests/localTests/EIP1559Tests.swift

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,26 @@ class EIP1559Tests: XCTestCase {
3939
// [3] - Should fail or not
4040
let headerArray: [(BigUInt, BigUInt, BigUInt, Bool) ] = [
4141
// Transitions from non-london to london
42-
(10000000, 4, 20000000, true), // No change
43-
(10000000, 4, 20019530, true), // Upper limit
44-
(10000000, 4, 20019531, false), // Upper +1
45-
(10000000, 4, 19980470, true), // Lower limit
46-
(10000000, 4, 19980469, false), // Lower limit -1
42+
(10_000_000, 12_964_999, 20_000_000, true), // No change
43+
(10_000_000, 12_964_999, 20_019_530, true), // Upper limit
44+
(10_000_000, 12_964_999, 20_019_531, false), // Upper +1
45+
(10_000_000, 12_964_999, 19_980_470, true), // Lower limit
46+
(10_000_000, 12_964_999, 19_980_469, false), // Lower limit -1
4747

4848
// London to London
49-
(20000000, 5, 20000000, true),
50-
(20000000, 5, 20019530, true), // Upper limit
51-
(20000000, 5, 20019531, false), // Upper limit +1
52-
(20000000, 5, 19980470, true), // Lower limit
53-
(20000000, 5, 19980469, false), // Lower limit -1
54-
(40000000, 5, 40039061, true), // Upper limit
55-
(40000000, 5, 40039062, false), // Upper limit +1
56-
(40000000, 5, 39960939, true), // lower limit
57-
(40000000, 5, 39960938, false), // Lower limit -1
49+
(20_000_000, 12_965_000, 20_000_000, true),
50+
(20_000_000, 12_965_000, 20_019_530, true), // Upper limit
51+
(20_000_000, 12_965_000, 20_019_531, false), // Upper limit +1
52+
(20_000_000, 12_965_000, 19_980_470, true), // Lower limit
53+
(20_000_000, 12_965_000, 19_980_469, false), // Lower limit -1
54+
(40_000_000, 12_965_000, 40_039_061, true), // Upper limit
55+
(40_000_000, 12_965_000, 40_039_062, false), // Upper limit +1
56+
(40_000_000, 12_965_000, 39_960_939, true), // lower limit
57+
(40_000_000, 12_965_000, 39_960_938, false), // Lower limit -1
5858
]
5959

60-
try headerArray.forEach { ( touple: (parentGasLimit: BigUInt, parentNumber: BigUInt, currentGasLimit: BigUInt, isOk: Bool)) in
61-
let parent = Block(number: touple.parentGasLimit,
60+
try headerArray.forEach { (touple: (parentGasLimit: BigUInt, parentNumber: BigUInt, currentGasLimit: BigUInt, isOk: Bool)) in
61+
let parent = Block(number: touple.parentNumber,
6262
hash: uselessBlockPart.hash,
6363
parentHash: uselessBlockPart.parentHash,
6464
nonce: uselessBlockPart.nonce,
@@ -79,7 +79,7 @@ class EIP1559Tests: XCTestCase {
7979
transactions: uselessBlockPart.transactions,
8080
uncles: uselessBlockPart.uncles)
8181

82-
let current = Block(number: touple.parentGasLimit + 1,
82+
let current = Block(number: touple.parentNumber + 1,
8383
hash: uselessBlockPart.hash,
8484
parentHash: uselessBlockPart.parentHash,
8585
nonce: uselessBlockPart.nonce,
@@ -103,9 +103,11 @@ class EIP1559Tests: XCTestCase {
103103
let web3 = Web3()
104104

105105
if touple.isOk {
106-
XCTAssertNoThrow(_ = try web3.verifyEip1559Block(chain: .London, parent: parent, current: current), "Shoult not fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)")
106+
XCTAssertTrue(web3.verifyEip1559Block(parent: parent, current: current),
107+
"Shoult not fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)")
107108
} else {
108-
XCTAssertThrowsError(_ = try web3.verifyEip1559Block(chain: .London, parent: parent, current: current), "Should fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)")
109+
XCTAssertFalse(web3.verifyEip1559Block(parent: parent, current: current),
110+
"Should fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)")
109111
}
110112
}
111113
}

0 commit comments

Comments
 (0)