Skip to content

Commit a0faade

Browse files
MacOMNIxlc
andauthored
update RPC ChainHandler (#268)
* add more rpc test * update getBlock * update chainHandle tests * update chainhandles * update datasource * update chainHandlers * update chainhandler test * update swiftlint * update system handlers * update TelemetryHandlers tests * update statehandler * update swiftlint * update NodeDataSource * update node test * update tests * update chainhandler * Update RPC/Sources/RPC/Handlers/ChainHandlers.swift Co-authored-by: Xiliang Chen <xlchen1291@gmail.com> * update chainhandler --------- Co-authored-by: Xiliang Chen <xlchen1291@gmail.com>
1 parent 0dba01d commit a0faade

22 files changed

+570
-69
lines changed

Blockchain/Sources/Blockchain/BlockchainDataProvider/BlockchainDataProvider.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ extension BlockchainDataProvider {
9898
try await dataProvider.getBlockHash(byNumber: number)
9999
}
100100

101+
public func getFinalizedHead() async throws -> Data32? {
102+
try await dataProvider.getFinalizedHead()
103+
}
104+
105+
public func getKeys(prefix: Data32, count: UInt32, startKey: Data32?, blockHash: Data32?) async throws -> [String] {
106+
try await dataProvider.getKeys(prefix: prefix, count: count, startKey: startKey, blockHash: blockHash)
107+
}
108+
109+
public func getStorage(key: Data32, blockHash: Data32?) async throws -> [String] {
110+
try await dataProvider.getStorage(key: key, blockHash: blockHash)
111+
}
112+
101113
// add forks of finalized head is not allowed
102114
public func add(block: BlockRef) async throws {
103115
logger.debug("adding block: \(block.hash)")

Blockchain/Sources/Blockchain/BlockchainDataProvider/BlockchainDataProviderProtocol.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ public protocol BlockchainDataProviderProtocol: Sendable {
1414
func getState(hash: Data32) async throws -> StateRef?
1515

1616
func getFinalizedHead() async throws -> Data32?
17+
1718
func getHeads() async throws -> Set<Data32>
1819

20+
func getKeys(prefix: Data32, count: UInt32, startKey: Data32?, blockHash: Data32?) async throws -> [String]
21+
22+
func getStorage(key: Data32, blockHash: Data32?) async throws -> [String]
23+
1924
/// return empty set if not found
2025
func getBlockHash(byTimeslot timeslot: TimeslotIndex) async throws -> Set<Data32>
2126
/// return empty set if not found

Blockchain/Sources/Blockchain/BlockchainDataProvider/InMemoryDataProvider.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ public actor InMemoryDataProvider {
2222
}
2323

2424
extension InMemoryDataProvider: BlockchainDataProviderProtocol {
25+
public func getKeys(prefix: Data32, count: UInt32, startKey: Data32?, blockHash: Data32?) async throws -> [String] {
26+
guard let stateRef = try getState(hash: blockHash ?? genesisBlockHash) else {
27+
return []
28+
}
29+
30+
return try await stateRef.value.backend.getKeys(prefix, startKey, count).map { $0.key.toHexString() }
31+
}
32+
33+
public func getStorage(key: Data32, blockHash: Data32?) async throws -> [String] {
34+
guard let stateRef = try getState(hash: blockHash ?? genesisBlockHash) else {
35+
return []
36+
}
37+
38+
guard let value = try await stateRef.value.backend.readRaw(key) else {
39+
throw StateBackendError.missingState(key: key)
40+
}
41+
return [value.toHexString()]
42+
}
43+
2544
public func hasBlock(hash: Data32) -> Bool {
2645
blockByHash[hash] != nil
2746
}

Blockchain/Sources/Blockchain/Config/ProtocolConfig+Preset.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import Utils
22

3+
extension ProtocolConfig {
4+
private static let presetMapping: [String: ProtocolConfig] = [
5+
"minimal": ProtocolConfigRef.minimal.value,
6+
"dev": ProtocolConfigRef.dev.value,
7+
"tiny": ProtocolConfigRef.tiny.value,
8+
"mainnet": ProtocolConfigRef.mainnet.value,
9+
]
10+
11+
public func presetName() -> String? {
12+
ProtocolConfig.presetMapping.first(where: { $0.value == self })?.key
13+
}
14+
}
15+
316
extension Ref where T == ProtocolConfig {
417
// TODO: pick some good numbers for dev env
518
public static let minimal = Ref(ProtocolConfig(

Blockchain/Sources/Blockchain/State/StateBackend.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public final class StateBackend: Sendable {
3838
throw StateBackendError.missingState(key: key)
3939
}
4040

41+
public func getKeys(_ prefix: Data32, _ startKey: Data32?, _ limit: UInt32?) async throws -> [(key: Data, value: Data)] {
42+
try await impl.readAll(prefix: prefix.data, startKey: startKey?.data, limit: limit)
43+
}
44+
4145
public func batchRead(_ keys: [any StateKey]) async throws -> [(key: any StateKey, value: (Codable & Sendable)?)] {
4246
var ret = [(key: any StateKey, value: (Codable & Sendable)?)]()
4347
ret.reserveCapacity(keys.count)

Database/Sources/Database/RocksDBBackend.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,31 @@ public final class RocksDBBackend: Sendable {
7272
}
7373

7474
extension RocksDBBackend: BlockchainDataProviderProtocol {
75+
public func getKeys(prefix: Data32, count: UInt32, startKey: Data32?, blockHash: Data32?) async throws -> [String] {
76+
logger.trace("""
77+
getKeys() prefix: \(prefix), count: \(count),
78+
startKey: \(String(describing: startKey)), blockHash: \(String(describing: blockHash))
79+
""")
80+
81+
guard let stateRef = try await getState(hash: blockHash ?? genesisBlockHash) else {
82+
return []
83+
}
84+
return try await stateRef.value.backend.getKeys(prefix, startKey, count).map { $0.key.toHexString() }
85+
}
86+
87+
public func getStorage(key: Data32, blockHash: Data32?) async throws -> [String] {
88+
logger.trace("getStorage() key: \(key), blockHash: \(String(describing: blockHash))")
89+
90+
guard let stateRef = try await getState(hash: blockHash ?? genesisBlockHash) else {
91+
return []
92+
}
93+
94+
guard let value = try await stateRef.value.backend.readRaw(key) else {
95+
throw StateBackendError.missingState(key: key)
96+
}
97+
return [value.toHexString()]
98+
}
99+
75100
public func hasBlock(hash: Data32) async throws -> Bool {
76101
try blocks.exists(key: hash)
77102
}

Node/Sources/Node/NetworkingProtocol/Network.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ public final class Network: Sendable {
9292
public var peersCount: Int {
9393
peer.peersCount
9494
}
95+
96+
public var networkKey: String {
97+
peer.publicKey.description
98+
}
9599
}
96100

97101
struct HandlerDef: StreamHandler {

Node/Sources/Node/NodeDataSource.swift

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,46 @@ public final class NodeDataSource: Sendable {
2222
}
2323
}
2424

25-
extension NodeDataSource: SystemDataSource {}
25+
extension NodeDataSource: SystemDataSource {
26+
public func getProperties() async throws -> JSON {
27+
// TODO: Get a custom set of properties as a JSON object, defined in the chain spec
28+
JSON.array([])
29+
}
30+
31+
public func getChainName() async throws -> String {
32+
blockchain.config.value.presetName() ?? ""
33+
}
34+
35+
public func getNodeRoles() async throws -> [String] {
36+
// TODO: Returns the roles the node is running as.
37+
[]
38+
}
39+
40+
public func getVersion() async throws -> String {
41+
// TODO: From spec or config
42+
"0.0.1"
43+
}
44+
45+
public func getHealth() async throws -> Bool {
46+
// TODO: Check health status
47+
true
48+
}
49+
50+
public func getImplementation() async throws -> String {
51+
name
52+
}
53+
}
2654

2755
extension NodeDataSource: ChainDataSource {
56+
public func getKeys(prefix: Data32, count: UInt32, startKey: Data32?, blockHash: Data32?) async throws -> [String] {
57+
// TODO:
58+
try await chainDataProvider.getKeys(prefix: prefix, count: count, startKey: startKey, blockHash: blockHash)
59+
}
60+
61+
public func getStorage(key: Data32, blockHash: Utils.Data32?) async throws -> [String] {
62+
try await chainDataProvider.getStorage(key: key, blockHash: blockHash)
63+
}
64+
2865
public func getBestBlock() async throws -> BlockRef {
2966
try await chainDataProvider.getBlock(hash: chainDataProvider.bestHead.hash)
3067
}
@@ -37,6 +74,18 @@ extension NodeDataSource: ChainDataSource {
3774
let state = try await chainDataProvider.getState(hash: blockHash)
3875
return try await state.value.read(key: key)
3976
}
77+
78+
public func getBlockHash(byTimeslot timeslot: TimeslotIndex) async throws -> Set<Data32> {
79+
try await chainDataProvider.getBlockHash(byTimeslot: timeslot)
80+
}
81+
82+
public func getHeader(hash: Data32) async throws -> HeaderRef? {
83+
try await chainDataProvider.getHeader(hash: hash)
84+
}
85+
86+
public func getFinalizedHead() async throws -> Data32? {
87+
try await chainDataProvider.getFinalizedHead()
88+
}
4089
}
4190

4291
extension NodeDataSource: TelemetryDataSource {
@@ -47,4 +96,8 @@ extension NodeDataSource: TelemetryDataSource {
4796
public func getPeersCount() async throws -> Int {
4897
networkManager.peersCount
4998
}
99+
100+
public func getNetworkKey() async throws -> String {
101+
networkManager.network.networkKey
102+
}
50103
}

Node/Tests/NodeTests/NodeTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Blockchain
2+
import Database
23
import Foundation
34
import Testing
45
import Utils
@@ -79,6 +80,10 @@ final class NodeTests {
7980
// Verify block was produced
8081
#expect(newTimeslot > initialTimeslot)
8182
#expect(try await validatorNode.blockchain.dataProvider.hasBlock(hash: newBestHead.hash))
83+
#expect(try await validatorNode.blockchain.dataProvider.getKeys(prefix: Data32(), count: 0, startKey: nil, blockHash: nil).isEmpty)
84+
await #expect(throws: StateBackendError.self) {
85+
_ = try await validatorNode.blockchain.dataProvider.getStorage(key: Data32.random(), blockHash: nil)
86+
}
8287
}
8388

8489
@Test func sync() async throws {

Node/Tests/NodeTests/Topology.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ struct Topology {
2525
}
2626

2727
func build(genesis: Genesis) async throws -> ([(Node, StoreMiddleware)], MockScheduler) {
28-
// setupTestLogger()
29-
3028
let timeProvider = MockTimeProvider(time: 1000)
3129
let scheduler = MockScheduler(timeProvider: timeProvider)
3230
var ret: [(Node, StoreMiddleware)] = []

0 commit comments

Comments
 (0)