Skip to content

Commit e782075

Browse files
committed
Merge branch 'develop' into experimental/EIP-1559-combined
* develop: Fix typo in WebsocketTests comments. Fixing Remote tests WebSocket tests are unstable on Carthage. Commented out them yet. Rename GanacheTests to RemoteTests Comment out failing WS remote test. Remote tests test plan toggled on Disable some remote test temporary. Fix Carthage building. Rename Remote tests Rename chainVersion to MainChainVersion to make it more explicit. Move back to Infura provider in remote tests Update CONTRIBUTION.md Refactoring Update CONTRIBUTION.md Update CONTRIBUTION.md Add CONTRIBUTION.md # Conflicts: # web3swift.xcodeproj/project.pbxproj
2 parents 9b04656 + c9b050a commit e782075

16 files changed

+489
-460
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ jobs:
4242
run: sleep 1
4343
- name: Run local tests
4444
run: swift test --skip-build -c debug --filter localTests
45-
# - name: Run remote tests
46-
# run: swift test --skip-build -c debug --filter remoteTests
45+
- name: Run remote tests
46+
run: swift test --skip-build -c debug --filter remoteTests
4747
carthage:
4848
name: Carthage
4949
runs-on: macOS-11
@@ -64,7 +64,7 @@ jobs:
6464
- name: Building dependencies
6565
run: carthage build --no-use-binaries --platform iOS Simulator --use-xcframeworks
6666
- name: Building framework
67-
run: xcodebuild build-for-testing -project "web3swift.xcodeproj" -scheme "web3swift" -destination "${{matrix.destination}}" -testPlan LocalTests
67+
run: xcodebuild build-for-testing -project "web3swift.xcodeproj" -scheme "web3swift" -destination "${{matrix.destination}}"
6868
- name: Install ganache
6969
run: npm install ganache --global
7070
- name: Start ganache in background
@@ -73,5 +73,5 @@ jobs:
7373
run: sleep 1
7474
- name: Run local tests
7575
run: xcodebuild test-without-building -project "web3swift.xcodeproj" -scheme "web3swift" -destination "${{matrix.destination}}" -testPlan LocalTests
76-
# - name: Run remote tests
77-
# run: xcodebuild test-without-building -project "web3swift.xcodeproj" -scheme "web3swift" -destination "${{matrix.destination}}" -testPlan RemoteTests
76+
- name: Run remote tests
77+
run: xcodebuild test-without-building -project "web3swift.xcodeproj" -scheme "web3swift" -destination "${{matrix.destination}}" -testPlan RemoteTests

CONTRIBUTION.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Contribution guide
2+
## Version convention
3+
We’re conforming [default versions convention](https://semver.org/).
4+
So in the `1.0.0` version each position means follow:
5+
- 1.\*.***major release**, includes API groundbreaking changes (ie: your old code will not work).
6+
- \*.1.***minor release**, we’ve added some new feature to the lib, but we didn’t break something in anyway (ie: everything will work as expected without any moves after update).
7+
- \*.*.1 — **patch release**, we’re haven’t add any breaking changes or even new features for the user, but we’ve fixed some bugs or rewrote something internal (ie: you should not event mention that anything were changed in the lib).
8+
9+
This library yet living within **three weeks minor release** schedule. Also please keep in mind that in sake of avoiding complex merge conflicts, we’re currently taking only **one big feature** in release, so if you want to take some, please drop us a message somewhere to avoiding reworking it after it’ll be broken by some massive merge.
10+
11+
Critical bug fixes are should be marked with appropriate label in PR and should be proceed **within one week** till patch ’ll be released (at least we’ll try our best to made that).
12+
13+
## What task to choose
14+
Please take it from the [roadmap](https://hackmd.io/G5znP3xAQY-BVc1X8Y1jSg) or from the [opened issues](https://github.com/skywinder/web3swift/issues?q=is:issue+is:open+sort:updated-desc "").
15+
16+
> If you want to make something completely new and purely magical, please drop us a message somewhere before, since it could ends up that this is what we planning to do a lot later or that we not planning at all.
17+
18+
## Codestyle guideline
19+
- `swiftlint` check should goes with no warnings.
20+
- Here’s some more detailed and human readable code style [guidelines](https://hackmd.io/8bACoAnTSsKc55Os596yCg "") (you can add there some suggestion if you’d like to).
21+
- We use [swift](https://www.swift.org/documentation/api-design-guidelines/ "") name convention.
22+
## Tests guideline
23+
1. Cover each new public method with tests.
24+
2. If you’re implementing some big feature encapsulate it in Separate file.
25+
3. Choose one of the two directory to add test case:
26+
* `localTests` — tests which could be ran without needing to connecting to real Ethereum network.
27+
* `remoteTests` — tests which needing connection to real Ethereum network to be ran.
28+
4. Exclude added file from opposite `*.xctestplan` file (e.g. if you’re adding file to `localTests` please exclude it from `RemoteTests.xctestplan`.
29+
5. Add test file to `web3swift.xcodeproj` to make it working within Carthage building system.
30+
31+
## Hacks & tricks & magic
32+
### TestPlans
33+
In ci/cd we’re using Xcode test plans feature to spread tests to local and remote one. So any time you’re adding any new test suit (file) please exclude it from `LocalTests.xctestplan` rather `RemoteTests.xctestplan` depends on what tests group it included.
34+
### Swift package manager
35+
Please add any files unused due build process to `excludeFiles` array in `Package.swift`.
36+
### Carthage
37+
Please do not forget to add & remove all new or dropped files and dependencies in carthage `.xcodeproj` file if you’re working with project anywhere but carthage project.
38+
### Cocoapods
39+
Please do not forget to add & remove all dependencies within `web3swift.podspec` file.
40+
### GitHub actions
41+
You’re able to use our github actions checks in your fork without needing to make PR to this repo. To get that just add your branch name to the branch list in file on path `.github/actions/ci.yml` to let the magic happening like follow:
42+
43+
```yml
44+
on:
45+
push:
46+
branches:
47+
- master
48+
- develop
49+
- hotfix
50+
- #YOUR_REPO_NAME#
51+
```
52+
53+
> Please remove your branch from this list before making PR.
54+
55+
## Good PR checklist
56+
### Code
57+
- [ ] All new functionality covered by unit tests.
58+
- [ ] Ci/cd green.
59+
- [ ] No redundant files are added (build cache, Xcode breakpoints settings and so on).
60+
61+
### Info
62+
- [ ] Relative and concrete PR title.
63+
- [ ] Issue or roadmap goal attached.
64+
- [ ] PR description filled with detail explanation of what it is and what’s its specific.
65+
66+
### Codestyle
67+
- [ ] All public method have `///` styled comments.
68+
- [ ] All magic or nonintuitive internal code parts are clearly explained in inline comments.
69+
- [ ] `swiftlint` ran have no warnings.
70+
- [ ] No commented out code lefts in PR.

Sources/web3swift/Convenience/Decodable+Extensions.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ extension KeyedDecodingContainer {
106106
/// to be initialized as `DecodableFromHex`.
107107
public func decodeHex<T: DecodableFromHex>(to type: T.Type, key: KeyedDecodingContainer<K>.Key) throws -> T {
108108
let string = try self.decode(String.self, forKey: key)
109-
guard let number = T(from: string) else { throw Web3Error.dataError }
109+
guard let number = T(fromHex: string) else { throw Web3Error.dataError }
110110
return number
111111
}
112112

@@ -126,22 +126,20 @@ extension KeyedDecodingContainer {
126126
}
127127

128128
public protocol DecodableFromHex: Decodable {
129-
init?(from hexString: String)
129+
init?(fromHex hexString: String)
130130
}
131131

132132
extension Data: DecodableFromHex {
133-
public init?(from hexString: String) {
133+
public init?(fromHex hexString: String) {
134134
self.init()
135135
guard let tmp = Self.fromHex(hexString) else { return nil }
136136
self = tmp
137137
}
138138
}
139139

140140
extension BigUInt: DecodableFromHex {
141-
public init?(from hexString: String) {
142-
self.init()
143-
guard let tmp = BigUInt(hexString.stripHexPrefix(), radix: 16) else { return nil }
144-
self = tmp
141+
public init?(fromHex hexString: String) {
142+
self.init(hexString.stripHexPrefix(), radix: 16)
145143
}
146144
}
147145

@@ -154,14 +152,20 @@ extension UInt: DecodableFromHex {
154152
}
155153

156154
extension Date: DecodableFromHex {
157-
public init?(from hexString: String) {
155+
public init?(fromHex hexString: String) {
158156
self.init()
159157
let stripedHexString = hexString.stripHexPrefix()
160158
guard let timestampInt = UInt64(stripedHexString, radix: 16) else { return nil }
161159
self = Date(timeIntervalSince1970: TimeInterval(timestampInt))
162160
}
163161
}
164162

163+
extension EthereumAddress: DecodableFromHex {
164+
public init?(fromHex hexString: String) {
165+
self.init(hexString, ignoreChecksum: true)
166+
}
167+
}
168+
165169
private extension KeyedDecodingContainer {
166170
func decode(_ type: [String: Any].Type) throws -> [String: Any] {
167171
var dictionary: [String: Any] = [:]

Sources/web3swift/Web3/Web3+EIP1559.swift

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public extension Web3 {
4444
/// - current: Current block
4545
/// - Returns: True or false if block is EIP-1559 or not
4646
static func isEip1559Block(parent: Block, current: Block) -> Bool {
47-
let parentGasLimit = parent.chainVersion >= .London ? parent.gasLimit : parent.gasLimit * Web3.ElasticityMultiplier
47+
let parentGasLimit = parent.mainChainVersion >= .London ? parent.gasLimit : parent.gasLimit * Web3.ElasticityMultiplier
4848

4949
guard verifyGasLimit(parentGasLimit: parentGasLimit, currentGasLimit: current.gasLimit) else { return false }
5050

@@ -60,39 +60,41 @@ public extension Web3 {
6060
///
6161
/// Calculation for current `Block` based on parents block object only
6262
///
63-
/// If passed block isn't `ChainVersion.London` one will return
63+
/// If passed block isn't `ChainVersion.London` nil will return
6464
///
6565
/// - Parameter parent: Parent `Block`
6666
/// - Returns: Amount of expected base fee for current `Block`
67-
static func calcBaseFee(_ parent: Block) -> BigUInt {
67+
static func calcBaseFee(_ parent: Block) -> BigUInt? {
68+
guard let parentBaseFee = parent.baseFeePerGas else { return nil }
69+
6870
// If given blocks ChainVersion is lower than London — always returns InitialBaseFee
69-
guard parent.chainVersion >= .London else { return Web3.InitialBaseFee }
71+
guard parent.mainChainVersion >= .London else { return Web3.InitialBaseFee }
7072

7173
let parentGasTarget = parent.gasLimit / Web3.ElasticityMultiplier
7274

7375
if parent.gasUsed > parentGasTarget {
7476
// If the parent block used more gas than its target, the baseFee should increase.
7577
let gasUsedDelta = parent.gasUsed - parentGasTarget
76-
let baseFeePerGasDelta = max(parent.baseFeePerGas * gasUsedDelta / parentGasTarget / Web3.BaseFeeChangeDenominator, 1)
77-
let expectedBaseFeePerGas = parent.baseFeePerGas + baseFeePerGasDelta
78+
let baseFeePerGasDelta = max(parentBaseFee * gasUsedDelta / parentGasTarget / Web3.BaseFeeChangeDenominator, 1)
79+
let expectedBaseFeePerGas = parentBaseFee + baseFeePerGasDelta
7880

7981
return expectedBaseFeePerGas
8082
} else if parent.gasUsed < parentGasTarget {
8183
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
8284
let gasUsedDelta = parentGasTarget - parent.gasUsed
83-
let baseFeePerGasDelta = parent.baseFeePerGas * gasUsedDelta / parentGasTarget / Web3.BaseFeeChangeDenominator
84-
let expectedBaseFeePerGas = parent.baseFeePerGas - baseFeePerGasDelta
85+
let baseFeePerGasDelta = parentBaseFee * gasUsedDelta / parentGasTarget / Web3.BaseFeeChangeDenominator
86+
let expectedBaseFeePerGas = parentBaseFee - baseFeePerGasDelta
8587

8688
return expectedBaseFeePerGas
8789
} else {
8890
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
89-
return parent.baseFeePerGas
91+
return parentBaseFee
9092
}
9193
}
9294
}
9395

9496
public extension Web3 {
95-
enum ChainVersion: BigUInt {
97+
enum MainChainVersion: BigUInt {
9698
/// Byzantium switch block
9799
///
98100
/// Date: 16.10.2017
@@ -149,29 +151,29 @@ public extension Web3 {
149151
}
150152
}
151153

152-
static func getChainVersion(of block: BigUInt) -> ChainVersion {
154+
static func getChainVersion(of block: BigUInt) -> MainChainVersion {
153155
// Iterate given block number over each ChainVersion block numbers
154156
// to get the block's ChainVersion.
155-
if block < ChainVersion.Constantinople.mainNetFisrtBlockNumber {
157+
if block < MainChainVersion.Constantinople.mainNetFisrtBlockNumber {
156158
return .Byzantium
157159
// ~= means included in a given range
158-
} else if ChainVersion.Constantinople.mainNetFisrtBlockNumber..<ChainVersion.Istanbul.mainNetFisrtBlockNumber ~= block {
160+
} else if MainChainVersion.Constantinople.mainNetFisrtBlockNumber..<MainChainVersion.Istanbul.mainNetFisrtBlockNumber ~= block {
159161
return .Constantinople
160-
} else if ChainVersion.Istanbul.mainNetFisrtBlockNumber..<ChainVersion.MuirGlacier.mainNetFisrtBlockNumber ~= block {
162+
} else if MainChainVersion.Istanbul.mainNetFisrtBlockNumber..<MainChainVersion.MuirGlacier.mainNetFisrtBlockNumber ~= block {
161163
return .Istanbul
162-
} else if ChainVersion.MuirGlacier.mainNetFisrtBlockNumber..<ChainVersion.Berlin.mainNetFisrtBlockNumber ~= block {
164+
} else if MainChainVersion.MuirGlacier.mainNetFisrtBlockNumber..<MainChainVersion.Berlin.mainNetFisrtBlockNumber ~= block {
163165
return .MuirGlacier
164-
} else if ChainVersion.Berlin.mainNetFisrtBlockNumber..<ChainVersion.London.mainNetFisrtBlockNumber ~= block {
166+
} else if MainChainVersion.Berlin.mainNetFisrtBlockNumber..<MainChainVersion.London.mainNetFisrtBlockNumber ~= block {
165167
return .Berlin
166-
} else if ChainVersion.London.mainNetFisrtBlockNumber..<ChainVersion.ArrowGlacier.mainNetFisrtBlockNumber ~= block {
168+
} else if MainChainVersion.London.mainNetFisrtBlockNumber..<MainChainVersion.ArrowGlacier.mainNetFisrtBlockNumber ~= block {
167169
return .London
168-
} else if block >= ChainVersion.ArrowGlacier.mainNetFisrtBlockNumber {
170+
} else if block >= MainChainVersion.ArrowGlacier.mainNetFisrtBlockNumber {
169171
// Pass to the default return.
170172
}
171173
return .ArrowGlacier
172174
}
173175
}
174176

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

Sources/web3swift/Web3/Web3+JSONRPC.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public struct JSONRPCresponse: Decodable{
109109
[String: Int].self,
110110
[String: [String: [String: [String]]]].self]
111111

112+
// FIXME: Make me a real generic
112113
public init(from decoder: Decoder) throws {
113114
let container = try decoder.container(keyedBy: JSONRPCresponseKeys.self)
114115
let id: Int = try container.decode(Int.self, forKey: .id)
@@ -164,24 +165,26 @@ public struct JSONRPCresponse: Decodable{
164165
self.init(id: id, jsonrpc: jsonrpc, result: result, error: nil)
165166
}
166167

168+
// FIXME: Make me a real generic
167169
/// Get the JSON RCP reponse value by deserializing it into some native <T> class.
168170
///
169171
/// Returns nil if serialization fails
170172
public func getValue<T>() -> T? {
171-
let slf = T.self
172-
if slf == BigUInt.self {
173+
let type = T.self
174+
175+
if type == BigUInt.self {
173176
guard let string = self.result as? String else {return nil}
174177
guard let value = BigUInt(string.stripHexPrefix(), radix: 16) else {return nil}
175178
return value as? T
176-
} else if slf == BigInt.self {
179+
} else if type == BigInt.self {
177180
guard let string = self.result as? String else {return nil}
178181
guard let value = BigInt(string.stripHexPrefix(), radix: 16) else {return nil}
179182
return value as? T
180-
} else if slf == Data.self {
183+
} else if type == Data.self {
181184
guard let string = self.result as? String else {return nil}
182185
guard let value = Data.fromHex(string) else {return nil}
183186
return value as? T
184-
} else if slf == EthereumAddress.self {
187+
} else if type == EthereumAddress.self {
185188
guard let string = self.result as? String else {return nil}
186189
guard let value = EthereumAddress(string, ignoreChecksum: true) else {return nil}
187190
return value as? T
@@ -193,25 +196,25 @@ public struct JSONRPCresponse: Decodable{
193196
// guard let value = self.result as? T else {return nil}
194197
// return value
195198
// }
196-
else if slf == [BigUInt].self {
199+
else if type == [BigUInt].self {
197200
guard let string = self.result as? [String] else {return nil}
198201
let values = string.compactMap { (str) -> BigUInt? in
199202
return BigUInt(str.stripHexPrefix(), radix: 16)
200203
}
201204
return values as? T
202-
} else if slf == [BigInt].self {
205+
} else if type == [BigInt].self {
203206
guard let string = self.result as? [String] else {return nil}
204207
let values = string.compactMap { (str) -> BigInt? in
205208
return BigInt(str.stripHexPrefix(), radix: 16)
206209
}
207210
return values as? T
208-
} else if slf == [Data].self {
211+
} else if type == [Data].self {
209212
guard let string = self.result as? [String] else {return nil}
210213
let values = string.compactMap { (str) -> Data? in
211214
return Data.fromHex(str)
212215
}
213216
return values as? T
214-
} else if slf == [EthereumAddress].self {
217+
} else if type == [EthereumAddress].self {
215218
guard let string = self.result as? [String] else {return nil}
216219
let values = string.compactMap { (str) -> EthereumAddress? in
217220
return EthereumAddress(str, ignoreChecksum: true)

Sources/web3swift/Web3/Web3+Structures.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public struct Block: Decodable {
216216
public var size: BigUInt
217217
public var gasLimit: BigUInt
218218
public var gasUsed: BigUInt
219-
public var baseFeePerGas: BigUInt
219+
public var baseFeePerGas: BigUInt?
220220
public var timestamp: Date
221221
public var transactions: [TransactionInBlock]
222222
public var uncles: [Data]
@@ -247,7 +247,7 @@ public struct Block: Decodable {
247247
}
248248

249249
/// Returns chain version of mainnet block with such number
250-
var chainVersion: Web3.ChainVersion { Web3.getChainVersion(of: number) }
250+
var mainChainVersion: Web3.MainChainVersion { Web3.getChainVersion(of: number) }
251251
}
252252

253253
extension Block {
@@ -278,7 +278,9 @@ extension Block {
278278
self.size = try container.decodeHex(to: BigUInt.self, key: .size)
279279
self.gasLimit = try container.decodeHex(to: BigUInt.self, key: .gasLimit)
280280
self.gasUsed = try container.decodeHex(to: BigUInt.self, key: .gasUsed)
281-
self.baseFeePerGas = try container.decodeHex(to: BigUInt.self, key: .baseFeePerGas)
281+
282+
// optional, since pre EIP-1559 block haven't such property.
283+
self.baseFeePerGas = try? container.decodeHex(to: BigUInt.self, key: .baseFeePerGas)
282284

283285
self.timestamp = try container.decodeHex(to: Date.self, key: .timestamp)
284286

0 commit comments

Comments
 (0)