From fa8a0a89ef8ec72136cc69d9f0abeabb3cb349d3 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Sat, 12 Oct 2024 15:28:10 +0800
Subject: [PATCH 01/22] update genesis
---
.../Blockchain/Config/ProtocolConfig.swift | 147 +++++++++++++++++-
.../Blockchain/Types/State+Genesis.swift | 34 ++++
.../xcshareddata/xcschemes/Boka.xcscheme | 12 ++
Boka/.vscode/launch.json | 22 +++
Node/Sources/Node/Genesis.swift | 104 ++++++++++++-
5 files changed, 315 insertions(+), 4 deletions(-)
create mode 100644 Boka/.vscode/launch.json
diff --git a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
index 21d61277..0002b447 100644
--- a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
+++ b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
@@ -2,7 +2,7 @@ import PolkaVM
import Utils
// constants defined in the graypaper
-public struct ProtocolConfig: Sendable {
+public struct ProtocolConfig: Sendable, Codable {
// A = 8: The period, in seconds, between audit tranches.
public var auditTranchePeriod: Int
@@ -191,6 +191,151 @@ extension Ref: @retroactive PvmConfig where T == ProtocolConfig {
public var pvmProgramInitSegmentSize: Int { value.pvmProgramInitSegmentSize }
}
+extension ProtocolConfig {
+ public func merged(with other: ProtocolConfig) -> ProtocolConfig {
+ ProtocolConfig(
+ auditTranchePeriod: other.auditTranchePeriod != 0
+ ? other.auditTranchePeriod : auditTranchePeriod,
+ additionalMinBalancePerStateItem: other.additionalMinBalancePerStateItem != 0
+ ? other.additionalMinBalancePerStateItem : additionalMinBalancePerStateItem,
+ additionalMinBalancePerStateByte: other.additionalMinBalancePerStateByte != 0
+ ? other.additionalMinBalancePerStateByte : additionalMinBalancePerStateByte,
+ serviceMinBalance: other.serviceMinBalance != 0
+ ? other.serviceMinBalance : serviceMinBalance,
+ totalNumberOfCores: other.totalNumberOfCores != 0
+ ? other.totalNumberOfCores : totalNumberOfCores,
+ preimagePurgePeriod: other.preimagePurgePeriod != 0
+ ? other.preimagePurgePeriod : preimagePurgePeriod,
+ epochLength: other.epochLength != 0 ? other.epochLength : epochLength,
+ auditBiasFactor: other.auditBiasFactor != 0
+ ? other.auditBiasFactor : auditBiasFactor,
+ coreAccumulationGas: other.coreAccumulationGas.value != 0
+ ? other.coreAccumulationGas : coreAccumulationGas,
+ workPackageAuthorizerGas: other.workPackageAuthorizerGas.value != 0
+ ? other.workPackageAuthorizerGas : workPackageAuthorizerGas,
+ workPackageRefineGas: other.workPackageRefineGas.value != 0
+ ? other.workPackageRefineGas : workPackageRefineGas,
+ recentHistorySize: other.recentHistorySize != 0
+ ? other.recentHistorySize : recentHistorySize,
+ maxWorkItems: other.maxWorkItems != 0 ? other.maxWorkItems : maxWorkItems,
+ maxTicketsPerExtrinsic: other.maxTicketsPerExtrinsic != 0
+ ? other.maxTicketsPerExtrinsic : maxTicketsPerExtrinsic,
+ maxLookupAnchorAge: other.maxLookupAnchorAge != 0
+ ? other.maxLookupAnchorAge : maxLookupAnchorAge,
+ transferMemoSize: other.transferMemoSize != 0
+ ? other.transferMemoSize : transferMemoSize,
+ ticketEntriesPerValidator: other.ticketEntriesPerValidator != 0
+ ? other.ticketEntriesPerValidator : ticketEntriesPerValidator,
+ maxAuthorizationsPoolItems: other.maxAuthorizationsPoolItems != 0
+ ? other.maxAuthorizationsPoolItems : maxAuthorizationsPoolItems,
+ slotPeriodSeconds: other.slotPeriodSeconds != 0
+ ? other.slotPeriodSeconds : slotPeriodSeconds,
+ maxAuthorizationsQueueItems: other.maxAuthorizationsQueueItems != 0
+ ? other.maxAuthorizationsQueueItems : maxAuthorizationsQueueItems,
+ coreAssignmentRotationPeriod: other.coreAssignmentRotationPeriod != 0
+ ? other.coreAssignmentRotationPeriod : coreAssignmentRotationPeriod,
+ maxServiceCodeSize: other.maxServiceCodeSize != 0
+ ? other.maxServiceCodeSize : maxServiceCodeSize,
+ preimageReplacementPeriod: other.preimageReplacementPeriod != 0
+ ? other.preimageReplacementPeriod : preimageReplacementPeriod,
+ totalNumberOfValidators: other.totalNumberOfValidators != 0
+ ? other.totalNumberOfValidators : totalNumberOfValidators,
+ erasureCodedPieceSize: other.erasureCodedPieceSize != 0
+ ? other.erasureCodedPieceSize : erasureCodedPieceSize,
+ maxWorkPackageManifestEntries: other.maxWorkPackageManifestEntries != 0
+ ? other.maxWorkPackageManifestEntries : maxWorkPackageManifestEntries,
+ maxEncodedWorkPackageSize: other.maxEncodedWorkPackageSize != 0
+ ? other.maxEncodedWorkPackageSize : maxEncodedWorkPackageSize,
+ maxEncodedWorkReportSize: other.maxEncodedWorkReportSize != 0
+ ? other.maxEncodedWorkReportSize : maxEncodedWorkReportSize,
+ erasureCodedSegmentSize: other.erasureCodedSegmentSize != 0
+ ? other.erasureCodedSegmentSize : erasureCodedSegmentSize,
+ ticketSubmissionEndSlot: other.ticketSubmissionEndSlot != 0
+ ? other.ticketSubmissionEndSlot : ticketSubmissionEndSlot,
+ pvmDynamicAddressAlignmentFactor: other.pvmDynamicAddressAlignmentFactor != 0
+ ? other.pvmDynamicAddressAlignmentFactor : pvmDynamicAddressAlignmentFactor,
+ pvmProgramInitInputDataSize: other.pvmProgramInitInputDataSize != 0
+ ? other.pvmProgramInitInputDataSize : pvmProgramInitInputDataSize,
+ pvmProgramInitPageSize: other.pvmProgramInitPageSize != 0
+ ? other.pvmProgramInitPageSize : pvmProgramInitPageSize,
+ pvmProgramInitSegmentSize: other.pvmProgramInitSegmentSize != 0
+ ? other.pvmProgramInitSegmentSize : pvmProgramInitSegmentSize
+ )
+ }
+
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+
+ auditTranchePeriod =
+ try container.decodeIfPresent(Int.self, forKey: .auditTranchePeriod) ?? 0
+ additionalMinBalancePerStateItem =
+ try container.decodeIfPresent(Int.self, forKey: .additionalMinBalancePerStateItem) ?? 0
+ additionalMinBalancePerStateByte =
+ try container.decodeIfPresent(Int.self, forKey: .additionalMinBalancePerStateByte) ?? 0
+ serviceMinBalance =
+ try container.decodeIfPresent(Int.self, forKey: .serviceMinBalance) ?? 0
+ totalNumberOfCores =
+ try container.decodeIfPresent(Int.self, forKey: .totalNumberOfCores) ?? 0
+ preimagePurgePeriod =
+ try container.decodeIfPresent(Int.self, forKey: .preimagePurgePeriod) ?? 0
+ epochLength = try container.decodeIfPresent(Int.self, forKey: .epochLength) ?? 0
+ auditBiasFactor =
+ try container.decodeIfPresent(Int.self, forKey: .auditBiasFactor) ?? 0
+ coreAccumulationGas =
+ try container.decodeIfPresent(Gas.self, forKey: .coreAccumulationGas) ?? Gas(0)
+ workPackageAuthorizerGas =
+ try container.decodeIfPresent(Gas.self, forKey: .workPackageAuthorizerGas)
+ ?? Gas(0)
+ workPackageRefineGas =
+ try container.decodeIfPresent(Gas.self, forKey: .workPackageRefineGas) ?? Gas(0)
+ recentHistorySize =
+ try container.decodeIfPresent(Int.self, forKey: .recentHistorySize) ?? 0
+ maxWorkItems = try container.decodeIfPresent(Int.self, forKey: .maxWorkItems) ?? 0
+ maxTicketsPerExtrinsic =
+ try container.decodeIfPresent(Int.self, forKey: .maxTicketsPerExtrinsic) ?? 0
+ maxLookupAnchorAge =
+ try container.decodeIfPresent(Int.self, forKey: .maxLookupAnchorAge) ?? 0
+ transferMemoSize =
+ try container.decodeIfPresent(Int.self, forKey: .transferMemoSize) ?? 0
+ ticketEntriesPerValidator =
+ try container.decodeIfPresent(Int.self, forKey: .ticketEntriesPerValidator) ?? 0
+ maxAuthorizationsPoolItems =
+ try container.decodeIfPresent(Int.self, forKey: .maxAuthorizationsPoolItems) ?? 0
+ slotPeriodSeconds =
+ try container.decodeIfPresent(Int.self, forKey: .slotPeriodSeconds) ?? 0
+ maxAuthorizationsQueueItems =
+ try container.decodeIfPresent(Int.self, forKey: .maxAuthorizationsQueueItems) ?? 0
+ coreAssignmentRotationPeriod =
+ try container.decodeIfPresent(Int.self, forKey: .coreAssignmentRotationPeriod) ?? 0
+ maxServiceCodeSize =
+ try container.decodeIfPresent(Int.self, forKey: .maxServiceCodeSize) ?? 0
+ preimageReplacementPeriod =
+ try container.decodeIfPresent(Int.self, forKey: .preimageReplacementPeriod) ?? 0
+ totalNumberOfValidators =
+ try container.decodeIfPresent(Int.self, forKey: .totalNumberOfValidators) ?? 0
+ erasureCodedPieceSize =
+ try container.decodeIfPresent(Int.self, forKey: .erasureCodedPieceSize) ?? 0
+ maxWorkPackageManifestEntries =
+ try container.decodeIfPresent(Int.self, forKey: .maxWorkPackageManifestEntries) ?? 0
+ maxEncodedWorkPackageSize =
+ try container.decodeIfPresent(Int.self, forKey: .maxEncodedWorkPackageSize) ?? 0
+ maxEncodedWorkReportSize =
+ try container.decodeIfPresent(Int.self, forKey: .maxEncodedWorkReportSize) ?? 0
+ erasureCodedSegmentSize =
+ try container.decodeIfPresent(Int.self, forKey: .erasureCodedSegmentSize) ?? 0
+ ticketSubmissionEndSlot =
+ try container.decodeIfPresent(Int.self, forKey: .ticketSubmissionEndSlot) ?? 0
+ pvmDynamicAddressAlignmentFactor =
+ try container.decodeIfPresent(Int.self, forKey: .pvmDynamicAddressAlignmentFactor) ?? 0
+ pvmProgramInitInputDataSize =
+ try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitInputDataSize) ?? 0
+ pvmProgramInitPageSize =
+ try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitPageSize) ?? 0
+ pvmProgramInitSegmentSize =
+ try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitSegmentSize) ?? 0
+ }
+}
+
extension ProtocolConfig {
public enum AuditTranchePeriod: ReadInt {
public typealias TConfig = ProtocolConfigRef
diff --git a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
index df08f188..869ccf5c 100644
--- a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
+++ b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
@@ -34,4 +34,38 @@ extension State {
return state
}
+
+ public static func fileGenesis(config: ProtocolConfigRef) throws -> State {
+ var devKeys = [ValidatorKey]()
+
+ var state = State.dummy(config: config)
+
+ for i in 0 ..< config.value.totalNumberOfValidators {
+ let keySet = try DevKeyStore.getDevKey(seed: UInt32(i))
+ devKeys.append(ValidatorKey(
+ bandersnatch: keySet.bandersnatch.data,
+ ed25519: keySet.ed25519.data,
+ bls: Data144(), // TODO: figure out BLS pub key size
+ metadata: Data128()
+ ))
+ }
+ state.safroleState.nextValidators = try ConfigFixedSizeArray(config: config, array: devKeys)
+ state.validatorQueue = try ConfigFixedSizeArray(config: config, array: devKeys)
+ state.currentValidators = try ConfigFixedSizeArray(config: config, array: devKeys)
+
+ var epochKeys = [BandersnatchPublicKey]()
+ for i in 0 ..< config.value.epochLength {
+ epochKeys.append(devKeys[i % config.value.totalNumberOfValidators].bandersnatch)
+ }
+ state.safroleState.ticketsOrKeys = try .right(ConfigFixedSizeArray(config: config, array: epochKeys))
+
+ let ctx = try Bandersnatch.RingContext(size: UInt(config.value.totalNumberOfValidators))
+ let commitment = try Bandersnatch.RingCommitment(
+ ring: devKeys.map { try Bandersnatch.PublicKey(data: $0.bandersnatch) },
+ ctx: ctx
+ )
+ state.safroleState.ticketsVerifier = commitment.data
+
+ return state
+ }
}
diff --git a/Boka/.swiftpm/xcode/xcshareddata/xcschemes/Boka.xcscheme b/Boka/.swiftpm/xcode/xcshareddata/xcschemes/Boka.xcscheme
index ed43f72f..ae134e00 100644
--- a/Boka/.swiftpm/xcode/xcshareddata/xcschemes/Boka.xcscheme
+++ b/Boka/.swiftpm/xcode/xcshareddata/xcschemes/Boka.xcscheme
@@ -29,6 +29,18 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
+
+
+
+
+
+
(StateRef, ProtocolConfigRef) {
switch self {
- case .file:
- fatalError("TODO: not implemented")
case .dev:
let config = ProtocolConfigRef.dev
let state = try State.devGenesis(config: config)
-
return (StateRef(state), config)
+ case let .file(path):
+ let genesis = try GenesisFileHandler().readAndValidateGenesis(from: path)
+ if let config = genesis.config {
+ let state = try State.devGenesis(config: Ref(config))
+ return (StateRef(state), Ref(config))
+ }
+ let config = ProtocolConfigRef.dev
+ let state = try State.fileGenesis(config: config)
+ return (StateRef(state), config)
+ }
+ }
+}
+
+struct GenesisData: Sendable, Codable {
+ var name: String
+ var id: String
+ var bootnodes: [String]
+ var preset: String?
+ var config: ProtocolConfig?
+ var state: String
+
+ init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ name = try container.decode(String.self, forKey: .name)
+ id = try container.decode(String.self, forKey: .id)
+ bootnodes = try container.decode([String].self, forKey: .bootnodes)
+ preset = try container.decodeIfPresent(String.self, forKey: .preset)
+ config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config)
+ state = try container.decode(String.self, forKey: .state)
+ }
+
+ func missConfigFiled() -> Bool {
+ guard let config else {
+ return true
+ }
+ let mirror = Mirror(reflecting: config)
+ for child in mirror.children {
+ if let value = child.value as? Int, value == 0 {
+ return true
+ }
+ if let value = child.value as? Gas, value.value == 0 {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+// Class to handle Genesis JSON file operations
+class GenesisFileHandler {
+ private func validateGenesis(_ genesis: GenesisData) throws {
+ // Validate required fields
+ if genesis.name.isEmpty {
+ throw GenesisError.invalidFormat("Invalid or missing 'name'")
+ }
+ if genesis.id.isEmpty {
+ throw GenesisError.invalidFormat("Invalid or missing 'id'")
+ }
+ if genesis.bootnodes.isEmpty {
+ throw GenesisError.invalidFormat("Invalid or missing 'bootnodes'")
+ }
+ if genesis.state.isEmpty {
+ throw GenesisError.invalidFormat("Invalid or missing 'state'")
+ }
+ if let preset = genesis.preset, !["dev", "mainnet"].contains(preset.lowercased()) {
+ throw GenesisError.invalidFormat("Invalid preset value. Must be 'dev' or 'mainnet'.")
+ }
+ if genesis.preset == nil, genesis.missConfigFiled() {
+ throw GenesisError.invalidFormat("Missing 'preset' or 'config' field.")
+ }
+ }
+
+ func readAndValidateGenesis(from filePath: String) throws -> GenesisData {
+ do {
+ let fileContents = try String(contentsOfFile: filePath, encoding: .utf8)
+ let data = fileContents.data(using: .utf8)!
+ let decoder = JSONDecoder()
+ let genesis = try decoder.decode(GenesisData.self, from: data)
+ try validateGenesis(genesis)
+ return genesis
+ } catch let error as GenesisError {
+ throw error
+ } catch {
+ throw GenesisError.fileReadError(error)
}
}
}
From 29d495071bdfda303de41df53cd3621cedb8ac19 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Sat, 12 Oct 2024 15:51:58 +0800
Subject: [PATCH 02/22] update genesis
---
.../Blockchain/Types/State+Genesis.swift | 36 ++-----------------
Node/Sources/Node/Genesis.swift | 23 ++++++++----
2 files changed, 19 insertions(+), 40 deletions(-)
diff --git a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
index 869ccf5c..a3979a00 100644
--- a/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
+++ b/Blockchain/Sources/Blockchain/Types/State+Genesis.swift
@@ -34,38 +34,6 @@ extension State {
return state
}
-
- public static func fileGenesis(config: ProtocolConfigRef) throws -> State {
- var devKeys = [ValidatorKey]()
-
- var state = State.dummy(config: config)
-
- for i in 0 ..< config.value.totalNumberOfValidators {
- let keySet = try DevKeyStore.getDevKey(seed: UInt32(i))
- devKeys.append(ValidatorKey(
- bandersnatch: keySet.bandersnatch.data,
- ed25519: keySet.ed25519.data,
- bls: Data144(), // TODO: figure out BLS pub key size
- metadata: Data128()
- ))
- }
- state.safroleState.nextValidators = try ConfigFixedSizeArray(config: config, array: devKeys)
- state.validatorQueue = try ConfigFixedSizeArray(config: config, array: devKeys)
- state.currentValidators = try ConfigFixedSizeArray(config: config, array: devKeys)
-
- var epochKeys = [BandersnatchPublicKey]()
- for i in 0 ..< config.value.epochLength {
- epochKeys.append(devKeys[i % config.value.totalNumberOfValidators].bandersnatch)
- }
- state.safroleState.ticketsOrKeys = try .right(ConfigFixedSizeArray(config: config, array: epochKeys))
-
- let ctx = try Bandersnatch.RingContext(size: UInt(config.value.totalNumberOfValidators))
- let commitment = try Bandersnatch.RingCommitment(
- ring: devKeys.map { try Bandersnatch.PublicKey(data: $0.bandersnatch) },
- ctx: ctx
- )
- state.safroleState.ticketsVerifier = commitment.data
-
- return state
- }
+ // TODO: add file genesis
+ // public static func fileGenesis(config: ProtocolConfigRef) throws -> State
}
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index 58fba45e..1a3de99c 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -32,13 +32,23 @@ extension Genesis {
return (StateRef(state), config)
case let .file(path):
let genesis = try GenesisFileHandler().readAndValidateGenesis(from: path)
- if let config = genesis.config {
- let state = try State.devGenesis(config: Ref(config))
- return (StateRef(state), Ref(config))
+ var config: ProtocolConfig
+ switch genesis.preset?.lowercased() {
+ case "dev":
+ config = ProtocolConfigRef.dev.value
+ if let genesisConfig = genesis.config {
+ config = config.merged(with: genesisConfig)
+ }
+ case "mainnet":
+ config = ProtocolConfigRef.mainnet.value
+ if let genesisConfig = genesis.config {
+ config = config.merged(with: genesisConfig)
+ }
+ default:
+ config = genesis.config!
}
- let config = ProtocolConfigRef.dev
- let state = try State.fileGenesis(config: config)
- return (StateRef(state), config)
+ let state = try State.devGenesis(config: Ref(config))
+ return (StateRef(state), Ref(config))
}
}
}
@@ -49,6 +59,7 @@ struct GenesisData: Sendable, Codable {
var bootnodes: [String]
var preset: String?
var config: ProtocolConfig?
+ // TODO: check he deal with state
var state: String
init(from decoder: Decoder) throws {
From e50a8902c972d11c8ac9d0e8163a1d13deec146c Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Sun, 13 Oct 2024 18:45:04 +0800
Subject: [PATCH 03/22] update boka command
---
Boka/Package.resolved | 77 +++++++++++--------
Boka/Sources/Boka.swift | 14 +++-
.../chainfiles/devnet_noconfig_spec.json | 11 +++
.../chainfiles/mainnet_someconfig_spec.json | 27 +++++++
4 files changed, 91 insertions(+), 38 deletions(-)
create mode 100644 Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
create mode 100644 Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
diff --git a/Boka/Package.resolved b/Boka/Package.resolved
index 78caa8ae..cb6478df 100644
--- a/Boka/Package.resolved
+++ b/Boka/Package.resolved
@@ -6,8 +6,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
- "revision" : "0ae99db85b2b9d1e79b362bd31fd1ffe492f7c47",
- "version" : "1.21.2"
+ "revision" : "64abc77edf1ef81e69bd90a2ac386de615c8e8ea",
+ "version" : "1.23.0"
}
},
{
@@ -33,8 +33,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/console-kit.git",
"state" : {
- "revision" : "9f7932f22ab6f64aafadc14491e694179b7d0f6f",
- "version" : "4.14.3"
+ "revision" : "78c0dd739df8cb9ee14a8bbbf770facc4fc3402a",
+ "version" : "4.15.0"
}
},
{
@@ -42,8 +42,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/grpc/grpc-swift.git",
"state" : {
- "revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1",
- "version" : "1.23.0"
+ "revision" : "3ef3a9f42a11bfca767de880f1a0aedd2b65b840",
+ "version" : "1.24.1"
}
},
{
@@ -76,10 +76,10 @@
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-argument-parser.git",
+ "location" : "https://github.com/apple/swift-argument-parser",
"state" : {
- "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
- "version" : "1.4.0"
+ "revision" : "41982a3656a71c768319979febd796c6fd111d5c",
+ "version" : "1.5.0"
}
},
{
@@ -87,8 +87,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms.git",
"state" : {
- "revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
- "version" : "1.0.1"
+ "revision" : "5c8bd186f48c16af0775972700626f0b74588278",
+ "version" : "1.0.2"
}
},
{
@@ -105,8 +105,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
- "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
- "version" : "1.1.2"
+ "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
+ "version" : "1.1.4"
}
},
{
@@ -114,8 +114,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-crypto.git",
"state" : {
- "revision" : "bc1c29221f6dfeb0ebbfbc98eb95cd3d4967868e",
- "version" : "3.4.0"
+ "revision" : "ffca28be3c9c6a86a579949d23f68818a4b9b5d8",
+ "version" : "3.8.0"
}
},
{
@@ -123,8 +123,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-distributed-tracing.git",
"state" : {
- "revision" : "11c756c5c4d7de0eeed8595695cadd7fa107aa19",
- "version" : "1.1.1"
+ "revision" : "6483d340853a944c96dbcc28b27dd10b6c581703",
+ "version" : "1.1.2"
}
},
{
@@ -159,8 +159,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
- "revision" : "4c4453b489cf76e6b3b0f300aba663eb78182fad",
- "version" : "2.70.0"
+ "revision" : "665206000b8307cab5ac51203d29b0f232d7e31b",
+ "version" : "2.74.0"
}
},
{
@@ -168,8 +168,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
- "revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e",
- "version" : "1.23.0"
+ "revision" : "d1ead62745cc3269e482f1c51f27608057174379",
+ "version" : "1.24.0"
}
},
{
@@ -177,8 +177,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
- "revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
- "version" : "1.34.0"
+ "revision" : "eaa71bb6ae082eee5a07407b1ad0cbd8f48f9dca",
+ "version" : "1.34.1"
}
},
{
@@ -186,8 +186,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
- "revision" : "a9fa5efd86e7ce2e5c1b6de113262e58035ca251",
- "version" : "2.27.1"
+ "revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69",
+ "version" : "2.27.2"
}
},
{
@@ -195,14 +195,14 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
- "revision" : "38ac8221dd20674682148d6451367f89c2652980",
- "version" : "1.21.0"
+ "revision" : "dbace16f126fdcd80d58dc54526c561ca17327d7",
+ "version" : "1.22.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-numerics",
+ "location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"branch" : "main",
"revision" : "e30276bff2ff5ed80566fbdca49f50aa160b0e83"
@@ -213,8 +213,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/slashmo/swift-otel.git",
"state" : {
- "revision" : "8c271c7fed34a39f29c728598b3358fbdddf8ff4",
- "version" : "0.9.0"
+ "revision" : "90d63b478fbc4c97f396c1cf9ad011979a83f10b",
+ "version" : "0.10.1"
}
},
{
@@ -222,8 +222,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
- "revision" : "e17d61f26df0f0e06f58f6977ba05a097a720106",
- "version" : "1.27.1"
+ "revision" : "ebc7251dd5b37f627c93698e4374084d98409633",
+ "version" : "1.28.2"
}
},
{
@@ -253,13 +253,22 @@
"version" : "1.3.2"
}
},
+ {
+ "identity" : "swift-w3c-trace-context",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/slashmo/swift-w3c-trace-context.git",
+ "state" : {
+ "revision" : "3da4b79545b38cf5551f1c525d800756f38cb697",
+ "version" : "1.0.0-beta.3"
+ }
+ },
{
"identity" : "vapor",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/vapor.git",
"state" : {
- "revision" : "a823735db57b46100b0c61cdfc5a08525b1e7cad",
- "version" : "4.102.1"
+ "revision" : "1466c50e4ad39072143e2fcdf13b4ba11be375a0",
+ "version" : "4.106.0"
}
},
{
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index 7af09ffc..a0de629c 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -38,7 +38,10 @@ struct Boka: AsyncParsableCommand {
@Option(name: [.customLong("p2p"), .long], help: "Listen address for P2P protocol.")
var p2pListenAddress: String?
- @Option(name: [.customLong("peers"), .long], parsing: .upToNextOption, help: "Specify peer P2P addresses.")
+ @Option(
+ name: [.customLong("peers"), .long], parsing: .upToNextOption,
+ help: "Specify peer P2P addresses."
+ )
var p2pPeers: [String] = []
@Flag(name: .long, help: "Run as a validator.")
@@ -107,21 +110,24 @@ struct Boka: AsyncParsableCommand {
),
handlerMiddleware: .tracing(prefix: "Handler")
)
+ let keystore = try await DevKeyStore()
do {
- let keystore = try await DevKeyStore()
+ logger.info("Starting ValidatorNode...")
let node = try await ValidatorNode(
genesis: .dev, config: config, eventBus: eventBus, keystore: keystore
)
+ logger.info("ValidatorNode started successfully.")
for service in services {
Task {
try await service.run()
}
}
-
try await node.wait()
+ } catch {
+ logger.error("Failed to start ValidatorNode: \(error.localizedDescription)")
+ throw error
}
-
logger.info("Exiting...")
}
}
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
new file mode 100644
index 00000000..51fce04b
--- /dev/null
+++ b/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
@@ -0,0 +1,11 @@
+{
+ "name": "MainNet",
+ "id": "mainnet-456",
+ "bootnodes": [
+ "node1.mainnet.com",
+ "node2.mainnet.com"
+ ],
+ "preset": "devnet",
+ "state": "0x1234567890abcdef"
+ }
+
\ No newline at end of file
diff --git a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
new file mode 100644
index 00000000..54936212
--- /dev/null
+++ b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
@@ -0,0 +1,27 @@
+{
+ "name": "Mainnet",
+ "id": "mainnet-1",
+ "bootnodes": [
+ "enode://abc@1.2.3.4:30303",
+ "enode://def@5.6.7.8:30303"
+ ],
+ "preset": "mainnet",
+ "config": {
+ "auditTranchePeriod": 100,
+ "additionalMinBalancePerStateItem": 10,
+ "additionalMinBalancePerStateByte": 1,
+ "serviceMinBalance": 1000,
+ "totalNumberOfCores": 4,
+ "preimagePurgePeriod": 1000,
+ "epochLength": 10000,
+ "auditBiasFactor": 5,
+ "coreAccumulationGas": 100,
+ "workPackageAuthorizerGas": 50,
+ "workPackageRefineGas": 20,
+ "recentHistorySize": 100,
+ "maxWorkItems": 10,
+ "maxTicketsPerExtrinsic": 5,
+ "maxLookupAnchorAge": 100
+ },
+ "state": "0xabcdef"
+}
\ No newline at end of file
From cf0cb68af4878275616376f4fca6b25a88af912b Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 11:53:48 +0800
Subject: [PATCH 04/22] update boka commandline
---
Boka/Package.resolved | 11 +-
Boka/Package.swift | 2 -
Boka/Sources/Boka.swift | 174 +++++++++---------
Boka/Sources/main.swift | 11 ++
.../xcshareddata/swiftpm/Package.resolved | 13 +-
5 files changed, 100 insertions(+), 111 deletions(-)
create mode 100644 Boka/Sources/main.swift
diff --git a/Boka/Package.resolved b/Boka/Package.resolved
index cb6478df..478bf7bc 100644
--- a/Boka/Package.resolved
+++ b/Boka/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "374b7e6e0a436000edb551e3149c1a5a7546e03c66996cbebd99bc9ef520cbed",
+ "originHash" : "3ffe5d8aed92ff623b0fda4bed30c24dbc202e6d967a574ec3c6096b0093f399",
"pins" : [
{
"identity" : "async-http-client",
@@ -73,15 +73,6 @@
"version" : "1.2.0"
}
},
- {
- "identity" : "swift-argument-parser",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-argument-parser",
- "state" : {
- "revision" : "41982a3656a71c768319979febd796c6fd111d5c",
- "version" : "1.5.0"
- }
- },
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
diff --git a/Boka/Package.swift b/Boka/Package.swift
index 78a91829..57ce41ce 100644
--- a/Boka/Package.swift
+++ b/Boka/Package.swift
@@ -11,7 +11,6 @@ let package = Package(
dependencies: [
.package(path: "../Node"),
.package(path: "../TracingUtils"),
- .package(url: "https://github.com/apple/swift-argument-parser", from: "1.4.0"),
.package(url: "https://github.com/slashmo/swift-otel.git", from: "0.9.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.6.0"),
.package(url: "https://github.com/vapor/console-kit.git", from: "4.14.3"),
@@ -24,7 +23,6 @@ let package = Package(
dependencies: [
"Node",
"TracingUtils",
- .product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
.product(name: "OTel", package: "swift-otel"),
.product(name: "OTLPGRPC", package: "swift-otel"),
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index a0de629c..ece069d2 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -1,108 +1,117 @@
-// The Swift Programming Language
-// https://docs.swift.org/swift-book
-//
-// Swift Argument Parser
-// https://swiftpackageindex.com/apple/swift-argument-parser/documentation
-
-import ArgumentParser
import Blockchain
+import ConsoleKit
import Foundation
import Node
import ServiceLifecycle
import TracingUtils
import Utils
-@main
-struct Boka: AsyncParsableCommand {
- static let configuration = CommandConfiguration(
- abstract: "A command-line tool for Boka.",
- version: "1.0.0"
- )
+struct Boka: AsyncCommand {
+ struct Signature: CommandSignature {
+ @Option(name: "base-path", short: "d", help: "Base path to database files.")
+ var basePath: String?
- @Option(name: [.customShort("d"), .long], help: "Base path to database files.")
- var basePath: String?
+ @Option(name: "chain", short: "c", help: "Path to chain spec file.")
+ var chain: String?
- @Option(name: [.customShort("c"), .long], help: "Path to chain spec file.")
- var chain: String?
+ @Option(name: "config-file", short: "f", help: "Path to config file.")
+ var configFile: String?
- @Option(name: [.customShort("f"), .long], help: "Path to config file.")
- var configFile: String?
+ @Option(
+ name: "rpc",
+ help:
+ "Listen address for RPC server. Pass 'false' to disable RPC server. Default to 127.0.0.1:9955."
+ )
+ var rpc: String?
- @Option(
- name: [.customLong("rpc"), .long],
- help:
- "Listen address for RPC server. Pass 'false' to disable RPC server. Default to 127.0.0.1:9955."
- )
- var rpcListenAddress: String = "127.0.0.1:9955"
+ @Option(name: "p2p", help: "Listen address for P2P protocol.")
+ var p2p: String?
- @Option(name: [.customLong("p2p"), .long], help: "Listen address for P2P protocol.")
- var p2pListenAddress: String?
+ @Option(name: "peers", help: "Specify peer P2P addresses separated by commas.")
+ var peers: String?
- @Option(
- name: [.customLong("peers"), .long], parsing: .upToNextOption,
- help: "Specify peer P2P addresses."
- )
- var p2pPeers: [String] = []
+ @Flag(name: "validator", help: "Run as a validator.")
+ var validator: Bool
- @Flag(name: .long, help: "Run as a validator.")
- var validator: Bool = false
+ @Option(
+ name: "operator-rpc",
+ help:
+ "Listen address for operator RPC server. Pass 'false' to disable operator RPC server. Default to false."
+ )
+ var operatorRpc: String?
- @Option(
- name: [.customLong("operator-rpc"), .long],
- help:
- "Listen address for operator RPC server. Pass 'false' to disable operator RPC server. Default to false."
- )
- var operatorRpcListenAddress: String = "false"
+ @Option(name: "dev-seed", help: "For development only. Seed for validator keys.")
+ var devSeed: String?
- @Option(name: .long, help: "For development only. Seed for validator keys.")
- var devSeed: String?
+ @Flag(name: "version", help: "Show the version.")
+ var version: Bool
+
+ @Flag(name: "help", short: "h", help: "Show help information.")
+ var help: Bool
+ }
- mutating func run() async throws {
- let logger = Logger(label: "boka")
+ var help: String {
+ "A command-line tool for Boka."
+ }
- if let basePath {
- logger.info("Base Path: \(basePath)")
+ func run(using context: CommandContext, signature: Signature) async throws {
+ if signature.help {
+ context.console.info(help)
+ return
}
- if let chain {
- logger.info("Chain: \(chain)")
+
+ if signature.version {
+ context.console.info("Boka version 1.0.0")
+ return
}
- if let configFile {
- logger.info("Config File: \(configFile)")
+
+ // Handle other options and flags
+ if let basePath = signature.basePath {
+ context.console.info("Base path: \(basePath)")
}
- logger.info("RPC Listen Address: \(rpcListenAddress)")
+ if let chain = signature.chain {
+ context.console.info("Chain: \(chain)")
+ }
- if let p2pListenAddress {
- logger.info("P2P Listen Address: \(p2pListenAddress)")
+ if let configFile = signature.configFile {
+ context.console.info("Config file: \(configFile)")
}
- if rpcListenAddress.lowercased() == "false" {
- logger.warning("TODO: RPC server is disabled")
- rpcListenAddress = "127.0.0.1:9955"
+
+ if let p2p = signature.p2p {
+ context.console.info("P2P listen address: \(p2p)")
}
- let (rpcAddress, rpcPort) = try Regexs.parseAddress(rpcListenAddress)
- if !p2pPeers.isEmpty {
- logger.info("P2P Peers: \(p2pPeers.joined(separator: ", "))")
+ if let peers = signature.peers {
+ let peerList = peers.split(separator: ",").map {
+ $0.trimmingCharacters(in: .whitespaces)
+ }
+ context.console.info("Peers: \(peerList.joined(separator: ", "))")
}
- logger.info("Validator: \(validator ? "Enabled" : "Disabled")")
- if operatorRpcListenAddress.lowercased() == "false" {
- logger.warning("TODO: Operator RPC server is disabled")
- } else {
- logger.info("Operator RPC Listen Address: \(operatorRpcListenAddress)")
+ if signature.validator {
+ context.console.info("Running as validator")
}
- if let devSeed {
- logger.info("Dev Seed: \(devSeed)")
+ if let operatorRpc = signature.operatorRpc {
+ context.console.info("Operator RPC listen address: \(operatorRpc)")
}
+ if let devSeed = signature.devSeed {
+ context.console.info("Dev seed: \(devSeed)")
+ }
+ var rpcListenAddress = "127.0.0.1:9955"
+ if let rpc = signature.rpc {
+ if rpc.lowercased() == "false" {
+ context.console.warning("RPC server is disabled")
+ } else {
+ rpcListenAddress = rpc
+ }
+ context.console.info("RPC listen address: \(rpc)")
+ }
+ let (rpcAddress, rpcPort) = try Regexs.parseAddress(rpcListenAddress)
let services = try await Tracing.bootstrap("Boka", loggerOnly: true)
-
- logger.info("Starting Boka...")
-
- let config = Node.Config(
- rpc: RPCConfig(listenAddress: rpcAddress, port: rpcPort)
- )
+ let config = Node.Config(rpc: RPCConfig(listenAddress: rpcAddress, port: rpcPort))
let eventBus = EventBus(
eventMiddleware: .serial(
.log(logger: Logger(label: "EventBus")),
@@ -111,23 +120,12 @@ struct Boka: AsyncParsableCommand {
handlerMiddleware: .tracing(prefix: "Handler")
)
let keystore = try await DevKeyStore()
- do {
- logger.info("Starting ValidatorNode...")
- let node = try await ValidatorNode(
- genesis: .dev, config: config, eventBus: eventBus, keystore: keystore
- )
- logger.info("ValidatorNode started successfully.")
-
- for service in services {
- Task {
- try await service.run()
- }
+ let node = try await ValidatorNode(genesis: .dev, config: config, eventBus: eventBus, keystore: keystore)
+ for service in services {
+ Task {
+ try await service.run()
}
- try await node.wait()
- } catch {
- logger.error("Failed to start ValidatorNode: \(error.localizedDescription)")
- throw error
}
- logger.info("Exiting...")
+ try await node.wait()
}
}
diff --git a/Boka/Sources/main.swift b/Boka/Sources/main.swift
new file mode 100644
index 00000000..c8c524e8
--- /dev/null
+++ b/Boka/Sources/main.swift
@@ -0,0 +1,11 @@
+import ConsoleKit
+
+// Set up the CLI
+let input = CommandInput(arguments: CommandLine.arguments)
+let console = Terminal()
+let boka = Boka()
+do {
+ try await console.run(boka, input: input)
+} catch {
+ console.error("\(error)")
+}
diff --git a/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index dadbcffe..48b1a9c8 100644
--- a/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "64d6d2bd3a54574173837ac745942b523c8e42e36237f566a2706ce1d1c2b949",
+ "originHash" : "74f67ee171359522e232c57cd2ceb3e2aee823b7fadbe87349ca4a2605336aad",
"pins" : [
{
"identity" : "async-http-client",
@@ -73,15 +73,6 @@
"version" : "1.2.0"
}
},
- {
- "identity" : "swift-argument-parser",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-argument-parser.git",
- "state" : {
- "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
- "version" : "1.4.0"
- }
- },
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
@@ -202,7 +193,7 @@
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-numerics",
+ "location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"branch" : "main",
"revision" : "e30276bff2ff5ed80566fbdca49f50aa160b0e83"
From 37b90b42ae576c6c58c24a4babae3fa75b2f074e Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 14:30:10 +0800
Subject: [PATCH 05/22] update boka cli
---
Boka/Sources/Boka.swift | 2 ++
JAMTests/jamtestvectors | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index ece069d2..696d3281 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -100,6 +100,7 @@ struct Boka: AsyncCommand {
if let devSeed = signature.devSeed {
context.console.info("Dev seed: \(devSeed)")
}
+
var rpcListenAddress = "127.0.0.1:9955"
if let rpc = signature.rpc {
if rpc.lowercased() == "false" {
@@ -109,6 +110,7 @@ struct Boka: AsyncCommand {
}
context.console.info("RPC listen address: \(rpc)")
}
+
let (rpcAddress, rpcPort) = try Regexs.parseAddress(rpcListenAddress)
let services = try await Tracing.bootstrap("Boka", loggerOnly: true)
let config = Node.Config(rpc: RPCConfig(listenAddress: rpcAddress, port: rpcPort))
diff --git a/JAMTests/jamtestvectors b/JAMTests/jamtestvectors
index 92890655..4fdcf95a 160000
--- a/JAMTests/jamtestvectors
+++ b/JAMTests/jamtestvectors
@@ -1 +1 @@
-Subproject commit 9289065548ccbc11ee21f9e47bc0f99a91502fed
+Subproject commit 4fdcf95aeed04d53bb4198373925d34f63069059
From a1335bdf1c4c9494babb193496ad7f704d03a79b Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 17:13:21 +0800
Subject: [PATCH 06/22] update Boka command
---
Boka/Package.swift | 2 +-
Boka/Sources/Boka.swift | 17 +++---
.../chainfiles/devnet_allconfig_spec.json | 43 ++++++++++++++
.../chainfiles/devnet_noconfig_spec.json | 2 +-
Node/Package.resolved | 8 +--
RPC/Package.resolved | 58 +++++++++----------
RPC/Package.swift | 5 +-
RPC/Sources/RPC/Server.swift | 4 +-
.../xcshareddata/swiftpm/Package.resolved | 14 ++---
9 files changed, 98 insertions(+), 55 deletions(-)
create mode 100644 Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
diff --git a/Boka/Package.swift b/Boka/Package.swift
index 57ce41ce..2ed4bfb1 100644
--- a/Boka/Package.swift
+++ b/Boka/Package.swift
@@ -13,7 +13,7 @@ let package = Package(
.package(path: "../TracingUtils"),
.package(url: "https://github.com/slashmo/swift-otel.git", from: "0.9.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.6.0"),
- .package(url: "https://github.com/vapor/console-kit.git", from: "4.14.3"),
+ .package(url: "https://github.com/vapor/console-kit.git", from: "4.15.0"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index 696d3281..8b322b89 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -70,14 +70,6 @@ struct Boka: AsyncCommand {
context.console.info("Base path: \(basePath)")
}
- if let chain = signature.chain {
- context.console.info("Chain: \(chain)")
- }
-
- if let configFile = signature.configFile {
- context.console.info("Config file: \(configFile)")
- }
-
if let p2p = signature.p2p {
context.console.info("P2P listen address: \(p2p)")
}
@@ -122,7 +114,14 @@ struct Boka: AsyncCommand {
handlerMiddleware: .tracing(prefix: "Handler")
)
let keystore = try await DevKeyStore()
- let node = try await ValidatorNode(genesis: .dev, config: config, eventBus: eventBus, keystore: keystore)
+ var genesis: Genesis = .dev
+ if let configFile = signature.configFile {
+ context.console.info("Config file: \(configFile)")
+ genesis = .file(path: configFile)
+ }
+ let node: ValidatorNode = try await ValidatorNode(
+ genesis: genesis, config: config, eventBus: eventBus, keystore: keystore
+ )
for service in services {
Task {
try await service.run()
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
new file mode 100644
index 00000000..f8742cd2
--- /dev/null
+++ b/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
@@ -0,0 +1,43 @@
+{
+ "name": "Devnet",
+ "id": "devnet-1",
+ "bootnodes": ["127.0.0.1:9955"],
+ "preset": null,
+ "config": {
+ "auditTranchePeriod": 10,
+ "additionalMinBalancePerStateItem": 1,
+ "additionalMinBalancePerStateByte": 1,
+ "serviceMinBalance": 100,
+ "totalNumberOfCores": 1,
+ "preimagePurgePeriod": 100,
+ "epochLength": 1000,
+ "auditBiasFactor": 1,
+ "coreAccumulationGas": 10,
+ "workPackageAuthorizerGas": 5,
+ "workPackageRefineGas": 2,
+ "recentHistorySize": 10,
+ "maxWorkItems": 2,
+ "maxTicketsPerExtrinsic": 1,
+ "maxLookupAnchorAge": 10,
+ "transferMemoSize": 64,
+ "ticketEntriesPerValidator": 1,
+ "maxAuthorizationsPoolItems": 10,
+ "slotPeriodSeconds": 1,
+ "maxAuthorizationsQueueItems": 5,
+ "coreAssignmentRotationPeriod": 100,
+ "maxServiceCodeSize": 256,
+ "preimageReplacementPeriod": 100,
+ "totalNumberOfValidators": 5,
+ "erasureCodedPieceSize": 128,
+ "maxWorkPackageManifestEntries": 2,
+ "maxEncodedWorkPackageSize": 512,
+ "maxEncodedWorkReportSize": 256,
+ "erasureCodedSegmentSize": 1024,
+ "ticketSubmissionEndSlot": 10,
+ "pvmDynamicAddressAlignmentFactor": 2,
+ "pvmProgramInitInputDataSize": 64,
+ "pvmProgramInitPageSize": 1024,
+ "pvmProgramInitSegmentSize": 2048
+ },
+ "state": "0x789abc"
+}
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
index 51fce04b..92f107cc 100644
--- a/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
+++ b/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
@@ -5,7 +5,7 @@
"node1.mainnet.com",
"node2.mainnet.com"
],
- "preset": "devnet",
+ "preset": "dev",
"state": "0x1234567890abcdef"
}
\ No newline at end of file
diff --git a/Node/Package.resolved b/Node/Package.resolved
index ed891dc2..3b73112d 100644
--- a/Node/Package.resolved
+++ b/Node/Package.resolved
@@ -141,8 +141,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
- "revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e",
- "version" : "1.23.0"
+ "revision" : "d1ead62745cc3269e482f1c51f27608057174379",
+ "version" : "1.24.0"
}
},
{
@@ -204,8 +204,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/vapor.git",
"state" : {
- "revision" : "a823735db57b46100b0c61cdfc5a08525b1e7cad",
- "version" : "4.102.1"
+ "revision" : "1466c50e4ad39072143e2fcdf13b4ba11be375a0",
+ "version" : "4.106.0"
}
},
{
diff --git a/RPC/Package.resolved b/RPC/Package.resolved
index cb3923e3..8dce31cb 100644
--- a/RPC/Package.resolved
+++ b/RPC/Package.resolved
@@ -1,13 +1,13 @@
{
- "originHash" : "b321ce09e4e6d9d71a2e200de7c83616493e740a9be4805f0d13a7caba7a8086",
+ "originHash" : "7b96cffee59bcf3ffc3dd86f84561500dff49efc82bcdd615bb1d37430c8c096",
"pins" : [
{
"identity" : "async-http-client",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
- "revision" : "0ae99db85b2b9d1e79b362bd31fd1ffe492f7c47",
- "version" : "1.21.2"
+ "revision" : "64abc77edf1ef81e69bd90a2ac386de615c8e8ea",
+ "version" : "1.23.0"
}
},
{
@@ -15,8 +15,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/async-kit.git",
"state" : {
- "revision" : "15b3fb7b2437f9db11f6ddcf365c5b5db8c3a346",
- "version" : "1.19.1"
+ "revision" : "e048c8ee94967e8d8a1c2ec0e1156d6f7fa34d31",
+ "version" : "1.20.0"
}
},
{
@@ -33,8 +33,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/console-kit.git",
"state" : {
- "revision" : "9f7932f22ab6f64aafadc14491e694179b7d0f6f",
- "version" : "4.14.3"
+ "revision" : "78c0dd739df8cb9ee14a8bbbf770facc4fc3402a",
+ "version" : "4.15.0"
}
},
{
@@ -78,8 +78,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
- "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
- "version" : "1.1.2"
+ "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
+ "version" : "1.1.4"
}
},
{
@@ -87,8 +87,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-crypto.git",
"state" : {
- "revision" : "46072478ca365fe48370993833cb22de9b41567f",
- "version" : "3.5.2"
+ "revision" : "ffca28be3c9c6a86a579949d23f68818a4b9b5d8",
+ "version" : "3.8.0"
}
},
{
@@ -96,8 +96,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-distributed-tracing.git",
"state" : {
- "revision" : "11c756c5c4d7de0eeed8595695cadd7fa107aa19",
- "version" : "1.1.1"
+ "revision" : "6483d340853a944c96dbcc28b27dd10b6c581703",
+ "version" : "1.1.2"
}
},
{
@@ -132,8 +132,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
- "revision" : "fc79798d5a150d61361a27ce0c51169b889e23de",
- "version" : "2.68.0"
+ "revision" : "665206000b8307cab5ac51203d29b0f232d7e31b",
+ "version" : "2.74.0"
}
},
{
@@ -141,8 +141,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
- "revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e",
- "version" : "1.23.0"
+ "revision" : "d1ead62745cc3269e482f1c51f27608057174379",
+ "version" : "1.24.0"
}
},
{
@@ -150,8 +150,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
- "revision" : "a0224f3d20438635dd59c9fcc593520d80d131d0",
- "version" : "1.33.0"
+ "revision" : "eaa71bb6ae082eee5a07407b1ad0cbd8f48f9dca",
+ "version" : "1.34.1"
}
},
{
@@ -159,8 +159,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
- "revision" : "2b09805797f21c380f7dc9bedaab3157c5508efb",
- "version" : "2.27.0"
+ "revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69",
+ "version" : "2.27.2"
}
},
{
@@ -168,8 +168,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
- "revision" : "38ac8221dd20674682148d6451367f89c2652980",
- "version" : "1.21.0"
+ "revision" : "dbace16f126fdcd80d58dc54526c561ca17327d7",
+ "version" : "1.22.0"
}
},
{
@@ -195,8 +195,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
- "revision" : "06b5cdc432e93b60e3bdf53aff2857c6b312991a",
- "version" : "600.0.0-prerelease-2024-07-30"
+ "revision" : "0687f71944021d616d34d922343dcef086855920",
+ "version" : "600.0.1"
}
},
{
@@ -204,8 +204,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
- "revision" : "6a9e38e7bd22a3b8ba80bddf395623cf68f57807",
- "version" : "1.3.1"
+ "revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
+ "version" : "1.3.2"
}
},
{
@@ -222,8 +222,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/vapor.git",
"state" : {
- "revision" : "a823735db57b46100b0c61cdfc5a08525b1e7cad",
- "version" : "4.102.1"
+ "revision" : "1466c50e4ad39072143e2fcdf13b4ba11be375a0",
+ "version" : "4.106.0"
}
},
{
diff --git a/RPC/Package.swift b/RPC/Package.swift
index 83db47f3..f175b3f3 100644
--- a/RPC/Package.swift
+++ b/RPC/Package.swift
@@ -18,9 +18,10 @@ let package = Package(
dependencies: [
.package(path: "../Blockchain"),
.package(path: "../Utils"),
- .package(url: "https://github.com/vapor/vapor.git", from: "4.102.1"),
- .package(url: "https://github.com/vapor/async-kit.git", from: "1.19.1"),
+ .package(url: "https://github.com/vapor/vapor.git", from: "4.106.0"),
+ .package(url: "https://github.com/vapor/async-kit.git", from: "1.20.0"),
.package(url: "https://github.com/apple/swift-testing.git", branch: "0.10.0"),
+
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
diff --git a/RPC/Sources/RPC/Server.swift b/RPC/Sources/RPC/Server.swift
index bcf29b64..5540be93 100644
--- a/RPC/Sources/RPC/Server.swift
+++ b/RPC/Sources/RPC/Server.swift
@@ -23,8 +23,8 @@ public class Server {
public init(config: Config, source: DataSource) throws {
self.config = config
self.source = source
-
- let env = try Environment.detect()
+ // TODO: add env to arguments
+ let env = try Environment.detect(arguments: ["--env"])
app = Application(env)
var handlers: [String: JSONRPCHandler] = SystemHandler.getHandlers()
diff --git a/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 48b1a9c8..2cefe6f1 100644
--- a/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/boka.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "74f67ee171359522e232c57cd2ceb3e2aee823b7fadbe87349ca4a2605336aad",
+ "originHash" : "1983aff92fc95ce4913c3cc7907ebe17a0b29b1041bb5c359d4ade488640ded6",
"pins" : [
{
"identity" : "async-http-client",
@@ -33,8 +33,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/console-kit.git",
"state" : {
- "revision" : "9f7932f22ab6f64aafadc14491e694179b7d0f6f",
- "version" : "4.14.3"
+ "revision" : "78c0dd739df8cb9ee14a8bbbf770facc4fc3402a",
+ "version" : "4.15.0"
}
},
{
@@ -159,8 +159,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
- "revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e",
- "version" : "1.23.0"
+ "revision" : "d1ead62745cc3269e482f1c51f27608057174379",
+ "version" : "1.24.0"
}
},
{
@@ -267,8 +267,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/vapor/vapor.git",
"state" : {
- "revision" : "a823735db57b46100b0c61cdfc5a08525b1e7cad",
- "version" : "4.102.1"
+ "revision" : "1466c50e4ad39072143e2fcdf13b4ba11be375a0",
+ "version" : "4.106.0"
}
},
{
From 11a5b693cb6435a43dd1da6e23692ac1a37f7b40 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 17:31:29 +0800
Subject: [PATCH 07/22] update genesis
---
Node/Sources/Node/Genesis.swift | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index fc48e2f0..d16476e4 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -33,14 +33,10 @@ extension Genesis {
case let .file(path):
let genesis = try GenesisFileHandler().readAndValidateGenesis(from: path)
var config: ProtocolConfig
- switch genesis.preset?.lowercased() {
- case "dev":
- config = ProtocolConfigRef.dev.value
- if let genesisConfig = genesis.config {
- config = config.merged(with: genesisConfig)
- }
- case "mainnet":
- config = ProtocolConfigRef.mainnet.value
+ let preset = genesis.preset?.lowercased()
+ switch preset {
+ case "dev", "mainnet":
+ config = (preset == "dev" ? ProtocolConfigRef.dev.value : ProtocolConfigRef.mainnet.value)
if let genesisConfig = genesis.config {
config = config.merged(with: genesisConfig)
}
From 5c7d08016d42b5af23acd43bf9f043d3b240eeba Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 18:04:04 +0800
Subject: [PATCH 08/22] update genesis file
---
Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json | 1 -
.../BokaTests/chainfiles/mainnet_someconfig_spec.json | 4 +---
Node/Sources/Node/Genesis.swift | 7 ++++---
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
index f8742cd2..7613c9a8 100644
--- a/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
+++ b/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
@@ -2,7 +2,6 @@
"name": "Devnet",
"id": "devnet-1",
"bootnodes": ["127.0.0.1:9955"],
- "preset": null,
"config": {
"auditTranchePeriod": 10,
"additionalMinBalancePerStateItem": 1,
diff --git a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
index 54936212..ca1ade2e 100644
--- a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
+++ b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
@@ -2,10 +2,8 @@
"name": "Mainnet",
"id": "mainnet-1",
"bootnodes": [
- "enode://abc@1.2.3.4:30303",
- "enode://def@5.6.7.8:30303"
+ "127.0.0.1:9955"
],
- "preset": "mainnet",
"config": {
"auditTranchePeriod": 100,
"additionalMinBalancePerStateItem": 10,
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index d16476e4..6210e908 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -99,12 +99,13 @@ class GenesisFileHandler {
throw GenesisError.invalidFormat("Invalid or missing 'bootnodes'")
}
if genesis.state.isEmpty {
- throw GenesisError.invalidFormat("Invalid or missing 'state'")
+ throw GenesisError.invalidFormat("Invalid or missing 'state'") bjnii
}
- if let preset = genesis.preset, !["dev", "mainnet"].contains(preset.lowercased()) {
+ let preset = genesis.preset?.lowercased()
+ if preset != nil, !["dev", "mainnet"].contains(preset!) {
throw GenesisError.invalidFormat("Invalid preset value. Must be 'dev' or 'mainnet'.")
}
- if genesis.preset == nil, genesis.missConfigFiled() {
+ if preset == nil, genesis.missConfigFiled() {
throw GenesisError.invalidFormat("Missing 'preset' or 'config' field.")
}
}
From 80e82e8dcbf734f7bcfbdca4fdf6e6d0a6eb20f3 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 19:06:22 +0800
Subject: [PATCH 09/22] udpate genesis
---
Node/Sources/Node/Genesis.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index 6210e908..4b4dd5e6 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -99,7 +99,7 @@ class GenesisFileHandler {
throw GenesisError.invalidFormat("Invalid or missing 'bootnodes'")
}
if genesis.state.isEmpty {
- throw GenesisError.invalidFormat("Invalid or missing 'state'") bjnii
+ throw GenesisError.invalidFormat("Invalid or missing 'state'")
}
let preset = genesis.preset?.lowercased()
if preset != nil, !["dev", "mainnet"].contains(preset!) {
From 7dcc3bab94f79f0c0fa7771ef227b6e62350228d Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Mon, 14 Oct 2024 19:10:06 +0800
Subject: [PATCH 10/22] revert submodule change
---
JAMTests/jamtestvectors | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/JAMTests/jamtestvectors b/JAMTests/jamtestvectors
index 4fdcf95a..92890655 160000
--- a/JAMTests/jamtestvectors
+++ b/JAMTests/jamtestvectors
@@ -1 +1 @@
-Subproject commit 4fdcf95aeed04d53bb4198373925d34f63069059
+Subproject commit 9289065548ccbc11ee21f9e47bc0f99a91502fed
From 58c6d1ade18e735035907b51a04e029cc9ee6da9 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 06:29:05 +0800
Subject: [PATCH 11/22] Update Node/Sources/Node/Genesis.swift
Co-authored-by: Xiliang Chen
---
Node/Sources/Node/Genesis.swift | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index 4b4dd5e6..a11ac4be 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -43,8 +43,9 @@ extension Genesis {
default:
config = genesis.config!
}
- let state = try State.devGenesis(config: Ref(config))
- return (StateRef(state), Ref(config))
+ let configRef = Ref(config)
+ let state = try State.devGenesis(config: configRef)
+ return (StateRef(state), configRef)
}
}
}
From f899bcdf57e571e6036a9bc01f012de5f488cf4f Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 07:36:53 +0800
Subject: [PATCH 12/22] update genesis
---
.../xcschemes/Networking.xcscheme | 10 +++
Node/Sources/Node/Genesis.swift | 86 +++++++++----------
2 files changed, 50 insertions(+), 46 deletions(-)
diff --git a/Networking/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme b/Networking/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
index 943c06eb..7cdbd250 100644
--- a/Networking/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
+++ b/Networking/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
@@ -40,6 +40,16 @@
ReferencedContainer = "container:">
+
+
+
+
Bool {
- guard let config else {
- return true
- }
- let mirror = Mirror(reflecting: config)
- for child in mirror.children {
- if let value = child.value as? Int, value == 0 {
- return true
- }
- if let value = child.value as? Gas, value.value == 0 {
- return true
- }
- }
- return false
- }
-}
-// Class to handle Genesis JSON file operations
-class GenesisFileHandler {
- private func validateGenesis(_ genesis: GenesisData) throws {
+ private func validate(_ genesis: GenesisData) throws {
// Validate required fields
if genesis.name.isEmpty {
throw GenesisError.invalidFormat("Invalid or missing 'name'")
@@ -105,7 +63,7 @@ class GenesisFileHandler {
if preset != nil, !["dev", "mainnet"].contains(preset!) {
throw GenesisError.invalidFormat("Invalid preset value. Must be 'dev' or 'mainnet'.")
}
- if preset == nil, genesis.missConfigFiled() {
+ if preset == nil, genesis.validateConfig() {
throw GenesisError.invalidFormat("Missing 'preset' or 'config' field.")
}
}
@@ -116,7 +74,7 @@ class GenesisFileHandler {
let data = fileContents.data(using: .utf8)!
let decoder = JSONDecoder()
let genesis = try decoder.decode(GenesisData.self, from: data)
- try validateGenesis(genesis)
+ try validate(genesis)
return genesis
} catch let error as GenesisError {
throw error
@@ -125,3 +83,39 @@ class GenesisFileHandler {
}
}
}
+
+struct GenesisData: Sendable, Codable {
+ var name: String
+ var id: String
+ var bootnodes: [String]
+ var preset: String?
+ var config: ProtocolConfig?
+ // TODO: check & deal with state
+ var state: String
+
+ init(from decoder: Decoder) throws {
+ let container = try decoder.container(keyedBy: CodingKeys.self)
+ name = try container.decode(String.self, forKey: .name)
+ id = try container.decode(String.self, forKey: .id)
+ bootnodes = try container.decode([String].self, forKey: .bootnodes)
+ preset = try container.decodeIfPresent(String.self, forKey: .preset)
+ config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config)
+ state = try container.decode(String.self, forKey: .state)
+ }
+
+ func validateConfig() -> Bool {
+ guard let config: ProtocolConfig else {
+ return true
+ }
+ let mirror = Mirror(reflecting: config)
+ for child in mirror.children {
+ if let value = child.value as? Int, value == 0 {
+ return true
+ }
+ if let value = child.value as? Gas, value.value == 0 {
+ return true
+ }
+ }
+ return false
+ }
+}
From 1c96d8f6264514b8c32fb0698234995ad252c9a3 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 15:09:52 +0800
Subject: [PATCH 13/22] update genesis
---
.../Blockchain/Config/ProtocolConfig.swift | 166 +++++++++++-------
.../chainfiles/mainnet_someconfig_spec.json | 3 +-
Node/Sources/Node/Genesis.swift | 42 ++---
3 files changed, 121 insertions(+), 90 deletions(-)
diff --git a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
index 0002b447..532d482c 100644
--- a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
+++ b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
@@ -191,6 +191,19 @@ extension Ref: @retroactive PvmConfig where T == ProtocolConfig {
public var pvmProgramInitSegmentSize: Int { value.pvmProgramInitSegmentSize }
}
+extension KeyedDecodingContainer {
+ func decode(_: ProtocolConfig.Type, forKey key: K) throws -> ProtocolConfig {
+ let nestedDecoder = try superDecoder(forKey: key)
+ return try ProtocolConfig(from: nestedDecoder, true)
+ }
+
+ func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, required _: Bool) throws -> ProtocolConfig? {
+ guard contains(key) else { return nil }
+ let nestedDecoder = try superDecoder(forKey: key)
+ return try ProtocolConfig(from: nestedDecoder)
+ }
+}
+
extension ProtocolConfig {
public func merged(with other: ProtocolConfig) -> ProtocolConfig {
ProtocolConfig(
@@ -263,76 +276,93 @@ extension ProtocolConfig {
)
}
- public init(from decoder: Decoder) throws {
+ public init(from decoder: Decoder, _ required: Bool = false) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
- auditTranchePeriod =
- try container.decodeIfPresent(Int.self, forKey: .auditTranchePeriod) ?? 0
- additionalMinBalancePerStateItem =
- try container.decodeIfPresent(Int.self, forKey: .additionalMinBalancePerStateItem) ?? 0
- additionalMinBalancePerStateByte =
- try container.decodeIfPresent(Int.self, forKey: .additionalMinBalancePerStateByte) ?? 0
- serviceMinBalance =
- try container.decodeIfPresent(Int.self, forKey: .serviceMinBalance) ?? 0
- totalNumberOfCores =
- try container.decodeIfPresent(Int.self, forKey: .totalNumberOfCores) ?? 0
- preimagePurgePeriod =
- try container.decodeIfPresent(Int.self, forKey: .preimagePurgePeriod) ?? 0
- epochLength = try container.decodeIfPresent(Int.self, forKey: .epochLength) ?? 0
- auditBiasFactor =
- try container.decodeIfPresent(Int.self, forKey: .auditBiasFactor) ?? 0
- coreAccumulationGas =
- try container.decodeIfPresent(Gas.self, forKey: .coreAccumulationGas) ?? Gas(0)
- workPackageAuthorizerGas =
- try container.decodeIfPresent(Gas.self, forKey: .workPackageAuthorizerGas)
- ?? Gas(0)
- workPackageRefineGas =
- try container.decodeIfPresent(Gas.self, forKey: .workPackageRefineGas) ?? Gas(0)
- recentHistorySize =
- try container.decodeIfPresent(Int.self, forKey: .recentHistorySize) ?? 0
- maxWorkItems = try container.decodeIfPresent(Int.self, forKey: .maxWorkItems) ?? 0
- maxTicketsPerExtrinsic =
- try container.decodeIfPresent(Int.self, forKey: .maxTicketsPerExtrinsic) ?? 0
- maxLookupAnchorAge =
- try container.decodeIfPresent(Int.self, forKey: .maxLookupAnchorAge) ?? 0
- transferMemoSize =
- try container.decodeIfPresent(Int.self, forKey: .transferMemoSize) ?? 0
- ticketEntriesPerValidator =
- try container.decodeIfPresent(Int.self, forKey: .ticketEntriesPerValidator) ?? 0
- maxAuthorizationsPoolItems =
- try container.decodeIfPresent(Int.self, forKey: .maxAuthorizationsPoolItems) ?? 0
- slotPeriodSeconds =
- try container.decodeIfPresent(Int.self, forKey: .slotPeriodSeconds) ?? 0
- maxAuthorizationsQueueItems =
- try container.decodeIfPresent(Int.self, forKey: .maxAuthorizationsQueueItems) ?? 0
- coreAssignmentRotationPeriod =
- try container.decodeIfPresent(Int.self, forKey: .coreAssignmentRotationPeriod) ?? 0
- maxServiceCodeSize =
- try container.decodeIfPresent(Int.self, forKey: .maxServiceCodeSize) ?? 0
- preimageReplacementPeriod =
- try container.decodeIfPresent(Int.self, forKey: .preimageReplacementPeriod) ?? 0
- totalNumberOfValidators =
- try container.decodeIfPresent(Int.self, forKey: .totalNumberOfValidators) ?? 0
- erasureCodedPieceSize =
- try container.decodeIfPresent(Int.self, forKey: .erasureCodedPieceSize) ?? 0
- maxWorkPackageManifestEntries =
- try container.decodeIfPresent(Int.self, forKey: .maxWorkPackageManifestEntries) ?? 0
- maxEncodedWorkPackageSize =
- try container.decodeIfPresent(Int.self, forKey: .maxEncodedWorkPackageSize) ?? 0
- maxEncodedWorkReportSize =
- try container.decodeIfPresent(Int.self, forKey: .maxEncodedWorkReportSize) ?? 0
- erasureCodedSegmentSize =
- try container.decodeIfPresent(Int.self, forKey: .erasureCodedSegmentSize) ?? 0
- ticketSubmissionEndSlot =
- try container.decodeIfPresent(Int.self, forKey: .ticketSubmissionEndSlot) ?? 0
- pvmDynamicAddressAlignmentFactor =
- try container.decodeIfPresent(Int.self, forKey: .pvmDynamicAddressAlignmentFactor) ?? 0
- pvmProgramInitInputDataSize =
- try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitInputDataSize) ?? 0
- pvmProgramInitPageSize =
- try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitPageSize) ?? 0
- pvmProgramInitSegmentSize =
- try container.decodeIfPresent(Int.self, forKey: .pvmProgramInitSegmentSize) ?? 0
+ func decode(_ key: CodingKeys, defaultValue: T, required: Bool) throws -> T {
+ if required {
+ try container.decode(T.self, forKey: key)
+ } else {
+ try container.decodeIfPresent(T.self, forKey: key) ?? defaultValue
+ }
+ }
+
+ auditTranchePeriod = try decode(.auditTranchePeriod, defaultValue: 0, required: required)
+ additionalMinBalancePerStateItem = try decode(
+ .additionalMinBalancePerStateItem, defaultValue: 0, required: required
+ )
+ additionalMinBalancePerStateByte = try decode(
+ .additionalMinBalancePerStateByte, defaultValue: 0, required: required
+ )
+ serviceMinBalance = try decode(.serviceMinBalance, defaultValue: 0, required: required)
+ totalNumberOfCores = try decode(.totalNumberOfCores, defaultValue: 0, required: required)
+ preimagePurgePeriod = try decode(.preimagePurgePeriod, defaultValue: 0, required: required)
+ epochLength = try decode(.epochLength, defaultValue: 0, required: required)
+ auditBiasFactor = try decode(.auditBiasFactor, defaultValue: 0, required: required)
+ coreAccumulationGas = try decode(
+ .coreAccumulationGas, defaultValue: Gas(0), required: required
+ )
+ workPackageAuthorizerGas = try decode(
+ .workPackageAuthorizerGas, defaultValue: Gas(0), required: required
+ )
+ workPackageRefineGas = try decode(
+ .workPackageRefineGas, defaultValue: Gas(0), required: required
+ )
+ recentHistorySize = try decode(.recentHistorySize, defaultValue: 0, required: required)
+ maxWorkItems = try decode(.maxWorkItems, defaultValue: 0, required: required)
+ maxTicketsPerExtrinsic = try decode(
+ .maxTicketsPerExtrinsic, defaultValue: 0, required: required
+ )
+ maxLookupAnchorAge = try decode(.maxLookupAnchorAge, defaultValue: 0, required: required)
+ transferMemoSize = try decode(.transferMemoSize, defaultValue: 0, required: required)
+ ticketEntriesPerValidator = try decode(
+ .ticketEntriesPerValidator, defaultValue: 0, required: required
+ )
+ maxAuthorizationsPoolItems = try decode(
+ .maxAuthorizationsPoolItems, defaultValue: 0, required: required
+ )
+ slotPeriodSeconds = try decode(.slotPeriodSeconds, defaultValue: 0, required: required)
+ maxAuthorizationsQueueItems = try decode(
+ .maxAuthorizationsQueueItems, defaultValue: 0, required: required
+ )
+ coreAssignmentRotationPeriod = try decode(
+ .coreAssignmentRotationPeriod, defaultValue: 0, required: required
+ )
+ maxServiceCodeSize = try decode(.maxServiceCodeSize, defaultValue: 0, required: required)
+ preimageReplacementPeriod = try decode(
+ .preimageReplacementPeriod, defaultValue: 0, required: required
+ )
+ totalNumberOfValidators = try decode(
+ .totalNumberOfValidators, defaultValue: 0, required: required
+ )
+ erasureCodedPieceSize = try decode(.erasureCodedPieceSize, defaultValue: 0, required: required)
+ maxWorkPackageManifestEntries = try decode(
+ .maxWorkPackageManifestEntries, defaultValue: 0, required: required
+ )
+ maxEncodedWorkPackageSize = try decode(
+ .maxEncodedWorkPackageSize, defaultValue: 0, required: required
+ )
+ maxEncodedWorkReportSize = try decode(
+ .maxEncodedWorkReportSize, defaultValue: 0, required: required
+ )
+ erasureCodedSegmentSize = try decode(
+ .erasureCodedSegmentSize, defaultValue: 0, required: required
+ )
+ ticketSubmissionEndSlot = try decode(
+ .ticketSubmissionEndSlot, defaultValue: 0, required: required
+ )
+ pvmDynamicAddressAlignmentFactor = try decode(
+ .pvmDynamicAddressAlignmentFactor, defaultValue: 0, required: required
+ )
+ pvmProgramInitInputDataSize = try decode(
+ .pvmProgramInitInputDataSize, defaultValue: 0, required: required
+ )
+ pvmProgramInitPageSize = try decode(
+ .pvmProgramInitPageSize, defaultValue: 0, required: required
+ )
+ pvmProgramInitSegmentSize = try decode(
+ .pvmProgramInitSegmentSize, defaultValue: 0, required: required
+ )
}
}
diff --git a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
index ca1ade2e..5bc02817 100644
--- a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
+++ b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
@@ -4,6 +4,7 @@
"bootnodes": [
"127.0.0.1:9955"
],
+ "preset": "mainnet",
"config": {
"auditTranchePeriod": 100,
"additionalMinBalancePerStateItem": 10,
@@ -22,4 +23,4 @@
"maxLookupAnchorAge": 100
},
"state": "0xabcdef"
-}
\ No newline at end of file
+}
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index e9e01951..36686d29 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -33,11 +33,14 @@ extension Genesis {
let preset = genesis.preset?.lowercased()
switch preset {
case "dev", "mainnet":
- config = (preset == "dev" ? ProtocolConfigRef.dev.value : ProtocolConfigRef.mainnet.value)
+ config =
+ (preset == "dev"
+ ? ProtocolConfigRef.dev.value : ProtocolConfigRef.mainnet.value)
if let genesisConfig = genesis.config {
config = config.merged(with: genesisConfig)
}
default:
+ // In this case, genesis.config has been verified to be non-nil
config = genesis.config!
}
let configRef = Ref(config)
@@ -64,9 +67,6 @@ extension Genesis {
if preset != nil, !["dev", "mainnet"].contains(preset!) {
throw GenesisError.invalidFormat("Invalid preset value. Must be 'dev' or 'mainnet'.")
}
- if preset == nil, genesis.validateConfig() {
- throw GenesisError.invalidFormat("Missing 'preset' or 'config' field.")
- }
}
func readAndValidateGenesis(from filePath: String) throws -> GenesisData {
@@ -85,6 +85,18 @@ extension Genesis {
}
}
+extension KeyedDecodingContainer {
+ func decode(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = true) throws -> ProtocolConfig {
+ let nestedDecoder = try superDecoder(forKey: key)
+ return try ProtocolConfig(from: nestedDecoder, required)
+ }
+
+ func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = false) throws -> ProtocolConfig {
+ let nestedDecoder = try superDecoder(forKey: key)
+ return try ProtocolConfig(from: nestedDecoder, required)
+ }
+}
+
struct GenesisData: Sendable, Codable {
var name: String
var id: String
@@ -100,23 +112,11 @@ struct GenesisData: Sendable, Codable {
id = try container.decode(String.self, forKey: .id)
bootnodes = try container.decode([String].self, forKey: .bootnodes)
preset = try container.decodeIfPresent(String.self, forKey: .preset)
- config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config)
- state = try container.decode(String.self, forKey: .state)
- }
-
- func validateConfig() -> Bool {
- guard let config: ProtocolConfig else {
- return true
- }
- let mirror = Mirror(reflecting: config)
- for child in mirror.children {
- if let value = child.value as? Int, value == 0 {
- return true
- }
- if let value = child.value as? Gas, value.value == 0 {
- return true
- }
+ if preset == nil || !["dev", "mainnet"].contains(preset) {
+ config = try container.decode(ProtocolConfig.self, forKey: .config, true)
+ } else {
+ config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config, false)
}
- return false
+ state = try container.decode(String.self, forKey: .state)
}
}
From dbc50f4030382ad5f8bbcc71a1f3fad59faa5260 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 15:34:14 +0800
Subject: [PATCH 14/22] update genesis
---
Node/Sources/Node/Genesis.swift | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index 36686d29..ace37ee5 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -91,7 +91,10 @@ extension KeyedDecodingContainer {
return try ProtocolConfig(from: nestedDecoder, required)
}
- func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = false) throws -> ProtocolConfig {
+ func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = false) throws -> ProtocolConfig? {
+ guard contains(key), try !decodeNil(forKey: key) else {
+ return nil
+ }
let nestedDecoder = try superDecoder(forKey: key)
return try ProtocolConfig(from: nestedDecoder, required)
}
From 8597dfe918f09fe0ad8c2a331bb414b0363a1941 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 15:43:08 +0800
Subject: [PATCH 15/22] delete KeyedDecodingContainer
---
.../Sources/Blockchain/Config/ProtocolConfig.swift | 13 -------------
Node/Sources/Node/Genesis.swift | 12 +++++-------
2 files changed, 5 insertions(+), 20 deletions(-)
diff --git a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
index 532d482c..f2b68cbc 100644
--- a/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
+++ b/Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
@@ -191,19 +191,6 @@ extension Ref: @retroactive PvmConfig where T == ProtocolConfig {
public var pvmProgramInitSegmentSize: Int { value.pvmProgramInitSegmentSize }
}
-extension KeyedDecodingContainer {
- func decode(_: ProtocolConfig.Type, forKey key: K) throws -> ProtocolConfig {
- let nestedDecoder = try superDecoder(forKey: key)
- return try ProtocolConfig(from: nestedDecoder, true)
- }
-
- func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, required _: Bool) throws -> ProtocolConfig? {
- guard contains(key) else { return nil }
- let nestedDecoder = try superDecoder(forKey: key)
- return try ProtocolConfig(from: nestedDecoder)
- }
-}
-
extension ProtocolConfig {
public func merged(with other: ProtocolConfig) -> ProtocolConfig {
ProtocolConfig(
diff --git a/Node/Sources/Node/Genesis.swift b/Node/Sources/Node/Genesis.swift
index ace37ee5..52980efe 100644
--- a/Node/Sources/Node/Genesis.swift
+++ b/Node/Sources/Node/Genesis.swift
@@ -86,15 +86,13 @@ extension Genesis {
}
extension KeyedDecodingContainer {
- func decode(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = true) throws -> ProtocolConfig {
+ func decode(_: ProtocolConfig.Type, forKey key: K, required: Bool = true) throws -> ProtocolConfig {
let nestedDecoder = try superDecoder(forKey: key)
return try ProtocolConfig(from: nestedDecoder, required)
}
- func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, _ required: Bool = false) throws -> ProtocolConfig? {
- guard contains(key), try !decodeNil(forKey: key) else {
- return nil
- }
+ func decodeIfPresent(_: ProtocolConfig.Type, forKey key: K, required: Bool = false) throws -> ProtocolConfig? {
+ guard contains(key) else { return nil }
let nestedDecoder = try superDecoder(forKey: key)
return try ProtocolConfig(from: nestedDecoder, required)
}
@@ -116,9 +114,9 @@ struct GenesisData: Sendable, Codable {
bootnodes = try container.decode([String].self, forKey: .bootnodes)
preset = try container.decodeIfPresent(String.self, forKey: .preset)
if preset == nil || !["dev", "mainnet"].contains(preset) {
- config = try container.decode(ProtocolConfig.self, forKey: .config, true)
+ config = try container.decode(ProtocolConfig.self, forKey: .config, required: true)
} else {
- config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config, false)
+ config = try container.decodeIfPresent(ProtocolConfig.self, forKey: .config, required: false)
}
state = try container.decode(String.self, forKey: .state)
}
From 8c7a1396d32f9cea838836dbac7edf2935db1ca8 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 15:45:37 +0800
Subject: [PATCH 16/22] update main
---
Boka/Sources/main.swift | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Boka/Sources/main.swift b/Boka/Sources/main.swift
index c8c524e8..8c566d23 100644
--- a/Boka/Sources/main.swift
+++ b/Boka/Sources/main.swift
@@ -7,5 +7,6 @@ let boka = Boka()
do {
try await console.run(boka, input: input)
} catch {
- console.error("\(error)")
+ console.error("\(error.localizedDescription)")
+ throw error
}
From f68b0913b7bf7e259e8bb00621ed6ec35aa7398f Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 18:23:01 +0800
Subject: [PATCH 17/22] update spec
---
Boka/Package.resolved | 22 ++++++++++-
Boka/Package.swift | 9 ++++-
Boka/Tests/BokaTests/BokaTests.swift | 37 +++++++++++++++----
.../chainfiles/devnet_allconfig_spec.json | 0
.../chainfiles/devnet_noconfig_spec.json | 0
.../chainfiles/mainnet_someconfig_spec.json | 0
6 files changed, 57 insertions(+), 11 deletions(-)
rename Boka/{Tests/BokaTests => }/chainfiles/devnet_allconfig_spec.json (100%)
rename Boka/{Tests/BokaTests => }/chainfiles/devnet_noconfig_spec.json (100%)
rename Boka/{Tests/BokaTests => }/chainfiles/mainnet_someconfig_spec.json (100%)
diff --git a/Boka/Package.resolved b/Boka/Package.resolved
index 478bf7bc..0e3efad7 100644
--- a/Boka/Package.resolved
+++ b/Boka/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "3ffe5d8aed92ff623b0fda4bed30c24dbc202e6d967a574ec3c6096b0093f399",
+ "originHash" : "aee764b7bc3e981812abaf1d794ce8c732d662c7df55dc80fdf75322c145e77c",
"pins" : [
{
"identity" : "async-http-client",
@@ -193,7 +193,7 @@
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
- "location" : "https://github.com/apple/swift-numerics.git",
+ "location" : "https://github.com/apple/swift-numerics",
"state" : {
"branch" : "main",
"revision" : "e30276bff2ff5ed80566fbdca49f50aa160b0e83"
@@ -235,6 +235,15 @@
"version" : "2.6.1"
}
},
+ {
+ "identity" : "swift-syntax",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-syntax.git",
+ "state" : {
+ "revision" : "0687f71944021d616d34d922343dcef086855920",
+ "version" : "600.0.1"
+ }
+ },
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
@@ -244,6 +253,15 @@
"version" : "1.3.2"
}
},
+ {
+ "identity" : "swift-testing",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-testing.git",
+ "state" : {
+ "branch" : "0.10.0",
+ "revision" : "69d59cfc76e5daf498ca61f5af409f594768eef9"
+ }
+ },
{
"identity" : "swift-w3c-trace-context",
"kind" : "remoteSourceControl",
diff --git a/Boka/Package.swift b/Boka/Package.swift
index 2ed4bfb1..ab5a6a09 100644
--- a/Boka/Package.swift
+++ b/Boka/Package.swift
@@ -14,6 +14,7 @@ let package = Package(
.package(url: "https://github.com/slashmo/swift-otel.git", from: "0.9.0"),
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.6.0"),
.package(url: "https://github.com/vapor/console-kit.git", from: "4.15.0"),
+ .package(url: "https://github.com/apple/swift-testing.git", branch: "0.10.0"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
@@ -27,11 +28,15 @@ let package = Package(
.product(name: "OTel", package: "swift-otel"),
.product(name: "OTLPGRPC", package: "swift-otel"),
.product(name: "ConsoleKit", package: "console-kit"),
- ]
+ ],
+ resources: [.copy("../chainfiles")]
),
.testTarget(
name: "BokaTests",
- dependencies: ["Boka"]
+ dependencies: [
+ "Boka",
+ .product(name: "Testing", package: "swift-testing"),
+ ]
),
],
swiftLanguageModes: [.version("6")]
diff --git a/Boka/Tests/BokaTests/BokaTests.swift b/Boka/Tests/BokaTests/BokaTests.swift
index a12110e2..d2894879 100644
--- a/Boka/Tests/BokaTests/BokaTests.swift
+++ b/Boka/Tests/BokaTests/BokaTests.swift
@@ -1,13 +1,36 @@
-import XCTest
+import ConsoleKit
+import Foundation
+import Testing
@testable import Boka
-final class BokaTests: XCTestCase {
- func testExample() throws {
- // XCTest Documentation
- // https://developer.apple.com/documentation/xctest
+enum ResourceLoader {
+ static func loadResource(named name: String) -> URL? {
+ let bundle = Bundle.module
+ return bundle.url(forResource: name, withExtension: nil, subdirectory: "chainfiles")
+ }
+}
+
+final class BokaTests {
+ var console: Terminal
+ var boka: Boka
+ init() {
+ console = Terminal()
+ boka = Boka()
+ }
+
+ @Test func commandWithAllConfig() async throws {
+ let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
+ print("path = \(sepc)")
+ let input = CommandInput(arguments: ["Boka", "-f", sepc])
+ try await console.run(boka, input: input)
+ }
- // Defining Test Cases and Test Methods
- // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
+ @Test func commandWithWrongFilePath() async throws {
+ let sepc = "/path/to/wrong/file.json"
+ let input = CommandInput(arguments: ["Boka", "--config-file", sepc])
+ await #expect(throws: Error.self) {
+ try await console.run(boka, input: input)
+ }
}
}
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json b/Boka/chainfiles/devnet_allconfig_spec.json
similarity index 100%
rename from Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
rename to Boka/chainfiles/devnet_allconfig_spec.json
diff --git a/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json b/Boka/chainfiles/devnet_noconfig_spec.json
similarity index 100%
rename from Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
rename to Boka/chainfiles/devnet_noconfig_spec.json
diff --git a/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json b/Boka/chainfiles/mainnet_someconfig_spec.json
similarity index 100%
rename from Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
rename to Boka/chainfiles/mainnet_someconfig_spec.json
From 5c35b22058689b9aa8819382aca7a554d8178084 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 18:58:47 +0800
Subject: [PATCH 18/22] update cmommand
---
Boka/Sources/Boka.swift | 2 +-
Boka/Tests/BokaTests/BokaTests.swift | 9 +++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index 8b322b89..3f37d30c 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -104,7 +104,6 @@ struct Boka: AsyncCommand {
}
let (rpcAddress, rpcPort) = try Regexs.parseAddress(rpcListenAddress)
- let services = try await Tracing.bootstrap("Boka", loggerOnly: true)
let config = Node.Config(rpc: RPCConfig(listenAddress: rpcAddress, port: rpcPort))
let eventBus = EventBus(
eventMiddleware: .serial(
@@ -122,6 +121,7 @@ struct Boka: AsyncCommand {
let node: ValidatorNode = try await ValidatorNode(
genesis: genesis, config: config, eventBus: eventBus, keystore: keystore
)
+ let services = try await Tracing.bootstrap("Boka", loggerOnly: true)
for service in services {
Task {
try await service.run()
diff --git a/Boka/Tests/BokaTests/BokaTests.swift b/Boka/Tests/BokaTests/BokaTests.swift
index d2894879..daa366f6 100644
--- a/Boka/Tests/BokaTests/BokaTests.swift
+++ b/Boka/Tests/BokaTests/BokaTests.swift
@@ -19,6 +19,15 @@ final class BokaTests {
boka = Boka()
}
+ @Test func missCommand() async throws {
+ let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
+ print("path = \(sepc)")
+ let input = CommandInput(arguments: ["Boka", "-m", sepc])
+ await #expect(throws: Error.self) {
+ try await console.run(boka, input: input)
+ }
+ }
+
@Test func commandWithAllConfig() async throws {
let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
print("path = \(sepc)")
From 76213edd75b67e5565b4976002d745532ad94c6d Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Tue, 15 Oct 2024 19:51:00 +0800
Subject: [PATCH 19/22] update boka test
---
Boka/Tests/BokaTests/BokaTests.swift | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/Boka/Tests/BokaTests/BokaTests.swift b/Boka/Tests/BokaTests/BokaTests.swift
index daa366f6..c322144e 100644
--- a/Boka/Tests/BokaTests/BokaTests.swift
+++ b/Boka/Tests/BokaTests/BokaTests.swift
@@ -1,5 +1,7 @@
+import Blockchain
import ConsoleKit
import Foundation
+import Node
import Testing
@testable import Boka
@@ -30,9 +32,28 @@ final class BokaTests {
@Test func commandWithAllConfig() async throws {
let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
- print("path = \(sepc)")
- let input = CommandInput(arguments: ["Boka", "-f", sepc])
- try await console.run(boka, input: input)
+ let genesis: Genesis = .file(path: sepc)
+ let (_, protocolConfig) = try await genesis.load()
+ #expect(protocolConfig.value.maxWorkItems == 2)
+ #expect(protocolConfig.value.serviceMinBalance == 100)
+ }
+
+ @Test func commandWithSomeConfig() async throws {
+ let sepc = ResourceLoader.loadResource(named: "mainnet_someconfig_spec.json")!.path()
+ let genesis: Genesis = .file(path: sepc)
+ let config = ProtocolConfigRef.mainnet.value
+ let (_, protocolConfig) = try await genesis.load()
+ #expect(protocolConfig.value.auditTranchePeriod == 100)
+ #expect(protocolConfig.value.pvmProgramInitSegmentSize == config.pvmProgramInitSegmentSize)
+ }
+
+ @Test func commandWithNoConfig() async throws {
+ let sepc = ResourceLoader.loadResource(named: "devnet_noconfig_spec.json")!.path()
+ let genesis: Genesis = .file(path: sepc)
+ let config = ProtocolConfigRef.dev.value
+ let (_, protocolConfig) = try await genesis.load()
+ #expect(protocolConfig.value.maxWorkItems == config.maxWorkItems)
+ #expect(protocolConfig.value.serviceMinBalance == config.serviceMinBalance)
}
@Test func commandWithWrongFilePath() async throws {
From daedccdafb5472b9f6e050f9fe8eca9e53048292 Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Wed, 16 Oct 2024 06:46:05 +0800
Subject: [PATCH 20/22] Update Boka/Tests/BokaTests/BokaTests.swift
Co-authored-by: Xiliang Chen
---
Boka/Tests/BokaTests/BokaTests.swift | 1 -
1 file changed, 1 deletion(-)
diff --git a/Boka/Tests/BokaTests/BokaTests.swift b/Boka/Tests/BokaTests/BokaTests.swift
index c322144e..9ebe39ea 100644
--- a/Boka/Tests/BokaTests/BokaTests.swift
+++ b/Boka/Tests/BokaTests/BokaTests.swift
@@ -23,7 +23,6 @@ final class BokaTests {
@Test func missCommand() async throws {
let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
- print("path = \(sepc)")
let input = CommandInput(arguments: ["Boka", "-m", sepc])
await #expect(throws: Error.self) {
try await console.run(boka, input: input)
From 1be30197d71ae7c64aedfe4678a452b3a81da66c Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Wed, 16 Oct 2024 07:07:58 +0800
Subject: [PATCH 21/22] update resources
---
Boka/Package.swift | 6 ++++--
.../BokaTests}/chainfiles/devnet_allconfig_spec.json | 0
.../BokaTests}/chainfiles/devnet_noconfig_spec.json | 0
.../BokaTests}/chainfiles/mainnet_someconfig_spec.json | 0
4 files changed, 4 insertions(+), 2 deletions(-)
rename Boka/{ => Tests/BokaTests}/chainfiles/devnet_allconfig_spec.json (100%)
rename Boka/{ => Tests/BokaTests}/chainfiles/devnet_noconfig_spec.json (100%)
rename Boka/{ => Tests/BokaTests}/chainfiles/mainnet_someconfig_spec.json (100%)
diff --git a/Boka/Package.swift b/Boka/Package.swift
index ab5a6a09..fb81a5b1 100644
--- a/Boka/Package.swift
+++ b/Boka/Package.swift
@@ -28,14 +28,16 @@ let package = Package(
.product(name: "OTel", package: "swift-otel"),
.product(name: "OTLPGRPC", package: "swift-otel"),
.product(name: "ConsoleKit", package: "console-kit"),
- ],
- resources: [.copy("../chainfiles")]
+ ]
),
.testTarget(
name: "BokaTests",
dependencies: [
"Boka",
.product(name: "Testing", package: "swift-testing"),
+ ],
+ resources: [
+ .copy("chainfiles"),
]
),
],
diff --git a/Boka/chainfiles/devnet_allconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
similarity index 100%
rename from Boka/chainfiles/devnet_allconfig_spec.json
rename to Boka/Tests/BokaTests/chainfiles/devnet_allconfig_spec.json
diff --git a/Boka/chainfiles/devnet_noconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
similarity index 100%
rename from Boka/chainfiles/devnet_noconfig_spec.json
rename to Boka/Tests/BokaTests/chainfiles/devnet_noconfig_spec.json
diff --git a/Boka/chainfiles/mainnet_someconfig_spec.json b/Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
similarity index 100%
rename from Boka/chainfiles/mainnet_someconfig_spec.json
rename to Boka/Tests/BokaTests/chainfiles/mainnet_someconfig_spec.json
From 9d8cb01f32bc906997e4c68373c2e4c9640e946a Mon Sep 17 00:00:00 2001
From: MacOMNI <414294494@qq.com>
Date: Wed, 16 Oct 2024 07:17:31 +0800
Subject: [PATCH 22/22] udpate cli & test
---
Boka/Sources/Boka.swift | 2 +-
Boka/Tests/BokaTests/BokaTests.swift | 16 ++++++++--------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/Boka/Sources/Boka.swift b/Boka/Sources/Boka.swift
index 3f37d30c..d3537532 100644
--- a/Boka/Sources/Boka.swift
+++ b/Boka/Sources/Boka.swift
@@ -59,7 +59,7 @@ struct Boka: AsyncCommand {
context.console.info(help)
return
}
-
+ // TODO: fix version number issue #168
if signature.version {
context.console.info("Boka version 1.0.0")
return
diff --git a/Boka/Tests/BokaTests/BokaTests.swift b/Boka/Tests/BokaTests/BokaTests.swift
index 9ebe39ea..a70ca1c4 100644
--- a/Boka/Tests/BokaTests/BokaTests.swift
+++ b/Boka/Tests/BokaTests/BokaTests.swift
@@ -29,6 +29,14 @@ final class BokaTests {
}
}
+ @Test func commandWithWrongFilePath() async throws {
+ let sepc = "/path/to/wrong/file.json"
+ let input = CommandInput(arguments: ["Boka", "--config-file", sepc])
+ await #expect(throws: Error.self) {
+ try await console.run(boka, input: input)
+ }
+ }
+
@Test func commandWithAllConfig() async throws {
let sepc = ResourceLoader.loadResource(named: "devnet_allconfig_spec.json")!.path()
let genesis: Genesis = .file(path: sepc)
@@ -54,12 +62,4 @@ final class BokaTests {
#expect(protocolConfig.value.maxWorkItems == config.maxWorkItems)
#expect(protocolConfig.value.serviceMinBalance == config.serviceMinBalance)
}
-
- @Test func commandWithWrongFilePath() async throws {
- let sepc = "/path/to/wrong/file.json"
- let input = CommandInput(arguments: ["Boka", "--config-file", sepc])
- await #expect(throws: Error.self) {
- try await console.run(boka, input: input)
- }
- }
}