Swift grpc to NIO (#109)

* update protofiles

* update protobuf

* swift lint

* update GRPC service to NIO

* initial update [wip]

* Upgrade to SwiftGRPC NIO and Tests
This commit is contained in:
Francisco Gindre 2020-04-09 19:25:43 -03:00 committed by GitHub
parent 7510370892
commit 174ceb1d8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 1092 additions and 864 deletions

View File

@ -6,6 +6,7 @@ target 'ZcashLightClientSample' do
pod "KRProgressHUD"
# Pods for ZcashLightClientSample
pod 'ZcashLightClientKit', :path => '../../', :testspecs => ['Tests']
pod 'gRPC-Swift', '~> 1.0.0-alpha.11'
pod 'PaginatedTableView'
pod 'NotificationBubbles'
target 'ZcashLightClientSampleTests' do

View File

@ -1,43 +1,77 @@
PODS:
- BoringSSL-GRPC (0.0.3):
- BoringSSL-GRPC/Implementation (= 0.0.3)
- BoringSSL-GRPC/Interface (= 0.0.3)
- BoringSSL-GRPC/Implementation (0.0.3):
- BoringSSL-GRPC/Interface (= 0.0.3)
- BoringSSL-GRPC/Interface (0.0.3)
- gRPC-Core (1.23.1):
- gRPC-Core/Implementation (= 1.23.1)
- gRPC-Core/Interface (= 1.23.1)
- gRPC-Core/Implementation (1.23.1):
- BoringSSL-GRPC (= 0.0.3)
- gRPC-Core/Interface (= 1.23.1)
- nanopb (~> 0.3)
- gRPC-Core/Interface (1.23.1)
- CGRPCZlib (1.0.0-alpha.11)
- CNIOAtomics (2.15.0)
- CNIOBoringSSL (2.7.1)
- CNIOBoringSSLShims (2.7.1):
- CNIOBoringSSL (= 2.7.1)
- CNIODarwin (2.15.0)
- CNIOHTTPParser (2.15.0)
- CNIOLinux (2.15.0)
- CNIOSHA1 (2.15.0)
- gRPC-Swift (1.0.0-alpha.11):
- CGRPCZlib (= 1.0.0-alpha.11)
- Logging (= 1.2.0)
- SwiftNIO (= 2.15.0)
- SwiftNIOHTTP2 (= 1.11.0)
- SwiftNIOSSL (= 2.7.1)
- SwiftNIOTransportServices (= 1.3.0)
- SwiftProtobuf (= 1.8.0)
- KRActivityIndicatorView (3.0.4)
- KRProgressHUD (3.4.4):
- KRActivityIndicatorView (= 3.0.4)
- nanopb (0.3.9011):
- nanopb/decode (= 0.3.9011)
- nanopb/encode (= 0.3.9011)
- nanopb/decode (0.3.9011)
- nanopb/encode (0.3.9011)
- Logging (1.2.0)
- NotificationBubbles (0.1.1)
- PaginatedTableView (0.1.0)
- PaginatedTableView (1.0.1)
- SQLite.swift (0.12.2):
- SQLite.swift/standard (= 0.12.2)
- SQLite.swift/standard (0.12.2)
- SwiftGRPC (0.10.0):
- gRPC-Core (~> 1.23.0)
- SwiftProtobuf (~> 1.7.0)
- SwiftProtobuf (1.7.0)
- ZcashLightClientKit (0.3.2):
- SwiftNIO (2.15.0):
- CNIOAtomics (= 2.15.0)
- CNIODarwin (= 2.15.0)
- CNIOLinux (= 2.15.0)
- CNIOSHA1 (= 2.15.0)
- SwiftNIOConcurrencyHelpers (= 2.15.0)
- SwiftNIOConcurrencyHelpers (2.15.0):
- CNIOAtomics (= 2.15.0)
- SwiftNIOFoundationCompat (2.15.0):
- SwiftNIO (= 2.15.0)
- SwiftNIOHPACK (1.11.0):
- SwiftNIO (= 2.15.0)
- SwiftNIOConcurrencyHelpers (= 2.15.0)
- SwiftNIOHTTP1 (= 2.15.0)
- SwiftNIOHTTP1 (2.15.0):
- CNIOHTTPParser (= 2.15.0)
- SwiftNIO (= 2.15.0)
- SwiftNIOConcurrencyHelpers (= 2.15.0)
- SwiftNIOHTTP2 (1.11.0):
- SwiftNIO (= 2.15.0)
- SwiftNIOConcurrencyHelpers (= 2.15.0)
- SwiftNIOHPACK (= 1.11.0)
- SwiftNIOHTTP1 (= 2.15.0)
- SwiftNIOTLS (= 2.15.0)
- SwiftNIOSSL (2.7.1):
- CNIOBoringSSL (= 2.7.1)
- CNIOBoringSSLShims (= 2.7.1)
- SwiftNIO (= 2.15.0)
- SwiftNIOConcurrencyHelpers (= 2.15.0)
- SwiftNIOTLS (= 2.15.0)
- SwiftNIOTLS (2.15.0):
- SwiftNIO (= 2.15.0)
- SwiftNIOTransportServices (1.3.0):
- SwiftNIO (~> 2.0)
- SwiftNIOConcurrencyHelpers (~> 2.0)
- SwiftNIOFoundationCompat (~> 2.0)
- SwiftNIOTLS (~> 2.0)
- SwiftProtobuf (1.8.0)
- ZcashLightClientKit (0.4.0):
- gRPC-Swift (~> 1.0.0-alpha.11)
- SQLite.swift (~> 0.12.2)
- SwiftGRPC (~> 0.10.0)
- ZcashLightClientKit/Tests (0.3.2):
- ZcashLightClientKit/Tests (0.4.0):
- gRPC-Swift (~> 1.0.0-alpha.11)
- SQLite.swift (~> 0.12.2)
- SwiftGRPC (~> 0.10.0)
DEPENDENCIES:
- gRPC-Swift (~> 1.0.0-alpha.11)
- KRProgressHUD
- NotificationBubbles
- PaginatedTableView
@ -46,15 +80,30 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- BoringSSL-GRPC
- gRPC-Core
- CGRPCZlib
- CNIOAtomics
- CNIOBoringSSL
- CNIOBoringSSLShims
- CNIODarwin
- CNIOHTTPParser
- CNIOLinux
- CNIOSHA1
- gRPC-Swift
- KRActivityIndicatorView
- KRProgressHUD
- nanopb
- Logging
- NotificationBubbles
- PaginatedTableView
- SQLite.swift
- SwiftGRPC
- SwiftNIO
- SwiftNIOConcurrencyHelpers
- SwiftNIOFoundationCompat
- SwiftNIOHPACK
- SwiftNIOHTTP1
- SwiftNIOHTTP2
- SwiftNIOSSL
- SwiftNIOTLS
- SwiftNIOTransportServices
- SwiftProtobuf
EXTERNAL SOURCES:
@ -62,18 +111,33 @@ EXTERNAL SOURCES:
:path: "../../"
SPEC CHECKSUMS:
BoringSSL-GRPC: db8764df3204ccea016e1c8dd15d9a9ad63ff318
gRPC-Core: 4b1148eb8596225178e5a154e40e35141a3cdf0f
CGRPCZlib: e595387378d0601be796e858dd30c505458c4b1f
CNIOAtomics: ba49b1c86f281e1ecfd84c9205fbc27a81826847
CNIOBoringSSL: e4766830ab6d7c7fcd3618331f05fcb11638314d
CNIOBoringSSLShims: c3f3c6f05b7ce9b576521328a5b1b566d8f4665b
CNIODarwin: 2e341dd283fa3972706568b12925366145a8e2cd
CNIOHTTPParser: 25e1d1bc84c0612cbbbd6baedc4be05d77a17e01
CNIOLinux: 61598a8e49510207acb74c87f8fc11f762f76b5a
CNIOSHA1: 7b1dcceef9682aef4c6578b9fc67f87a03f0c48e
gRPC-Swift: 79f04da038f9a62005271d5b638611ce1bb31304
KRActivityIndicatorView: 549db10b9578d58bac73db063d8b544e8970f7f2
KRProgressHUD: c3b9a48a0ee4824ea13212ac3f1efa50dca021e3
nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
Logging: 7838d379d234d7e5ae1265fa02804a9084caf04c
NotificationBubbles: 91ee10deee54f35b5d49a161e1cb3d788ab5d011
PaginatedTableView: 14025b52a9f88bb1e9a87f31765eae7986ffb192
PaginatedTableView: 294d9831d5ddf5c0dcfbb4a281d4fcfb8d12f55a
SQLite.swift: d2b4642190917051ce6bd1d49aab565fe794eea3
SwiftGRPC: f8fcfecb547c96cc6913de619f95fa3cd09838ee
SwiftProtobuf: 4fd9645e69b72cbae6ec8da5be0cdd20ca6565dd
ZcashLightClientKit: 28a8fd46d8c29486902a16f2fddc01a38c107300
SwiftNIO: c9889dcd8aed2655af9163b42fc11ebd4ce94252
SwiftNIOConcurrencyHelpers: 2357037a16e9c51880c01b896a5ac3cd41066044
SwiftNIOFoundationCompat: f09ee499a8a9c636ec9007f73c5a1cedc23dcad3
SwiftNIOHPACK: 906596511ff9d1e095b7a72a0011351591bcae03
SwiftNIOHTTP1: b05f4061ba18482006a264a5aa087bbcd35d153c
SwiftNIOHTTP2: 3a52499594c6ec073af2a2801cf3c5d3d1c8700f
SwiftNIOSSL: 7c82b8393a6b69a3ef9b12fe74240e92c2bd7add
SwiftNIOTLS: 51580e51240d1a4d51efb2d317e92cf243181042
SwiftNIOTransportServices: 26d40c589fc8fe667af51b06ef0aa49fbc9ae7f2
SwiftProtobuf: 2cbd9409689b7df170d82a92a33443c8e3e14a70
ZcashLightClientKit: 47e707be6657391d5d4fd7db1544b0d98ce45e42
PODFILE CHECKSUM: 5a1fb98512fa179a4e83d67d14dd402f6d129a4d
PODFILE CHECKSUM: 4022861094cde8ab9d9c2f650b4a4adec279287f
COCOAPODS: 1.9.1

View File

@ -11,7 +11,7 @@ import ZcashLightClientKit
struct DemoAppConfig {
static var host = ZcashSDK.isMainnet ? "lightwalletd.z.cash" : "lightwalletd.testnet.z.cash"
static var port = "9067"
static var port: Int = 9067
static var birthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 643_500 : 620_000
static var network = ZcashSDK.isMainnet ? ZcashNetwork.mainNet : ZcashNetwork.testNet
static var seed = ZcashSDK.isMainnet ? Array("testreferencealicetestreferencealice".utf8) : Array("testreferencealicetestreferencealice".utf8)

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'ZcashLightClientKit'
s.version = '0.3.2'
s.version = '0.4.0'
s.summary = 'Zcash Light Client wallet SDK for iOS'
s.description = <<-DESC
@ -19,7 +19,7 @@ Pod::Spec.new do |s|
s.module_map = 'ZcashLightClientKit.modulemap'
s.swift_version = '5.1'
s.ios.deployment_target = '12.0'
s.dependency 'SwiftGRPC', '~> 0.10.0'
s.dependency 'gRPC-Swift', '~> 1.0.0-alpha.11'
s.dependency 'SQLite.swift', '~> 0.12.2'
s.ios.vendored_libraries = 'lib/libzcashlc.a'
s.preserve_paths = ['Scripts', 'rust','docs','Cargo.*','ZcashLightClientKit/Stencil']
@ -40,7 +40,7 @@ Pod::Spec.new do |s|
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_test_constants.sh && ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh --testing',
:execution_position => :before_compile
}
test_spec.dependency 'SwiftGRPC', '~> 0.10.0'
test_spec.dependency 'gRPC-Swift', '~> 1.0.0-alpha.11'
test_spec.dependency 'SQLite.swift', '~> 0.12.2'
end
end

View File

@ -7,7 +7,7 @@
//
import Foundation
import SwiftGRPC
import GRPC
/**
Errors thrown by CompactBlock Processor
@ -17,6 +17,7 @@ public enum CompactBlockProcessorError: Error {
case missingDbPath(path: String)
case dataDbInitFailed(path: String)
case connectionError(message: String)
case grpcError(statusCode: Int, message: String)
case generalError(message: String)
case maxAttemptsReached(attempts: Int)
}
@ -613,14 +614,15 @@ public class CompactBlockProcessor {
default:
return CompactBlockProcessorError.generalError(message: "Error: \(lwdError)")
}
} else if let rpcError = error as? SwiftGRPC.RPCError {
} else if let rpcError = error as? GRPC.GRPCStatus {
switch rpcError {
case .invalidMessageReceived:
return CompactBlockProcessorError.connectionError(message: "invalid GRPC Message received")
case .timedOut:
return CompactBlockProcessorError.connectionError(message: "connection timeout")
case .callError(let callResult):
return CompactBlockProcessorError.connectionError(message: "GRPC Call error. Success: \(callResult.success) - StatusCode: \(callResult.statusCode)")
case .ok:
let msg = "Error Raised when status is OK"
LoggerProxy.warn(msg)
return CompactBlockProcessorError.grpcError(statusCode: rpcError.code.rawValue, message: rpcError.message ?? "Error Raised when status is OK")
default:
return CompactBlockProcessorError.grpcError(statusCode: rpcError.code.rawValue, message: rpcError.message ?? "No message")
}
}
return error

View File

@ -23,13 +23,11 @@ public enum InitializerError: Error {
Represents a lightwallet instance endpoint to connect to
*/
public struct LightWalletEndpoint {
public var address: String
public var port: String
public var host: String
public var port: Int
public var secure: Bool
public var host: String {
"\(address):\(port)"
}
/**
initializes a LightWalletEndpoint
- Parameters:
@ -37,8 +35,8 @@ public struct LightWalletEndpoint {
- port: string with the port of the host address
- secure: true if connecting through TLS. Default value is true
*/
public init(address: String, port: String, secure: Bool = true) {
self.address = address
public init(address: String, port: Int, secure: Bool = true) {
self.host = address
self.port = port
self.secure = secure
}

View File

@ -7,7 +7,9 @@
//
import Foundation
import SwiftGRPC
import GRPC
import NIO
public typealias Channel = GRPC.GRPCChannel
/**
Swift GRPC implementation of Lightwalletd service */
@ -16,62 +18,59 @@ public class LightWalletGRPCService {
var queue = DispatchQueue.init(label: "LightWalletGRPCService")
let channel: Channel
let compactTxStreamer: CompactTxStreamerServiceClient
let compactTxStreamer: CompactTxStreamerClient
public init(channel: Channel) {
self.channel = channel
compactTxStreamer = CompactTxStreamerServiceClient(channel: self.channel)
compactTxStreamer = CompactTxStreamerClient(channel: self.channel)
}
public convenience init(endpoint: LightWalletEndpoint) {
self.init(host: endpoint.host, secure: endpoint.secure)
self.init(host: endpoint.host, port: endpoint.port, secure: endpoint.secure)
}
public convenience init(host: String, secure: Bool = true) {
let channel = Channel(address: host, secure: secure, arguments: [])
public convenience init(host: String, port: Int = 9067, secure: Bool = true) {
let configuration = ClientConnection.Configuration(target: .hostAndPort(host, port), eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1), tls: secure ? .init() : nil)
let channel = ClientConnection(configuration: configuration)
self.init(channel: channel)
}
func stop() {
channel.shutdown()
_ = channel.close()
}
func resume() -> Channel.ConnectivityState {
channel.connectivityState(tryToConnect: true)
}
func blockRange(startHeight: BlockHeight, endHeight: BlockHeight? = nil, result: @escaping (CallResult) -> Void) throws -> CompactTxStreamerGetBlockRangeCall {
try compactTxStreamer.getBlockRange(BlockRange(startHeight: startHeight, endHeight: endHeight)) { result($0) }
func blockRange(startHeight: BlockHeight, endHeight: BlockHeight? = nil, result: @escaping (CompactBlock) -> Void) throws -> ServerStreamingCall<BlockRange, CompactBlock> {
compactTxStreamer.getBlockRange(BlockRange(startHeight: startHeight, endHeight: endHeight), handler: result)
}
func latestBlock() throws -> BlockID {
try compactTxStreamer.getLatestBlock(ChainSpec())
try compactTxStreamer.getLatestBlock(ChainSpec()).response.wait()
}
func getTx(hash: String) throws -> RawTransaction {
var filter = TxFilter()
filter.hash = Data(hash.utf8)
return try compactTxStreamer.getTransaction(filter)
}
func getAllBlocksSinceSaplingLaunch(_ result: @escaping (CallResult) -> Void) throws -> CompactTxStreamerGetBlockRangeCall {
try compactTxStreamer.getBlockRange(BlockRange.sinceSaplingActivation(), completion: result)
return try compactTxStreamer.getTransaction(filter).response.wait()
}
}
extension LightWalletGRPCService: LightWalletService {
public func submit(spendTransaction: Data, result: @escaping (Result<LightWalletServiceResponse, LightWalletServiceError>) -> Void) {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
do {
let tx = try RawTransaction(serializedData: spendTransaction)
let response = self.compactTxStreamer.sendTransaction(tx).response
guard let self = self else { return }
do {
let response = try self.compactTxStreamer.sendTransaction(RawTransaction(serializedData: spendTransaction))
result(.success(response))
} catch {
result(.failure(LightWalletServiceError.genericError(error: error)))
response.whenComplete { (responseResult) in
switch responseResult {
case .failure(let e):
result(.failure(LightWalletServiceError.genericError(error: e)))
case .success(let s):
result(.success(s))
}
}
} catch {
result(.failure(LightWalletServiceError.genericError(error: error)))
}
}
@ -80,89 +79,78 @@ extension LightWalletGRPCService: LightWalletService {
let rawTx = RawTransaction.with { (raw) in
raw.data = spendTransaction
}
return try compactTxStreamer.sendTransaction(rawTx)
return try compactTxStreamer.sendTransaction(rawTx).response.wait()
}
public func blockRange(_ range: CompactBlockRange) throws -> [ZcashCompactBlock] {
var blocks = [ZcashCompactBlock]()
var blocks = [CompactBlock]()
let call = try compactTxStreamer.getBlockRange(range.blockRange(), completion: { statusCode in
LoggerProxy.debug("finished with statusCode: \(statusCode)")
})
let response = compactTxStreamer.getBlockRange(range.blockRange(), handler: {
blocks.append($0)
})
while let block = try call.receive() {
if let compactBlock = ZcashCompactBlock(compactBlock: block) {
blocks.append(compactBlock)
} else {
throw LightWalletServiceError.invalidBlock
}
do {
_ = try response.status.wait()
} catch {
throw LightWalletServiceError.genericError(error: error)
}
return blocks
do {
return try blocks.asZcashCompactBlocks()
} catch {
LoggerProxy.error("invalid block in range: \(range) - Error: \(error)")
throw LightWalletServiceError.genericError(error: error)
}
}
public func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
do {
try compactTxStreamer.getLatestBlock(ChainSpec()) { (blockID, callResult) in
guard let rawHeight = blockID?.height, let blockHeight = Int(exactly: rawHeight) else {
result(.failure(LightWalletServiceError.failed(statusCode: callResult.statusCode, message: callResult.statusMessage ?? "No message")))
return
}
result(.success(blockHeight))
let response = compactTxStreamer.getLatestBlock(ChainSpec()).response
response.whenSuccess { (blockID) in
guard let blockHeight = Int(exactly: blockID.height) else {
result(.failure(LightWalletServiceError.generalError))
return
}
} catch {
// TODO: Handle Error
LoggerProxy.debug(error.localizedDescription)
result(.failure(LightWalletServiceError.generalError))
result(.success(blockHeight))
}
response.whenFailure { (error) in
result(.failure(LightWalletServiceError.genericError(error: error)))
}
}
// TODO: Make cancellable
public func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void) {
queue.async { [weak self] in
guard let self = self else { return }
var blocks = [CompactBlock]()
var isSyncing = true
guard let response = try? self.compactTxStreamer.getBlockRange(range.blockRange(),completion: { (callResult) in
isSyncing = false
if callResult.success {
let code = callResult.statusCode
switch code{
case .ok:
do {
result(.success(try blocks.asZcashCompactBlocks()))
} catch {
result(.failure(LightWalletServiceError.generalError))
}
default:
result(.failure(LightWalletServiceError.failed(statusCode: code, message: callResult.statusMessage ?? "No Message")))
}
} else {
result(.failure(LightWalletServiceError.generalError))
return
}
}) else {
result(.failure(LightWalletServiceError.generalError))
return
}
let response = self.compactTxStreamer.getBlockRange(range.blockRange(), handler: { blocks.append($0) })
do {
var element: CompactBlock?
repeat {
element = try response.receive()
if let e = element {
blocks.append(e)
let status = try response.status.wait()
switch status.code {
case .ok:
do {
result(.success(try blocks.asZcashCompactBlocks()))
} catch {
result(.failure(LightWalletServiceError.generalError))
}
} while isSyncing && element != nil
default:
result(Result.failure(LightWalletServiceError.failed(statusCode: status.code.rawValue, message: status.message ?? "No Message")))
}
} catch {
result(.failure(LightWalletServiceError.generalError))
result(.failure(LightWalletServiceError.genericError(error: error)))
}
}
}

View File

@ -7,7 +7,7 @@
//
import Foundation
import SwiftGRPC
import GRPC
import SwiftProtobuf
/**
@ -15,7 +15,7 @@ import SwiftProtobuf
*/
public enum LightWalletServiceError: Error {
case generalError
case failed(statusCode: StatusCode, message: String)
case failed(statusCode: Int, message: String)
case invalidBlock
case sentFailed(sendResponse: LightWalletServiceResponse)
case genericError(error: Error)

View File

@ -3,7 +3,7 @@
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: compact_formats.proto
//
// For information on using the generated types, please see the documenation:
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Copyright (c) 2019-2020 The Zcash developers
@ -16,7 +16,7 @@ import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that your are building against the same version of the API
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}

View File

@ -1,52 +0,0 @@
// Copyright (c) 2019-2020 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
syntax = "proto3";
package cash.z.wallet.sdk.rpc;
option go_package = "walletrpc";
option swift_prefix = "";
// Remember that proto3 fields are all optional. A field that is not present will be set to its zero value.
// bytes fields of hashes are in canonical little-endian format.
// CompactBlock is a packaging of ONLY the data from a block that's needed to:
// 1. Detect a payment to your shielded Sapling address
// 2. Detect a spend of your shielded Sapling notes
// 3. Update your witnesses to generate new Sapling spend proofs.
message CompactBlock {
uint32 protoVersion = 1; // the version of this wire format, for storage
uint64 height = 2; // the height of this block
bytes hash = 3;
bytes prevHash = 4;
uint32 time = 5;
bytes header = 6; // (hash, prevHash, and time) OR (full header)
repeated CompactTx vtx = 7; // compact transactions from this block
}
// Index and hash will allow the receiver to call out to chain
// explorers or other data structures to retrieve more information
// about this transaction.
message CompactTx {
uint64 index = 1;
bytes hash = 2;
// The transaction fee: present if server can provide. In the case of a
// stateless server and a transaction with transparent inputs, this will be
// unset because the calculation requires reference to prior transactions.
// in a pure-Sapling context, the fee will be calculable as:
// valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
uint32 fee = 3;
repeated CompactSpend spends = 4;
repeated CompactOutput outputs = 5;
}
message CompactSpend {
bytes nf = 1;
}
message CompactOutput {
bytes cmu = 1;
bytes epk = 2;
bytes ciphertext = 3;
}

View File

@ -1,104 +0,0 @@
// Copyright (c) 2019-2020 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
syntax = "proto3";
package cash.z.wallet.sdk.rpc;
option go_package = "walletrpc";
option swift_prefix = "";
import "compact_formats.proto";
// A BlockID message contains identifiers to select a block: a height or a
// hash. Specification by hash is not implemented, but may be in the future.
message BlockID {
uint64 height = 1;
bytes hash = 2;
}
// BlockRange specifies a series of blocks from start to end inclusive.
// Both BlockIDs must be heights; specification by hash is not yet supported.
message BlockRange {
BlockID start = 1;
BlockID end = 2;
}
// A TxFilter contains the information needed to identify a particular
// transaction: either a block and an index, or a direct transaction hash.
// Currently, only specification by hash is supported.
message TxFilter {
BlockID block = 1;
uint64 index = 2;
bytes hash = 3;
}
// RawTransaction contains the complete transaction data. It also optionally includes
// the block height in which the transaction was included
message RawTransaction {
bytes data = 1;
uint64 height = 2;
}
// A SendResponse encodes an error code and a string. It is currently used
// only by SendTransaction(). If error code is zero, the operation was
// successful; if non-zero, it and the message specify the failure.
message SendResponse {
int32 errorCode = 1;
string errorMessage = 2;
}
// Chainspec is a placeholder to allow specification of a particular chain fork.
message ChainSpec {}
// Empty is for gRPCs that take no arguments, currently only GetLightdInfo.
message Empty {}
// LightdInfo returns various information about this lightwalletd instance
// and the state of the blockchain.
message LightdInfo {
string version = 1;
string vendor = 2;
bool taddrSupport = 3;
string chainName = 4;
uint64 saplingActivationHeight = 5;
string consensusBranchId = 6;
uint64 blockHeight = 7;
}
// TransparentAddressBlockFilter restricts the results to the given address
// or block range.
message TransparentAddressBlockFilter {
string address = 1;
BlockRange range = 2;
}
// Duration is currently used only for testing, so that the Ping rpc
// can simulate a delay, to create many simultaneous connections. Units
// are microseconds.
message Duration {
int64 intervalUs = 1;
}
// PingResponse is used to indicate concurrency, how many Ping rpcs
// are executing upon entry and upon exit (after the delay).
message PingResponse {
int64 entry = 1;
int64 exit = 2;
}
service CompactTxStreamer {
// Compact Blocks
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
rpc GetBlock(BlockID) returns (CompactBlock) {}
rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}
// Transactions
rpc GetTransaction(TxFilter) returns (RawTransaction) {}
rpc SendTransaction(RawTransaction) returns (SendResponse) {}
// t-Address support
rpc GetAddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {}
// Misc
rpc GetLightdInfo(Empty) returns (LightdInfo) {}
rpc Ping(Duration) returns (PingResponse) {}
}

View File

@ -20,291 +20,153 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Dispatch
import Foundation
import SwiftGRPC
import GRPC
import NIO
import NIOHTTP1
import SwiftProtobuf
internal protocol CompactTxStreamerGetLatestBlockCall: ClientCallUnary {}
fileprivate final class CompactTxStreamerGetLatestBlockCallBase: ClientCallUnaryBase<ChainSpec, BlockID>, CompactTxStreamerGetLatestBlockCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock" }
/// Usage: instantiate CompactTxStreamerClient, then call methods of this protocol to make API calls.
internal protocol CompactTxStreamerClientProtocol {
func getLatestBlock(_ request: ChainSpec, callOptions: CallOptions?) -> UnaryCall<ChainSpec, BlockID>
func getBlock(_ request: BlockID, callOptions: CallOptions?) -> UnaryCall<BlockID, CompactBlock>
func getBlockRange(_ request: BlockRange, callOptions: CallOptions?, handler: @escaping (CompactBlock) -> Void) -> ServerStreamingCall<BlockRange, CompactBlock>
func getTransaction(_ request: TxFilter, callOptions: CallOptions?) -> UnaryCall<TxFilter, RawTransaction>
func sendTransaction(_ request: RawTransaction, callOptions: CallOptions?) -> UnaryCall<RawTransaction, SendResponse>
func getAddressTxids(_ request: TransparentAddressBlockFilter, callOptions: CallOptions?, handler: @escaping (RawTransaction) -> Void) -> ServerStreamingCall<TransparentAddressBlockFilter, RawTransaction>
func getLightdInfo(_ request: Empty, callOptions: CallOptions?) -> UnaryCall<Empty, LightdInfo>
func ping(_ request: Duration, callOptions: CallOptions?) -> UnaryCall<Duration, PingResponse>
}
internal protocol CompactTxStreamerGetBlockCall: ClientCallUnary {}
internal final class CompactTxStreamerClient: GRPCClient, CompactTxStreamerClientProtocol {
internal let channel: GRPCChannel
internal var defaultCallOptions: CallOptions
fileprivate final class CompactTxStreamerGetBlockCallBase: ClientCallUnaryBase<BlockID, CompactBlock>, CompactTxStreamerGetBlockCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock" }
}
internal protocol CompactTxStreamerGetBlockRangeCall: ClientCallServerStreaming {
/// Do not call this directly, call `receive()` in the protocol extension below instead.
func _receive(timeout: DispatchTime) throws -> CompactBlock?
/// Call this to wait for a result. Nonblocking.
func receive(completion: @escaping (ResultOrRPCError<CompactBlock?>) -> Void) throws
}
internal extension CompactTxStreamerGetBlockRangeCall {
/// Call this to wait for a result. Blocking.
func receive(timeout: DispatchTime = .distantFuture) throws -> CompactBlock? { return try self._receive(timeout: timeout) }
}
fileprivate final class CompactTxStreamerGetBlockRangeCallBase: ClientCallServerStreamingBase<BlockRange, CompactBlock>, CompactTxStreamerGetBlockRangeCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange" }
}
internal protocol CompactTxStreamerGetTransactionCall: ClientCallUnary {}
fileprivate final class CompactTxStreamerGetTransactionCallBase: ClientCallUnaryBase<TxFilter, RawTransaction>, CompactTxStreamerGetTransactionCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction" }
}
internal protocol CompactTxStreamerSendTransactionCall: ClientCallUnary {}
fileprivate final class CompactTxStreamerSendTransactionCallBase: ClientCallUnaryBase<RawTransaction, SendResponse>, CompactTxStreamerSendTransactionCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction" }
}
internal protocol CompactTxStreamerGetAddressTxidsCall: ClientCallServerStreaming {
/// Do not call this directly, call `receive()` in the protocol extension below instead.
func _receive(timeout: DispatchTime) throws -> RawTransaction?
/// Call this to wait for a result. Nonblocking.
func receive(completion: @escaping (ResultOrRPCError<RawTransaction?>) -> Void) throws
}
internal extension CompactTxStreamerGetAddressTxidsCall {
/// Call this to wait for a result. Blocking.
func receive(timeout: DispatchTime = .distantFuture) throws -> RawTransaction? { return try self._receive(timeout: timeout) }
}
fileprivate final class CompactTxStreamerGetAddressTxidsCallBase: ClientCallServerStreamingBase<TransparentAddressBlockFilter, RawTransaction>, CompactTxStreamerGetAddressTxidsCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids" }
}
internal protocol CompactTxStreamerGetLightdInfoCall: ClientCallUnary {}
fileprivate final class CompactTxStreamerGetLightdInfoCallBase: ClientCallUnaryBase<Empty, LightdInfo>, CompactTxStreamerGetLightdInfoCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo" }
}
internal protocol CompactTxStreamerPingCall: ClientCallUnary {}
fileprivate final class CompactTxStreamerPingCallBase: ClientCallUnaryBase<Duration, PingResponse>, CompactTxStreamerPingCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.CompactTxStreamer/Ping" }
}
/// Instantiate CompactTxStreamerServiceClient, then call methods of this protocol to make API calls.
internal protocol CompactTxStreamerService: ServiceClient {
/// Synchronous. Unary.
func getLatestBlock(_ request: ChainSpec, metadata customMetadata: Metadata) throws -> BlockID
/// Asynchronous. Unary.
@discardableResult
func getLatestBlock(_ request: ChainSpec, metadata customMetadata: Metadata, completion: @escaping (BlockID?, CallResult) -> Void) throws -> CompactTxStreamerGetLatestBlockCall
/// Synchronous. Unary.
func getBlock(_ request: BlockID, metadata customMetadata: Metadata) throws -> CompactBlock
/// Asynchronous. Unary.
@discardableResult
func getBlock(_ request: BlockID, metadata customMetadata: Metadata, completion: @escaping (CompactBlock?, CallResult) -> Void) throws -> CompactTxStreamerGetBlockCall
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
func getBlockRange(_ request: BlockRange, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetBlockRangeCall
/// Synchronous. Unary.
func getTransaction(_ request: TxFilter, metadata customMetadata: Metadata) throws -> RawTransaction
/// Asynchronous. Unary.
@discardableResult
func getTransaction(_ request: TxFilter, metadata customMetadata: Metadata, completion: @escaping (RawTransaction?, CallResult) -> Void) throws -> CompactTxStreamerGetTransactionCall
/// Synchronous. Unary.
func sendTransaction(_ request: RawTransaction, metadata customMetadata: Metadata) throws -> SendResponse
/// Asynchronous. Unary.
@discardableResult
func sendTransaction(_ request: RawTransaction, metadata customMetadata: Metadata, completion: @escaping (SendResponse?, CallResult) -> Void) throws -> CompactTxStreamerSendTransactionCall
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
func getAddressTxids(_ request: TransparentAddressBlockFilter, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetAddressTxidsCall
/// Synchronous. Unary.
func getLightdInfo(_ request: Empty, metadata customMetadata: Metadata) throws -> LightdInfo
/// Asynchronous. Unary.
@discardableResult
func getLightdInfo(_ request: Empty, metadata customMetadata: Metadata, completion: @escaping (LightdInfo?, CallResult) -> Void) throws -> CompactTxStreamerGetLightdInfoCall
/// Synchronous. Unary.
func ping(_ request: Duration, metadata customMetadata: Metadata) throws -> PingResponse
/// Asynchronous. Unary.
@discardableResult
func ping(_ request: Duration, metadata customMetadata: Metadata, completion: @escaping (PingResponse?, CallResult) -> Void) throws -> CompactTxStreamerPingCall
}
internal extension CompactTxStreamerService {
/// Synchronous. Unary.
func getLatestBlock(_ request: ChainSpec) throws -> BlockID {
return try self.getLatestBlock(request, metadata: self.metadata)
}
/// Asynchronous. Unary.
@discardableResult
func getLatestBlock(_ request: ChainSpec, completion: @escaping (BlockID?, CallResult) -> Void) throws -> CompactTxStreamerGetLatestBlockCall {
return try self.getLatestBlock(request, metadata: self.metadata, completion: completion)
/// Creates a client for the cash.z.wallet.sdk.rpc.CompactTxStreamer service.
///
/// - Parameters:
/// - channel: `GRPCChannel` to the service host.
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
internal init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
self.channel = channel
self.defaultCallOptions = defaultCallOptions
}
/// Synchronous. Unary.
func getBlock(_ request: BlockID) throws -> CompactBlock {
return try self.getBlock(request, metadata: self.metadata)
}
/// Asynchronous. Unary.
@discardableResult
func getBlock(_ request: BlockID, completion: @escaping (CompactBlock?, CallResult) -> Void) throws -> CompactTxStreamerGetBlockCall {
return try self.getBlock(request, metadata: self.metadata, completion: completion)
/// Compact Blocks
///
/// - Parameters:
/// - request: Request to send to GetLatestBlock.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func getLatestBlock(_ request: ChainSpec, callOptions: CallOptions? = nil) -> UnaryCall<ChainSpec, BlockID> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
/// Asynchronous. Server-streaming.
func getBlockRange(_ request: BlockRange, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetBlockRangeCall {
return try self.getBlockRange(request, metadata: self.metadata, completion: completion)
/// Unary call to GetBlock
///
/// - Parameters:
/// - request: Request to send to GetBlock.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func getBlock(_ request: BlockID, callOptions: CallOptions? = nil) -> UnaryCall<BlockID, CompactBlock> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
/// Synchronous. Unary.
func getTransaction(_ request: TxFilter) throws -> RawTransaction {
return try self.getTransaction(request, metadata: self.metadata)
}
/// Asynchronous. Unary.
@discardableResult
func getTransaction(_ request: TxFilter, completion: @escaping (RawTransaction?, CallResult) -> Void) throws -> CompactTxStreamerGetTransactionCall {
return try self.getTransaction(request, metadata: self.metadata, completion: completion)
/// Server streaming call to GetBlockRange
///
/// - Parameters:
/// - request: Request to send to GetBlockRange.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - handler: A closure called when each response is received from the server.
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
internal func getBlockRange(_ request: BlockRange, callOptions: CallOptions? = nil, handler: @escaping (CompactBlock) -> Void) -> ServerStreamingCall<BlockRange, CompactBlock> {
return self.makeServerStreamingCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange",
request: request,
callOptions: callOptions ?? self.defaultCallOptions,
handler: handler)
}
/// Synchronous. Unary.
func sendTransaction(_ request: RawTransaction) throws -> SendResponse {
return try self.sendTransaction(request, metadata: self.metadata)
}
/// Asynchronous. Unary.
@discardableResult
func sendTransaction(_ request: RawTransaction, completion: @escaping (SendResponse?, CallResult) -> Void) throws -> CompactTxStreamerSendTransactionCall {
return try self.sendTransaction(request, metadata: self.metadata, completion: completion)
/// Transactions
///
/// - Parameters:
/// - request: Request to send to GetTransaction.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func getTransaction(_ request: TxFilter, callOptions: CallOptions? = nil) -> UnaryCall<TxFilter, RawTransaction> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
/// Asynchronous. Server-streaming.
func getAddressTxids(_ request: TransparentAddressBlockFilter, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetAddressTxidsCall {
return try self.getAddressTxids(request, metadata: self.metadata, completion: completion)
/// Unary call to SendTransaction
///
/// - Parameters:
/// - request: Request to send to SendTransaction.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func sendTransaction(_ request: RawTransaction, callOptions: CallOptions? = nil) -> UnaryCall<RawTransaction, SendResponse> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
/// Synchronous. Unary.
func getLightdInfo(_ request: Empty) throws -> LightdInfo {
return try self.getLightdInfo(request, metadata: self.metadata)
}
/// Asynchronous. Unary.
@discardableResult
func getLightdInfo(_ request: Empty, completion: @escaping (LightdInfo?, CallResult) -> Void) throws -> CompactTxStreamerGetLightdInfoCall {
return try self.getLightdInfo(request, metadata: self.metadata, completion: completion)
/// t-Address support
///
/// - Parameters:
/// - request: Request to send to GetAddressTxids.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - handler: A closure called when each response is received from the server.
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
internal func getAddressTxids(_ request: TransparentAddressBlockFilter, callOptions: CallOptions? = nil, handler: @escaping (RawTransaction) -> Void) -> ServerStreamingCall<TransparentAddressBlockFilter, RawTransaction> {
return self.makeServerStreamingCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids",
request: request,
callOptions: callOptions ?? self.defaultCallOptions,
handler: handler)
}
/// Synchronous. Unary.
func ping(_ request: Duration) throws -> PingResponse {
return try self.ping(request, metadata: self.metadata)
/// Misc
///
/// - Parameters:
/// - request: Request to send to GetLightdInfo.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func getLightdInfo(_ request: Empty, callOptions: CallOptions? = nil) -> UnaryCall<Empty, LightdInfo> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
/// Asynchronous. Unary.
@discardableResult
func ping(_ request: Duration, completion: @escaping (PingResponse?, CallResult) -> Void) throws -> CompactTxStreamerPingCall {
return try self.ping(request, metadata: self.metadata, completion: completion)
/// Unary call to Ping
///
/// - Parameters:
/// - request: Request to send to Ping.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func ping(_ request: Duration, callOptions: CallOptions? = nil) -> UnaryCall<Duration, PingResponse> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.CompactTxStreamer/Ping",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
}
internal final class CompactTxStreamerServiceClient: ServiceClientBase, CompactTxStreamerService {
/// Synchronous. Unary.
internal func getLatestBlock(_ request: ChainSpec, metadata customMetadata: Metadata) throws -> BlockID {
return try CompactTxStreamerGetLatestBlockCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func getLatestBlock(_ request: ChainSpec, metadata customMetadata: Metadata, completion: @escaping (BlockID?, CallResult) -> Void) throws -> CompactTxStreamerGetLatestBlockCall {
return try CompactTxStreamerGetLatestBlockCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func getBlock(_ request: BlockID, metadata customMetadata: Metadata) throws -> CompactBlock {
return try CompactTxStreamerGetBlockCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func getBlock(_ request: BlockID, metadata customMetadata: Metadata, completion: @escaping (CompactBlock?, CallResult) -> Void) throws -> CompactTxStreamerGetBlockCall {
return try CompactTxStreamerGetBlockCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
internal func getBlockRange(_ request: BlockRange, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetBlockRangeCall {
return try CompactTxStreamerGetBlockRangeCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func getTransaction(_ request: TxFilter, metadata customMetadata: Metadata) throws -> RawTransaction {
return try CompactTxStreamerGetTransactionCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func getTransaction(_ request: TxFilter, metadata customMetadata: Metadata, completion: @escaping (RawTransaction?, CallResult) -> Void) throws -> CompactTxStreamerGetTransactionCall {
return try CompactTxStreamerGetTransactionCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func sendTransaction(_ request: RawTransaction, metadata customMetadata: Metadata) throws -> SendResponse {
return try CompactTxStreamerSendTransactionCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func sendTransaction(_ request: RawTransaction, metadata customMetadata: Metadata, completion: @escaping (SendResponse?, CallResult) -> Void) throws -> CompactTxStreamerSendTransactionCall {
return try CompactTxStreamerSendTransactionCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
internal func getAddressTxids(_ request: TransparentAddressBlockFilter, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> CompactTxStreamerGetAddressTxidsCall {
return try CompactTxStreamerGetAddressTxidsCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func getLightdInfo(_ request: Empty, metadata customMetadata: Metadata) throws -> LightdInfo {
return try CompactTxStreamerGetLightdInfoCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func getLightdInfo(_ request: Empty, metadata customMetadata: Metadata, completion: @escaping (LightdInfo?, CallResult) -> Void) throws -> CompactTxStreamerGetLightdInfoCall {
return try CompactTxStreamerGetLightdInfoCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func ping(_ request: Duration, metadata customMetadata: Metadata) throws -> PingResponse {
return try CompactTxStreamerPingCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func ping(_ request: Duration, metadata customMetadata: Metadata, completion: @escaping (PingResponse?, CallResult) -> Void) throws -> CompactTxStreamerPingCall {
return try CompactTxStreamerPingCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
}
// Provides conformance to `GRPCPayload` for request and response messages
extension ChainSpec: GRPCProtobufPayload {}
extension BlockID: GRPCProtobufPayload {}
extension CompactBlock: GRPCProtobufPayload {}
extension BlockRange: GRPCProtobufPayload {}
extension TxFilter: GRPCProtobufPayload {}
extension RawTransaction: GRPCProtobufPayload {}
extension SendResponse: GRPCProtobufPayload {}
extension TransparentAddressBlockFilter: GRPCProtobufPayload {}
extension Empty: GRPCProtobufPayload {}
extension LightdInfo: GRPCProtobufPayload {}
extension Duration: GRPCProtobufPayload {}
extension PingResponse: GRPCProtobufPayload {}

View File

@ -3,7 +3,7 @@
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: service.proto
//
// For information on using the generated types, please see the documenation:
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Copyright (c) 2019-2020 The Zcash developers
@ -16,7 +16,7 @@ import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that your are building against the same version of the API
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
@ -47,28 +47,29 @@ struct BlockRange {
// methods supported on all messages.
var start: BlockID {
get {return _storage._start ?? BlockID()}
set {_uniqueStorage()._start = newValue}
get {return _start ?? BlockID()}
set {_start = newValue}
}
/// Returns true if `start` has been explicitly set.
var hasStart: Bool {return _storage._start != nil}
var hasStart: Bool {return self._start != nil}
/// Clears the value of `start`. Subsequent reads from it will return its default value.
mutating func clearStart() {_uniqueStorage()._start = nil}
mutating func clearStart() {self._start = nil}
var end: BlockID {
get {return _storage._end ?? BlockID()}
set {_uniqueStorage()._end = newValue}
get {return _end ?? BlockID()}
set {_end = newValue}
}
/// Returns true if `end` has been explicitly set.
var hasEnd: Bool {return _storage._end != nil}
var hasEnd: Bool {return self._end != nil}
/// Clears the value of `end`. Subsequent reads from it will return its default value.
mutating func clearEnd() {_uniqueStorage()._end = nil}
mutating func clearEnd() {self._end = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _storage = _StorageClass.defaultInstance
fileprivate var _start: BlockID? = nil
fileprivate var _end: BlockID? = nil
}
/// A TxFilter contains the information needed to identify a particular
@ -80,29 +81,23 @@ struct TxFilter {
// methods supported on all messages.
var block: BlockID {
get {return _storage._block ?? BlockID()}
set {_uniqueStorage()._block = newValue}
get {return _block ?? BlockID()}
set {_block = newValue}
}
/// Returns true if `block` has been explicitly set.
var hasBlock: Bool {return _storage._block != nil}
var hasBlock: Bool {return self._block != nil}
/// Clears the value of `block`. Subsequent reads from it will return its default value.
mutating func clearBlock() {_uniqueStorage()._block = nil}
mutating func clearBlock() {self._block = nil}
var index: UInt64 {
get {return _storage._index}
set {_uniqueStorage()._index = newValue}
}
var index: UInt64 = 0
var hash: Data {
get {return _storage._hash}
set {_uniqueStorage()._hash = newValue}
}
var hash: Data = SwiftProtobuf.Internal.emptyData
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _storage = _StorageClass.defaultInstance
fileprivate var _block: BlockID? = nil
}
/// RawTransaction contains the complete transaction data. It also optionally includes
@ -193,25 +188,22 @@ struct TransparentAddressBlockFilter {
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var address: String {
get {return _storage._address}
set {_uniqueStorage()._address = newValue}
}
var address: String = String()
var range: BlockRange {
get {return _storage._range ?? BlockRange()}
set {_uniqueStorage()._range = newValue}
get {return _range ?? BlockRange()}
set {_range = newValue}
}
/// Returns true if `range` has been explicitly set.
var hasRange: Bool {return _storage._range != nil}
var hasRange: Bool {return self._range != nil}
/// Clears the value of `range`. Subsequent reads from it will return its default value.
mutating func clearRange() {_uniqueStorage()._range = nil}
mutating func clearRange() {self._range = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _storage = _StorageClass.defaultInstance
fileprivate var _range: BlockRange? = nil
}
/// Duration is currently used only for testing, so that the Ping rpc
@ -291,63 +283,29 @@ extension BlockRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
2: .same(proto: "end"),
]
fileprivate class _StorageClass {
var _start: BlockID? = nil
var _end: BlockID? = nil
static let defaultInstance = _StorageClass()
private init() {}
init(copying source: _StorageClass) {
_start = source._start
_end = source._end
}
}
fileprivate mutating func _uniqueStorage() -> _StorageClass {
if !isKnownUniquelyReferenced(&_storage) {
_storage = _StorageClass(copying: _storage)
}
return _storage
}
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
_ = _uniqueStorage()
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &_storage._start)
case 2: try decoder.decodeSingularMessageField(value: &_storage._end)
default: break
}
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &self._start)
case 2: try decoder.decodeSingularMessageField(value: &self._end)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
if let v = _storage._start {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if let v = _storage._end {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
if let v = self._start {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if let v = self._end {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: BlockRange, rhs: BlockRange) -> Bool {
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
let _storage = _args.0
let rhs_storage = _args.1
if _storage._start != rhs_storage._start {return false}
if _storage._end != rhs_storage._end {return false}
return true
}
if !storagesAreEqual {return false}
}
if lhs._start != rhs._start {return false}
if lhs._end != rhs._end {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
@ -361,70 +319,34 @@ extension TxFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
3: .same(proto: "hash"),
]
fileprivate class _StorageClass {
var _block: BlockID? = nil
var _index: UInt64 = 0
var _hash: Data = SwiftProtobuf.Internal.emptyData
static let defaultInstance = _StorageClass()
private init() {}
init(copying source: _StorageClass) {
_block = source._block
_index = source._index
_hash = source._hash
}
}
fileprivate mutating func _uniqueStorage() -> _StorageClass {
if !isKnownUniquelyReferenced(&_storage) {
_storage = _StorageClass(copying: _storage)
}
return _storage
}
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
_ = _uniqueStorage()
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &_storage._block)
case 2: try decoder.decodeSingularUInt64Field(value: &_storage._index)
case 3: try decoder.decodeSingularBytesField(value: &_storage._hash)
default: break
}
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &self._block)
case 2: try decoder.decodeSingularUInt64Field(value: &self.index)
case 3: try decoder.decodeSingularBytesField(value: &self.hash)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
if let v = _storage._block {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if _storage._index != 0 {
try visitor.visitSingularUInt64Field(value: _storage._index, fieldNumber: 2)
}
if !_storage._hash.isEmpty {
try visitor.visitSingularBytesField(value: _storage._hash, fieldNumber: 3)
}
if let v = self._block {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if self.index != 0 {
try visitor.visitSingularUInt64Field(value: self.index, fieldNumber: 2)
}
if !self.hash.isEmpty {
try visitor.visitSingularBytesField(value: self.hash, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: TxFilter, rhs: TxFilter) -> Bool {
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
let _storage = _args.0
let rhs_storage = _args.1
if _storage._block != rhs_storage._block {return false}
if _storage._index != rhs_storage._index {return false}
if _storage._hash != rhs_storage._hash {return false}
return true
}
if !storagesAreEqual {return false}
}
if lhs._block != rhs._block {return false}
if lhs.index != rhs.index {return false}
if lhs.hash != rhs.hash {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
@ -610,63 +532,29 @@ extension TransparentAddressBlockFilter: SwiftProtobuf.Message, SwiftProtobuf._M
2: .same(proto: "range"),
]
fileprivate class _StorageClass {
var _address: String = String()
var _range: BlockRange? = nil
static let defaultInstance = _StorageClass()
private init() {}
init(copying source: _StorageClass) {
_address = source._address
_range = source._range
}
}
fileprivate mutating func _uniqueStorage() -> _StorageClass {
if !isKnownUniquelyReferenced(&_storage) {
_storage = _StorageClass(copying: _storage)
}
return _storage
}
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
_ = _uniqueStorage()
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularStringField(value: &_storage._address)
case 2: try decoder.decodeSingularMessageField(value: &_storage._range)
default: break
}
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularStringField(value: &self.address)
case 2: try decoder.decodeSingularMessageField(value: &self._range)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
if !_storage._address.isEmpty {
try visitor.visitSingularStringField(value: _storage._address, fieldNumber: 1)
}
if let v = _storage._range {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
if !self.address.isEmpty {
try visitor.visitSingularStringField(value: self.address, fieldNumber: 1)
}
if let v = self._range {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: TransparentAddressBlockFilter, rhs: TransparentAddressBlockFilter) -> Bool {
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
let _storage = _args.0
let rhs_storage = _args.1
if _storage._address != rhs_storage._address {return false}
if _storage._range != rhs_storage._range {return false}
return true
}
if !storagesAreEqual {return false}
}
if lhs.address != rhs.address {return false}
if lhs._range != rhs._range {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}

View File

@ -17,6 +17,7 @@ public enum SynchronizerError: Error {
case connectionFailed(message: String)
case generalError(message: String)
case maxRetryAttemptsReached(attempts: Int)
case connectionError(status: Int, message: String)
}
/**

View File

@ -117,8 +117,7 @@ public class SDKSynchronizer: Synchronizer {
- Throws: CompactBlockProcessorError when failures occur
*/
public func start(retry: Bool = false) throws {
let connectivityState = initializer.lightWalletService.resume()
LoggerProxy.info("service started with connectivityState: \(connectivityState)")
guard let processor = initializer.blockProcessor() else {
throw SynchronizerError.generalError(message: "compact block processor initialization failed")
}
@ -529,6 +528,8 @@ public class SDKSynchronizer: Synchronizer {
return SynchronizerError.generalError(message: message)
case .maxAttemptsReached(attempts: let attempts):
return SynchronizerError.maxRetryAttemptsReached(attempts: attempts)
case .grpcError(let statusCode, let message):
return SynchronizerError.connectionError(status: statusCode, message: message)
}
}
return error

View File

@ -8,7 +8,7 @@
import XCTest
@testable import ZcashLightClientKit
import SwiftGRPC
import GRPC
class LightWalletServiceTests: XCTestCase {
var service: LightWalletService!
@ -21,8 +21,6 @@ class LightWalletServiceTests: XCTestCase {
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
channel.shutdown()
}
/// FIXME: check whether this test is stil valid on in memory lwd implementatiojn

View File

@ -7,7 +7,7 @@
//
import XCTest
import SwiftGRPC
import GRPC
@testable import ZcashLightClientKit
@ -25,7 +25,6 @@ class ZcashLightClientKitTests: XCTestCase {
override func tearDown() {
super.tearDown()
service.channel.shutdown()
service = nil
latestBlockHeight = nil
}
@ -44,48 +43,23 @@ class ZcashLightClientKitTests: XCTestCase {
}
// /**
// LIGHTWALLETD KILLER TEST - DO NOT USE
// */
// func testBlockRangeService() {
//
// let expect = XCTestExpectation(description: self.debugDescription)
// let _ = try? service.getAllBlocksSinceSaplingLaunch(){ result in
// LoggerProxy.debug(result)
// expect.fulfill()
// XCTAssert(result.success)
// XCTAssertNotNil(result.resultData)
// }
// wait(for: [expect], timeout: 10)
// }
func testBlockRangeServiceTilLastest() {
let expectedCount: BlockHeight = 99
var count: BlockHeight = 0
let startHeight = latestBlockHeight - expectedCount
let endHeight = latestBlockHeight!
guard let call = try? service!.blockRange(startHeight: startHeight, endHeight: endHeight,result: {
result in
XCTAssert(result.success)
var blocks = [CompactBlock]()
guard let call = try? service!.blockRange(startHeight: startHeight, endHeight: endHeight, result: {
blocks.append($0)
count += 1
}) else {
XCTFail("failed to create getBlockRange( \(startHeight) ..<= \(endHeight)")
return
}
var blocks = [CompactBlock]()
while true {
guard let block = try? call.receive() else {
break
}
blocks.append(block)
count += 1
}
_ = try! call.status.wait()
XCTAssertEqual(expectedCount + 1, count)
}

View File

@ -20,87 +20,65 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Dispatch
import Foundation
import SwiftGRPC
import GRPC
import NIO
import NIOHTTP1
import SwiftProtobuf
@testable import ZcashLightClientKit
internal protocol DarksideStreamerDarksideGetIncomingTransactionsCall: ClientCallServerStreaming {
/// Do not call this directly, call `receive()` in the protocol extension below instead.
func _receive(timeout: DispatchTime) throws -> RawTransaction?
/// Call this to wait for a result. Nonblocking.
func receive(completion: @escaping (ResultOrRPCError<RawTransaction?>) -> Void) throws
/// Usage: instantiate DarksideStreamerClient, then call methods of this protocol to make API calls.
internal protocol DarksideStreamerClientProtocol {
func darksideGetIncomingTransactions(_ request: Empty, callOptions: CallOptions?, handler: @escaping (RawTransaction) -> Void) -> ServerStreamingCall<Empty, RawTransaction>
func darksideSetState(_ request: DarksideState, callOptions: CallOptions?) -> UnaryCall<DarksideState, Empty>
}
internal extension DarksideStreamerDarksideGetIncomingTransactionsCall {
/// Call this to wait for a result. Blocking.
func receive(timeout: DispatchTime = .distantFuture) throws -> RawTransaction? { return try self._receive(timeout: timeout) }
}
internal final class DarksideStreamerClient: GRPCClient, DarksideStreamerClientProtocol {
internal let channel: GRPCChannel
internal var defaultCallOptions: CallOptions
fileprivate final class DarksideStreamerDarksideGetIncomingTransactionsCallBase: ClientCallServerStreamingBase<Empty, RawTransaction>, DarksideStreamerDarksideGetIncomingTransactionsCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.DarksideStreamer/DarksideGetIncomingTransactions" }
}
internal protocol DarksideStreamerDarksideSetStateCall: ClientCallUnary {}
fileprivate final class DarksideStreamerDarksideSetStateCallBase: ClientCallUnaryBase<DarksideState, Empty>, DarksideStreamerDarksideSetStateCall {
override class var method: String { return "/cash.z.wallet.sdk.rpc.DarksideStreamer/DarksideSetState" }
}
/// Instantiate DarksideStreamerServiceClient, then call methods of this protocol to make API calls.
internal protocol DarksideStreamerService: ServiceClient {
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
func darksideGetIncomingTransactions(_ request: Empty, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> DarksideStreamerDarksideGetIncomingTransactionsCall
/// Synchronous. Unary.
func darksideSetState(_ request: DarksideState, metadata customMetadata: Metadata) throws -> Empty
/// Asynchronous. Unary.
@discardableResult
func darksideSetState(_ request: DarksideState, metadata customMetadata: Metadata, completion: @escaping (Empty?, CallResult) -> Void) throws -> DarksideStreamerDarksideSetStateCall
}
internal extension DarksideStreamerService {
/// Asynchronous. Server-streaming.
func darksideGetIncomingTransactions(_ request: Empty, completion: ((CallResult) -> Void)?) throws -> DarksideStreamerDarksideGetIncomingTransactionsCall {
return try self.darksideGetIncomingTransactions(request, metadata: self.metadata, completion: completion)
/// Creates a client for the cash.z.wallet.sdk.rpc.DarksideStreamer service.
///
/// - Parameters:
/// - channel: `GRPCChannel` to the service host.
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
internal init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
self.channel = channel
self.defaultCallOptions = defaultCallOptions
}
/// Synchronous. Unary.
func darksideSetState(_ request: DarksideState) throws -> Empty {
return try self.darksideSetState(request, metadata: self.metadata)
/// Return the list of transactions that have been submitted (via SendTransaction).
///
/// - Parameters:
/// - request: Request to send to DarksideGetIncomingTransactions.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - handler: A closure called when each response is received from the server.
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
internal func darksideGetIncomingTransactions(_ request: Empty, callOptions: CallOptions? = nil, handler: @escaping (RawTransaction) -> Void) -> ServerStreamingCall<Empty, RawTransaction> {
return self.makeServerStreamingCall(path: "/cash.z.wallet.sdk.rpc.DarksideStreamer/DarksideGetIncomingTransactions",
request: request,
callOptions: callOptions ?? self.defaultCallOptions,
handler: handler)
}
/// Asynchronous. Unary.
@discardableResult
func darksideSetState(_ request: DarksideState, completion: @escaping (Empty?, CallResult) -> Void) throws -> DarksideStreamerDarksideSetStateCall {
return try self.darksideSetState(request, metadata: self.metadata, completion: completion)
/// Set the information that GetLightdInfo returns, except that chainName specifies
/// a file of blocks within testdata/darkside that GetBlock will return.
///
/// - Parameters:
/// - request: Request to send to DarksideSetState.
/// - callOptions: Call options; `self.defaultCallOptions` is used if `nil`.
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
internal func darksideSetState(_ request: DarksideState, callOptions: CallOptions? = nil) -> UnaryCall<DarksideState, Empty> {
return self.makeUnaryCall(path: "/cash.z.wallet.sdk.rpc.DarksideStreamer/DarksideSetState",
request: request,
callOptions: callOptions ?? self.defaultCallOptions)
}
}
internal final class DarksideStreamerServiceClient: ServiceClientBase, DarksideStreamerService {
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
internal func darksideGetIncomingTransactions(_ request: Empty, metadata customMetadata: Metadata, completion: ((CallResult) -> Void)?) throws -> DarksideStreamerDarksideGetIncomingTransactionsCall {
return try DarksideStreamerDarksideGetIncomingTransactionsCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
/// Synchronous. Unary.
internal func darksideSetState(_ request: DarksideState, metadata customMetadata: Metadata) throws -> Empty {
return try DarksideStreamerDarksideSetStateCallBase(channel)
.run(request: request, metadata: customMetadata)
}
/// Asynchronous. Unary.
@discardableResult
internal func darksideSetState(_ request: DarksideState, metadata customMetadata: Metadata, completion: @escaping (Empty?, CallResult) -> Void) throws -> DarksideStreamerDarksideSetStateCall {
return try DarksideStreamerDarksideSetStateCallBase(channel)
.start(request: request, metadata: customMetadata, completion: completion)
}
}
// Provides conformance to `GRPCPayload` for request and response messages
extension Empty: GRPCProtobufPayload {}
extension RawTransaction: GRPCProtobufPayload {}
extension DarksideState: GRPCProtobufPayload {}

View File

@ -3,7 +3,7 @@
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: darkside.proto
//
// For information on using the generated types, please see the documenation:
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Copyright (c) 2019-2020 The Zcash developers
@ -16,7 +16,7 @@ import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that your are building against the same version of the API
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}

View File

@ -0,0 +1,625 @@
// DO NOT EDIT.
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: service.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Copyright (c) 2019-2020 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
/// A BlockID message contains identifiers to select a block: a height or a
/// hash. Specification by hash is not implemented, but may be in the future.
struct BlockID {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var height: UInt64 = 0
var hash: Data = SwiftProtobuf.Internal.emptyData
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// BlockRange specifies a series of blocks from start to end inclusive.
/// Both BlockIDs must be heights; specification by hash is not yet supported.
struct BlockRange {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var start: BlockID {
get {return _start ?? BlockID()}
set {_start = newValue}
}
/// Returns true if `start` has been explicitly set.
var hasStart: Bool {return self._start != nil}
/// Clears the value of `start`. Subsequent reads from it will return its default value.
mutating func clearStart() {self._start = nil}
var end: BlockID {
get {return _end ?? BlockID()}
set {_end = newValue}
}
/// Returns true if `end` has been explicitly set.
var hasEnd: Bool {return self._end != nil}
/// Clears the value of `end`. Subsequent reads from it will return its default value.
mutating func clearEnd() {self._end = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _start: BlockID? = nil
fileprivate var _end: BlockID? = nil
}
/// A TxFilter contains the information needed to identify a particular
/// transaction: either a block and an index, or a direct transaction hash.
/// Currently, only specification by hash is supported.
struct TxFilter {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var block: BlockID {
get {return _block ?? BlockID()}
set {_block = newValue}
}
/// Returns true if `block` has been explicitly set.
var hasBlock: Bool {return self._block != nil}
/// Clears the value of `block`. Subsequent reads from it will return its default value.
mutating func clearBlock() {self._block = nil}
var index: UInt64 = 0
var hash: Data = SwiftProtobuf.Internal.emptyData
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _block: BlockID? = nil
}
/// RawTransaction contains the complete transaction data. It also optionally includes
/// the block height in which the transaction was included
struct RawTransaction {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var data: Data = SwiftProtobuf.Internal.emptyData
var height: UInt64 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// A SendResponse encodes an error code and a string. It is currently used
/// only by SendTransaction(). If error code is zero, the operation was
/// successful; if non-zero, it and the message specify the failure.
struct SendResponse {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var errorCode: Int32 = 0
var errorMessage: String = String()
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// Chainspec is a placeholder to allow specification of a particular chain fork.
struct ChainSpec {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// Empty is for gRPCs that take no arguments, currently only GetLightdInfo.
struct Empty {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// LightdInfo returns various information about this lightwalletd instance
/// and the state of the blockchain.
struct LightdInfo {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var version: String = String()
var vendor: String = String()
var taddrSupport: Bool = false
var chainName: String = String()
var saplingActivationHeight: UInt64 = 0
var consensusBranchID: String = String()
var blockHeight: UInt64 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// TransparentAddressBlockFilter restricts the results to the given address
/// or block range.
struct TransparentAddressBlockFilter {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var address: String = String()
var range: BlockRange {
get {return _range ?? BlockRange()}
set {_range = newValue}
}
/// Returns true if `range` has been explicitly set.
var hasRange: Bool {return self._range != nil}
/// Clears the value of `range`. Subsequent reads from it will return its default value.
mutating func clearRange() {self._range = nil}
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _range: BlockRange? = nil
}
/// Duration is currently used only for testing, so that the Ping rpc
/// can simulate a delay, to create many simultaneous connections. Units
/// are microseconds.
struct Duration {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var intervalUs: Int64 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
/// PingResponse is used to indicate concurrency, how many Ping rpcs
/// are executing upon entry and upon exit (after the delay).
struct PingResponse {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var entry: Int64 = 0
var exit: Int64 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "cash.z.wallet.sdk.rpc"
extension BlockID: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".BlockID"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "height"),
2: .same(proto: "hash"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularUInt64Field(value: &self.height)
case 2: try decoder.decodeSingularBytesField(value: &self.hash)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.height != 0 {
try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 1)
}
if !self.hash.isEmpty {
try visitor.visitSingularBytesField(value: self.hash, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: BlockID, rhs: BlockID) -> Bool {
if lhs.height != rhs.height {return false}
if lhs.hash != rhs.hash {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension BlockRange: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".BlockRange"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "start"),
2: .same(proto: "end"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &self._start)
case 2: try decoder.decodeSingularMessageField(value: &self._end)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._start {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if let v = self._end {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: BlockRange, rhs: BlockRange) -> Bool {
if lhs._start != rhs._start {return false}
if lhs._end != rhs._end {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension TxFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".TxFilter"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "block"),
2: .same(proto: "index"),
3: .same(proto: "hash"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularMessageField(value: &self._block)
case 2: try decoder.decodeSingularUInt64Field(value: &self.index)
case 3: try decoder.decodeSingularBytesField(value: &self.hash)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if let v = self._block {
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
}
if self.index != 0 {
try visitor.visitSingularUInt64Field(value: self.index, fieldNumber: 2)
}
if !self.hash.isEmpty {
try visitor.visitSingularBytesField(value: self.hash, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: TxFilter, rhs: TxFilter) -> Bool {
if lhs._block != rhs._block {return false}
if lhs.index != rhs.index {return false}
if lhs.hash != rhs.hash {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension RawTransaction: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".RawTransaction"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "data"),
2: .same(proto: "height"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularBytesField(value: &self.data)
case 2: try decoder.decodeSingularUInt64Field(value: &self.height)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.data.isEmpty {
try visitor.visitSingularBytesField(value: self.data, fieldNumber: 1)
}
if self.height != 0 {
try visitor.visitSingularUInt64Field(value: self.height, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: RawTransaction, rhs: RawTransaction) -> Bool {
if lhs.data != rhs.data {return false}
if lhs.height != rhs.height {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension SendResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".SendResponse"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "errorCode"),
2: .same(proto: "errorMessage"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularInt32Field(value: &self.errorCode)
case 2: try decoder.decodeSingularStringField(value: &self.errorMessage)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.errorCode != 0 {
try visitor.visitSingularInt32Field(value: self.errorCode, fieldNumber: 1)
}
if !self.errorMessage.isEmpty {
try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: SendResponse, rhs: SendResponse) -> Bool {
if lhs.errorCode != rhs.errorCode {return false}
if lhs.errorMessage != rhs.errorMessage {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension ChainSpec: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".ChainSpec"
static let _protobuf_nameMap = SwiftProtobuf._NameMap()
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let _ = try decoder.nextFieldNumber() {
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: ChainSpec, rhs: ChainSpec) -> Bool {
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Empty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".Empty"
static let _protobuf_nameMap = SwiftProtobuf._NameMap()
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let _ = try decoder.nextFieldNumber() {
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: Empty, rhs: Empty) -> Bool {
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension LightdInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".LightdInfo"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "version"),
2: .same(proto: "vendor"),
3: .same(proto: "taddrSupport"),
4: .same(proto: "chainName"),
5: .same(proto: "saplingActivationHeight"),
6: .same(proto: "consensusBranchId"),
7: .same(proto: "blockHeight"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularStringField(value: &self.version)
case 2: try decoder.decodeSingularStringField(value: &self.vendor)
case 3: try decoder.decodeSingularBoolField(value: &self.taddrSupport)
case 4: try decoder.decodeSingularStringField(value: &self.chainName)
case 5: try decoder.decodeSingularUInt64Field(value: &self.saplingActivationHeight)
case 6: try decoder.decodeSingularStringField(value: &self.consensusBranchID)
case 7: try decoder.decodeSingularUInt64Field(value: &self.blockHeight)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.version.isEmpty {
try visitor.visitSingularStringField(value: self.version, fieldNumber: 1)
}
if !self.vendor.isEmpty {
try visitor.visitSingularStringField(value: self.vendor, fieldNumber: 2)
}
if self.taddrSupport != false {
try visitor.visitSingularBoolField(value: self.taddrSupport, fieldNumber: 3)
}
if !self.chainName.isEmpty {
try visitor.visitSingularStringField(value: self.chainName, fieldNumber: 4)
}
if self.saplingActivationHeight != 0 {
try visitor.visitSingularUInt64Field(value: self.saplingActivationHeight, fieldNumber: 5)
}
if !self.consensusBranchID.isEmpty {
try visitor.visitSingularStringField(value: self.consensusBranchID, fieldNumber: 6)
}
if self.blockHeight != 0 {
try visitor.visitSingularUInt64Field(value: self.blockHeight, fieldNumber: 7)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: LightdInfo, rhs: LightdInfo) -> Bool {
if lhs.version != rhs.version {return false}
if lhs.vendor != rhs.vendor {return false}
if lhs.taddrSupport != rhs.taddrSupport {return false}
if lhs.chainName != rhs.chainName {return false}
if lhs.saplingActivationHeight != rhs.saplingActivationHeight {return false}
if lhs.consensusBranchID != rhs.consensusBranchID {return false}
if lhs.blockHeight != rhs.blockHeight {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension TransparentAddressBlockFilter: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".TransparentAddressBlockFilter"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "address"),
2: .same(proto: "range"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularStringField(value: &self.address)
case 2: try decoder.decodeSingularMessageField(value: &self._range)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.address.isEmpty {
try visitor.visitSingularStringField(value: self.address, fieldNumber: 1)
}
if let v = self._range {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: TransparentAddressBlockFilter, rhs: TransparentAddressBlockFilter) -> Bool {
if lhs.address != rhs.address {return false}
if lhs._range != rhs._range {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Duration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".Duration"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "intervalUs"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularInt64Field(value: &self.intervalUs)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.intervalUs != 0 {
try visitor.visitSingularInt64Field(value: self.intervalUs, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: Duration, rhs: Duration) -> Bool {
if lhs.intervalUs != rhs.intervalUs {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension PingResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".PingResponse"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "entry"),
2: .same(proto: "exit"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1: try decoder.decodeSingularInt64Field(value: &self.entry)
case 2: try decoder.decodeSingularInt64Field(value: &self.exit)
default: break
}
}
}
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.entry != 0 {
try visitor.visitSingularInt64Field(value: self.entry, fieldNumber: 1)
}
if self.exit != 0 {
try visitor.visitSingularInt64Field(value: self.exit, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
static func ==(lhs: PingResponse, rhs: PingResponse) -> Bool {
if lhs.entry != rhs.entry {return false}
if lhs.exit != rhs.exit {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -7,17 +7,17 @@
import Foundation
import ZcashLightClientKit
import SwiftGRPC
import GRPC
class DarksideWalletService: LightWalletService {
var channel: Channel
init() {
let channel = ChannelProvider().channel()
self.channel = channel
self.service = LightWalletGRPCService(channel: channel)
self.darksideService = DarksideStreamerServiceClient(channel: channel)
self.darksideService = DarksideStreamerClient(channel: channel)
}
var service: LightWalletGRPCService
var darksideService: DarksideStreamerServiceClient
var darksideService: DarksideStreamerClient
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
service.latestBlockHeight(result: result)
@ -48,14 +48,14 @@ class DarksideWalletService: LightWalletService {
darksideState.latestHeight = UInt64(latestHeight)
darksideState.reorgHeight = UInt64(reOrgHeight)
_ = try darksideService.darksideSetState(darksideState, metadata: Metadata())
_ = try darksideService.darksideSetState(darksideState).response.wait()
}
func setLatestHeight(_ latestHeight: BlockHeight) throws {
var state = DarksideState()
state.reorgHeight = 0
state.latestHeight = UInt64(latestHeight)
_ = try darksideService.darksideSetState(state, metadata: Metadata())
var darksideState = DarksideState()
darksideState.reorgHeight = 0
darksideState.latestHeight = UInt64(latestHeight)
_ = try darksideService.darksideSetState(darksideState).response.wait()
}

View File

@ -7,7 +7,7 @@
//
import Foundation
import SwiftGRPC
import GRPC
import SwiftProtobuf
@testable import ZcashLightClientKit

View File

@ -7,19 +7,23 @@
//
import Foundation
import SwiftGRPC
import GRPC
import ZcashLightClientKit
import XCTest
import NIO
class LightWalletEndpointBuilder {
static var `default`: LightWalletEndpoint {
LightWalletEndpoint(address: "localhost", port: "9067", secure: false)
LightWalletEndpoint(address: Constants.address, port: 9067, secure: false)
}
}
class ChannelProvider {
func channel(secure: Bool = false) -> SwiftGRPC.Channel {
Channel(address: Constants.address, secure: secure)
func channel(secure: Bool = false) -> GRPCChannel {
let endpoint = LightWalletEndpointBuilder.default
let configuration = ClientConnection.Configuration(target: .hostAndPort(endpoint.host, endpoint.port), eventLoopGroup: MultiThreadedEventLoopGroup(numberOfThreads: 1), tls: secure ? .init() : nil)
return ClientConnection(configuration: configuration)
}
}