Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rpc refactor #235

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@
"name": "Release Cli (Cli)",
"program": "${workspaceFolder:boka}/Cli/.build/release/Cli",
"preLaunchTask": "swift: Build Release Cli (Cli)"
},
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:boka}/Tools",
"name": "Debug Tools (Tools)",
"program": "${workspaceFolder:boka}/Tools/.build/debug/Tools",
"preLaunchTask": "swift: Build Debug Tools (Tools)"
},
{
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:boka}/Tools",
"name": "Release Tools (Tools)",
"program": "${workspaceFolder:boka}/Tools/.build/release/Tools",
"preLaunchTask": "swift: Build Release Tools (Tools)"
}
]
}
}
14 changes: 14 additions & 0 deletions RPC/Sources/RPC/Handlers/AllHandlers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
public enum AllHandlers {
public static let handlers: [any RPCHandler.Type] =
ChainHandlers.handlers +
SystemHandlers.handlers +
TelemetryHandlers.handlers +
RPCHandlers.handlers

public static func getHandlers(source: ChainDataSource & SystemDataSource & TelemetryDataSource) -> [any RPCHandler] {
ChainHandlers.getHandlers(source: source) +
SystemHandlers.getHandlers(source: source) +
TelemetryHandlers.getHandlers(source: source) +
RPCHandlers.getHandlers(source: handlers)
}

Check warning on line 13 in RPC/Sources/RPC/Handlers/AllHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/AllHandlers.swift#L8-L13

Added lines #L8 - L13 were not covered by tests
}
23 changes: 15 additions & 8 deletions RPC/Sources/RPC/Handlers/ChainHandlers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,33 @@
import Foundation
import Utils

enum ChainHandlers {
static func getHandlers(source: ChainDataSource) -> [any RPCHandler] {
public enum ChainHandlers {
public static let handlers: [any RPCHandler.Type] = [
GetBlock.self,
]

public static func getHandlers(source: ChainDataSource) -> [any RPCHandler] {

Check warning on line 10 in RPC/Sources/RPC/Handlers/ChainHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/ChainHandlers.swift#L10

Added line #L10 was not covered by tests
[
GetBlock(source: source),
]
}

struct GetBlock: RPCHandler {
var method: String { "chain_getBlock" }
typealias Request = Data32?
typealias Response = BlockRef?
public struct GetBlock: RPCHandler {
public typealias Request = Request1<Data32?>
public typealias Response = BlockRef?
public typealias DataSource = ChainDataSource

public static var method: String { "chain_getBlock" }
public static var summary: String? { "Get block by hash. If hash is not provided, returns the best block." }

Check warning on line 22 in RPC/Sources/RPC/Handlers/ChainHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/ChainHandlers.swift#L21-L22

Added lines #L21 - L22 were not covered by tests

private let source: ChainDataSource

init(source: ChainDataSource) {
self.source = source
}

func handle(request: Request) async throws -> Response? {
if let hash = request {
public func handle(request: Request) async throws -> Response? {
if let hash = request.value {

Check warning on line 31 in RPC/Sources/RPC/Handlers/ChainHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/ChainHandlers.swift#L30-L31

Added lines #L30 - L31 were not covered by tests
try await source.getBlock(hash: hash)
} else {
try await source.getBestBlock()
Expand Down
29 changes: 17 additions & 12 deletions RPC/Sources/RPC/Handlers/RPCHandlers.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import Utils

enum RPCHandlers {
static func getHandlers(source: [any RPCHandler]) -> [any RPCHandler] {
[
Methods(source: source),
]
public enum RPCHandlers {
public static let handlers: [any RPCHandler.Type] = [
Methods.self,
]

public static func getHandlers(source: [any RPCHandler.Type]) -> [any RPCHandler] {
[Methods(source: source)]

Check warning on line 9 in RPC/Sources/RPC/Handlers/RPCHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/RPCHandlers.swift#L8-L9

Added lines #L8 - L9 were not covered by tests
}

struct Methods: RPCHandler {
var method: String { "rpc_methods" }
typealias Request = VoidRequest
typealias Response = [String]
public struct Methods: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = [String]
public typealias DataSource = [any RPCHandler.Type]

public static var method: String { "rpc_methods" }
public static var summary: String? { "Returns a list of available RPC methods." }

Check warning on line 18 in RPC/Sources/RPC/Handlers/RPCHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/RPCHandlers.swift#L17-L18

Added lines #L17 - L18 were not covered by tests

private let methods: [String]

init(source: [any RPCHandler]) {
methods = source.map(\.method)
init(source: [any RPCHandler.Type]) {
methods = source.map { h in h.method }

Check warning on line 23 in RPC/Sources/RPC/Handlers/RPCHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/RPCHandlers.swift#L22-L23

Added lines #L22 - L23 were not covered by tests
}

func handle(request _: Request) async throws -> Response? {
public func handle(request _: Request) async throws -> Response? {

Check warning on line 26 in RPC/Sources/RPC/Handlers/RPCHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/RPCHandlers.swift#L26

Added line #L26 was not covered by tests
methods
}
}
Expand Down
45 changes: 33 additions & 12 deletions RPC/Sources/RPC/Handlers/SystemHandlers.swift
Original file line number Diff line number Diff line change
@@ -1,29 +1,50 @@
import Utils

enum SystemHandlers {
static func getHandlers(source _: SystemDataSource) -> [any RPCHandler] {
public enum SystemHandlers {
public static let handlers: [any RPCHandler.Type] = [
Health.self,
Version.self,
]

public static func getHandlers(source _: SystemDataSource) -> [any RPCHandler] {
[
Health(),
Version(),
]
}

struct Health: RPCHandler {
var method: String { "system_health" }
typealias Request = VoidRequest
typealias Response = Bool
public struct Health: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = Bool

public static var method: String { "system_health" }
public static var summary: String? { "Returns true if the node is healthy." }

Check warning on line 21 in RPC/Sources/RPC/Handlers/SystemHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/SystemHandlers.swift#L21

Added line #L21 was not covered by tests

func handle(request _: Request) async throws -> Response? {
public func handle(request _: Request) async throws -> Response? {
true
}
}

struct Version: RPCHandler {
var method: String { "system_version" }
typealias Request = VoidRequest
typealias Response = String
public struct Implementation: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = String

public static var method: String { "system_implementation" }
public static var summary: String? { "Returns the implementation name of the node." }

Check warning on line 33 in RPC/Sources/RPC/Handlers/SystemHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/SystemHandlers.swift#L32-L33

Added lines #L32 - L33 were not covered by tests

public func handle(request _: Request) async throws -> Response? {
"Boka"
}

Check warning on line 37 in RPC/Sources/RPC/Handlers/SystemHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/SystemHandlers.swift#L35-L37

Added lines #L35 - L37 were not covered by tests
}

public struct Version: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = String

public static var method: String { "system_version" }
public static var summary: String? { "Returns the version of the node." }

Check warning on line 45 in RPC/Sources/RPC/Handlers/SystemHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/SystemHandlers.swift#L45

Added line #L45 was not covered by tests

func handle(request _: Request) async throws -> Response? {
public func handle(request _: Request) async throws -> Response? {

Check warning on line 47 in RPC/Sources/RPC/Handlers/SystemHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/SystemHandlers.swift#L47

Added line #L47 was not covered by tests
"0.0.1"
}
}
Expand Down
36 changes: 22 additions & 14 deletions RPC/Sources/RPC/Handlers/TelemetryHandlers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,57 @@
import Foundation
import Utils

enum TelemetryHandlers {
static func getHandlers(source: TelemetryDataSource & ChainDataSource) -> [any RPCHandler] {
public enum TelemetryHandlers {
public static let handlers: [any RPCHandler.Type] = [
GetUpdate.self,
Name.self,
]

public static func getHandlers(source: TelemetryDataSource & ChainDataSource) -> [any RPCHandler] {

Check warning on line 11 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L11

Added line #L11 was not covered by tests
[
GetUpdate(source: source),
Name(source: source),
]
}

struct GetUpdate: RPCHandler {
var method: String { "telemetry_getUpdate" }
typealias Request = VoidRequest
typealias Response = [String: String]
public struct GetUpdate: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = [String: String]

public static var method: String { "telemetry_getUpdate" }
public static var summary: String? { "Returns the latest telemetry update." }

Check warning on line 23 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L22-L23

Added lines #L22 - L23 were not covered by tests

private let source: TelemetryDataSource & ChainDataSource

init(source: TelemetryDataSource & ChainDataSource) {
self.source = source
}

func handle(request _: Request) async throws -> Response? {
public func handle(request _: Request) async throws -> Response? {

Check warning on line 31 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L31

Added line #L31 was not covered by tests
let block = try await source.getBestBlock()
let peerCount = try await source.getPeersCount()
return try await [
"name": source.name(),
return [

Check warning on line 34 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L34

Added line #L34 was not covered by tests
"chainHead": block.header.timeslot.description,
"blockHash": block.hash.description,
"peerCount": peerCount.description,
]
}
}

struct Name: RPCHandler {
var method: String { "telemetry_name" }
typealias Request = VoidRequest
typealias Response = String
public struct Name: RPCHandler {
public typealias Request = VoidRequest
public typealias Response = String

public static var method: String { "telemetry_name" }
public static var summary: String? { "Returns the name of the node." }

Check warning on line 47 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L46-L47

Added lines #L46 - L47 were not covered by tests

private let source: TelemetryDataSource

init(source: TelemetryDataSource) {
self.source = source
}

func handle(request _: Request) async throws -> Response? {
public func handle(request _: Request) async throws -> Response? {

Check warning on line 55 in RPC/Sources/RPC/Handlers/TelemetryHandlers.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/Handlers/TelemetryHandlers.swift#L55

Added line #L55 was not covered by tests
try await source.name()
}
}
Expand Down
18 changes: 9 additions & 9 deletions RPC/Sources/RPC/JSONRPC/FromJSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
case unexpectedJSON
}

protocol FromJSON {
public protocol FromJSON {
init(from: JSON?) throws
}

enum VoidRequest: FromJSON {
public enum VoidRequest: FromJSON {
case void

init(from _: JSON?) throws {
public init(from _: JSON?) throws {
// ignore
self = .void
}
}

extension Optional: FromJSON where Wrapped: FromJSON {
init(from json: JSON?) throws {
public init(from json: JSON?) throws {

Check warning on line 23 in RPC/Sources/RPC/JSONRPC/FromJSON.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/FromJSON.swift#L23

Added line #L23 was not covered by tests
guard let json else {
self = .none
return
Expand All @@ -35,7 +35,7 @@
}

extension BinaryInteger where Self: FromJSON {
init(from json: JSON?) throws {
public init(from json: JSON?) throws {

Check warning on line 38 in RPC/Sources/RPC/JSONRPC/FromJSON.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/FromJSON.swift#L38

Added line #L38 was not covered by tests
guard let json else {
throw FromJSONError.null
}
Expand All @@ -60,7 +60,7 @@
extension UInt: FromJSON {}

extension Data: FromJSON {
init(from json: JSON?) throws {
public init(from json: JSON?) throws {

Check warning on line 63 in RPC/Sources/RPC/JSONRPC/FromJSON.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/FromJSON.swift#L63

Added line #L63 was not covered by tests
guard let json else {
throw FromJSONError.null
}
Expand All @@ -73,14 +73,14 @@
}
}

extension Data32: FromJSON {
init(from json: JSON?) throws {
extension FixedSizeData: FromJSON {
public init(from json: JSON?) throws {

Check warning on line 77 in RPC/Sources/RPC/JSONRPC/FromJSON.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/FromJSON.swift#L77

Added line #L77 was not covered by tests
guard let json else {
throw FromJSONError.null
}
switch json {
case let .string(str):
self = try Data32(fromHexString: str).unwrap()
self = try FixedSizeData(fromHexString: str).unwrap()

Check warning on line 83 in RPC/Sources/RPC/JSONRPC/FromJSON.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/FromJSON.swift#L83

Added line #L83 was not covered by tests
default:
throw FromJSONError.unexpectedJSON
}
Expand Down
28 changes: 14 additions & 14 deletions RPC/Sources/RPC/JSONRPC/JSONRPC.swift
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
import Utils
import Vapor

struct JSONRequest: Content {
let jsonrpc: String
let method: String
let params: JSON?
let id: JSON
public struct JSONRequest: Content {
public let jsonrpc: String
public let method: String
public let params: JSON?
public let id: JSON
}

struct JSONResponse: Content {
let jsonrpc: String
let result: AnyCodable?
let error: JSONError?
let id: JSON?
public struct JSONResponse: Content {
public let jsonrpc: String
public let result: AnyCodable?
public let error: JSONError?
public let id: JSON?

init(id: JSON?, result: (any Encodable)?) {
public init(id: JSON?, result: (any Encodable)?) {
jsonrpc = "2.0"
self.result = result.map(AnyCodable.init)
error = nil
self.id = id
}

init(id: JSON?, error: JSONError) {
public init(id: JSON?, error: JSONError) {

Check warning on line 24 in RPC/Sources/RPC/JSONRPC/JSONRPC.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/JSONRPC.swift#L24

Added line #L24 was not covered by tests
jsonrpc = "2.0"
result = nil
self.error = error
self.id = id
}
}

struct JSONError: Content, Error {
public struct JSONError: Content, Error {
let code: Int
let message: String
}

extension JSONError {
static func methodNotFound(_ method: String) -> JSONError {
public static func methodNotFound(_ method: String) -> JSONError {

Check warning on line 38 in RPC/Sources/RPC/JSONRPC/JSONRPC.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/JSONRPC.swift#L38

Added line #L38 was not covered by tests
JSONError(code: -32601, message: "Method not found: \(method)")
}
}
7 changes: 4 additions & 3 deletions RPC/Sources/RPC/JSONRPC/JSONRPCController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
init(handlers: [any RPCHandler]) {
var dict = [String: any RPCHandler]()
for handler in handlers {
if dict.keys.contains(handler.method) {
logger.warning("Duplicated handler: \(handler.method)")
let method = type(of: handler).method
if dict.keys.contains(method) {
logger.warning("Duplicated handler: \(method)")

Check warning on line 18 in RPC/Sources/RPC/JSONRPC/JSONRPCController.swift

View check run for this annotation

Codecov / codecov/patch

RPC/Sources/RPC/JSONRPC/JSONRPCController.swift#L18

Added line #L18 was not covered by tests
}
dict[handler.method] = handler
dict[method] = handler
}
self.handlers = dict

Expand Down
Loading