Skip to content

Commit

Permalink
boka command line (#159)
Browse files Browse the repository at this point in the history
* change  preimage size to data count

* update

* update ignore

* update

* no message

* update Cli

* update cli

* update regex

* update regexs

* update regexs

* update test

* update regexs

* udpate regex

* revert submodule change
  • Loading branch information
MacOMNI authored Oct 11, 2024
1 parent 02dc8c1 commit cb748af
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 3 deletions.
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@
"name": "Release Boka (Boka)",
"program": "${workspaceFolder:boka}/Boka/.build/release/Boka",
"preLaunchTask": "swift: Build Release Boka (Boka)"
},
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:boka}/Cli",
"name": "Debug Cli (Cli)",
"program": "${workspaceFolder:boka}/Cli/.build/debug/Cli",
"preLaunchTask": "swift: Build Debug Cli (Cli)"
},
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:boka}/Cli",
"name": "Release Cli (Cli)",
"program": "${workspaceFolder:boka}/Cli/.build/release/Cli",
"preLaunchTask": "swift: Build Release Cli (Cli)"
}
]
}
88 changes: 85 additions & 3 deletions Boka/Sources/Boka.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,100 @@

import ArgumentParser
import Blockchain
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"
)

@Option(name: [.customShort("d"), .long], help: "Base path to database files.")
var basePath: String?

@Option(name: [.customShort("c"), .long], help: "Path to chain spec file.")
var chain: String?

@Option(name: [.customShort("f"), .long], help: "Path to config file.")
var configFile: 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: [.customLong("p2p"), .long], help: "Listen address for P2P protocol.")
var p2pListenAddress: String?

@Option(name: [.customLong("peers"), .long], parsing: .upToNextOption, help: "Specify peer P2P addresses.")
var p2pPeers: [String] = []

@Flag(name: .long, help: "Run as a validator.")
var validator: Bool = false

@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: .long, help: "For development only. Seed for validator keys.")
var devSeed: String?

mutating func run() async throws {
let services = try await Tracing.bootstrap("Boka", loggerOnly: true)
let logger = Logger(label: "boka")

if let basePath {
logger.info("Base Path: \(basePath)")
}
if let chain {
logger.info("Chain: \(chain)")
}
if let configFile {
logger.info("Config File: \(configFile)")
}

logger.info("RPC Listen Address: \(rpcListenAddress)")

if let p2pListenAddress {
logger.info("P2P Listen Address: \(p2pListenAddress)")
}
if rpcListenAddress.lowercased() == "false" {
logger.warning("TODO: RPC server is disabled")
rpcListenAddress = "127.0.0.1:9955"
}
let (rpcAddress, rpcPort) = try Regexs.parseAddress(rpcListenAddress)

if !p2pPeers.isEmpty {
logger.info("P2P Peers: \(p2pPeers.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 let devSeed {
logger.info("Dev Seed: \(devSeed)")
}

let services = try await Tracing.bootstrap("Boka", loggerOnly: true)

logger.info("Starting Boka...")

let config = Node.Config(rpc: RPCConfig(listenAddress: "127.0.0.1", port: 9955))
let config = Node.Config(
rpc: RPCConfig(listenAddress: rpcAddress, port: rpcPort)
)
let eventBus = EventBus(
eventMiddleware: .serial(
.log(logger: Logger(label: "EventBus")),
Expand All @@ -29,7 +109,9 @@ struct Boka: AsyncParsableCommand {
)
do {
let keystore = try await DevKeyStore()
let node = try await ValidatorNode(genesis: .dev, config: config, eventBus: eventBus, keystore: keystore)
let node = try await ValidatorNode(
genesis: .dev, config: config, eventBus: eventBus, keystore: keystore
)

for service in services {
Task {
Expand Down
66 changes: 66 additions & 0 deletions Utils/Sources/Utils/Regexs.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Foundation

public enum RegexsError: Error {
case invalidFormat
case invalidPort
}

public enum Regexs {
// Combined regex pattern for IP address with port
public static func parseAddress(_ address: String) throws -> (ip: String, port: Int) {
let ipv4Pattern: String = [
"(?:",
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
"\\.",
"){3}",
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
].reduce("", +)

let ipv6Pattern = [
"(?:",
"(?:(?:[0-9A-Fa-f]{1,4}:){6}",
"|::(?:[0-9A-Fa-f]{1,4}:){5}",
"|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)",
"(?:",
"[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}",
"|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}",
"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
")",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}",
"|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::",
")",
].reduce("", +)
let ipAddressWithPortPattern = #"(?:(\#(ipv4Pattern))|\[(\#(ipv6Pattern))\]):(\d{1,5})"#

let regex = try NSRegularExpression(pattern: ipAddressWithPortPattern, options: [])
let range = NSRange(location: 0, length: address.utf16.count)

if let match = regex.firstMatch(in: address, options: [], range: range) {
let ipRange: Range<String.Index>
if let ipv4Range = Range(match.range(at: 1), in: address) {
ipRange = ipv4Range
} else if let ipv6Range = Range(match.range(at: 2), in: address) {
ipRange = ipv6Range
} else {
throw RegexsError.invalidFormat
}

let portRange = Range(match.range(at: 3), in: address)!

let ip = String(address[ipRange])
let portString = String(address[portRange])

if let port = Int(portString), (0 ... 65535).contains(port) {
return (ip, port)
} else {
throw RegexsError.invalidPort
}
} else {
throw RegexsError.invalidFormat
}
}
}
30 changes: 30 additions & 0 deletions Utils/Tests/UtilsTests/RegexsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation
import Testing

@testable import Utils

struct RegexsTests {
@Test func parseAddress() throws {
// Correct IPv4 address
#expect(try Regexs.parseAddress("127.0.0.1:9955") == ("127.0.0.1", 9955))

// Correct IPv6 addresses
#expect(try Regexs
.parseAddress("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8080") == ("2001:0db8:85a3:0000:0000:8a2e:0370:7334", 8080))
#expect(try Regexs.parseAddress("[2001:db8:85a3::8a2e:370:7334]:8080") == ("2001:db8:85a3::8a2e:370:7334", 8080))
#expect(try Regexs.parseAddress("[::1]:8080") == ("::1", 8080))

// // Exception case: Missing port
#expect(throws: RegexsError.invalidFormat) { try Regexs.parseAddress("127.0.0.1") }
#expect(throws: RegexsError.invalidFormat) { try Regexs.parseAddress("abcd:::") }
// Exception case: Invalid port
#expect(throws: RegexsError.invalidPort) { try Regexs.parseAddress("127.0.0.1:75535") }
#expect(throws: RegexsError.invalidPort) { try Regexs.parseAddress("[2001:db8::1]:75535") }

// Exception case: Invalid IPv4 format
#expect(throws: RegexsError.invalidFormat) { try Regexs.parseAddress("256.256.256.256:8080") }

// Exception case: Invalid IPv6 format
#expect(throws: RegexsError.invalidFormat) { try Regexs.parseAddress("[2001:db8:::1]:8080") }
}
}

0 comments on commit cb748af

Please sign in to comment.