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) - } - } }