2019-10-18 11:45:19 -07:00
//
// S t u b s . s w i f t
// Z c a s h L i g h t C l i e n t K i t T e s t s
//
// C r e a t e d b y F r a n c i s c o G i n d r e o n 1 8 / 0 9 / 2 0 1 9 .
// C o p y r i g h t © 2 0 1 9 E l e c t r i c C o i n C o m p a n y . A l l r i g h t s r e s e r v e d .
//
import Foundation
2020-04-09 15:25:43 -07:00
import GRPC
2019-12-16 14:25:45 -08:00
import SwiftProtobuf
2019-11-14 06:38:54 -08:00
@ testable import ZcashLightClientKit
2019-10-18 11:45:19 -07:00
2019-12-16 14:25:45 -08:00
class AwfulLightWalletService : MockLightWalletService {
override func latestBlockHeight ( ) throws -> BlockHeight {
2020-08-10 15:19:59 -07:00
throw LightWalletServiceError . criticalError
2019-10-18 11:45:19 -07:00
}
2019-12-16 14:25:45 -08:00
override func blockRange ( _ range : CompactBlockRange ) throws -> [ ZcashCompactBlock ] {
2019-10-18 11:45:19 -07:00
throw LightWalletServiceError . invalidBlock
}
2019-12-16 14:25:45 -08:00
override func latestBlockHeight ( result : @ escaping ( Result < BlockHeight , LightWalletServiceError > ) -> Void ) {
2019-10-18 11:45:19 -07:00
DispatchQueue . main . asyncAfter ( deadline : . now ( ) + 0.5 ) {
2020-08-10 15:19:59 -07:00
result ( . failure ( LightWalletServiceError . invalidBlock ) )
2019-10-18 11:45:19 -07:00
}
}
2020-02-26 08:54:48 -08:00
override func blockRange ( _ range : CompactBlockRange , result : @ escaping ( Result < [ ZcashCompactBlock ] , LightWalletServiceError > ) -> Void ) {
2019-10-18 11:45:19 -07:00
DispatchQueue . main . asyncAfter ( deadline : . now ( ) + 0.5 ) {
2020-08-10 15:19:59 -07:00
result ( . failure ( LightWalletServiceError . invalidBlock ) )
2019-10-18 11:45:19 -07:00
}
}
2019-12-16 14:25:45 -08:00
override func submit ( spendTransaction : Data , result : @ escaping ( Result < LightWalletServiceResponse , LightWalletServiceError > ) -> Void ) {
2019-12-03 07:19:44 -08:00
DispatchQueue . main . asyncAfter ( deadline : . now ( ) + 0.5 ) {
2020-08-10 15:19:59 -07:00
result ( . failure ( LightWalletServiceError . invalidBlock ) )
2019-12-03 07:19:44 -08:00
}
}
/* *
Submits a raw transaction over lightwalletd . Blocking
*/
2019-12-16 14:25:45 -08:00
override func submit ( spendTransaction : Data ) throws -> LightWalletServiceResponse {
2020-08-10 15:19:59 -07:00
throw LightWalletServiceError . invalidBlock
2019-12-03 07:19:44 -08:00
}
2019-10-18 11:45:19 -07:00
}
2019-11-14 06:38:54 -08:00
2019-12-16 14:25:45 -08:00
class SlightlyBadLightWalletService : MockLightWalletService {
override func submit ( spendTransaction : Data , result : @ escaping ( Result < LightWalletServiceResponse , LightWalletServiceError > ) -> Void ) {
DispatchQueue . main . asyncAfter ( deadline : . now ( ) + 0.5 ) {
result ( . success ( LightWalletServiceMockResponse . error ) )
}
}
/* *
Submits a raw transaction over lightwalletd . Blocking
*/
override func submit ( spendTransaction : Data ) throws -> LightWalletServiceResponse {
LightWalletServiceMockResponse . error
}
}
extension LightWalletServiceMockResponse {
static var error : LightWalletServiceMockResponse {
LightWalletServiceMockResponse ( errorCode : - 100 , errorMessage : " Ohhh this is bad dude, really bad, you lost all your internet money " , unknownFields : UnknownStorage ( ) )
}
static var success : LightWalletServiceMockResponse {
LightWalletServiceMockResponse ( errorCode : 0 , errorMessage : " " , unknownFields : UnknownStorage ( ) )
}
}
2019-11-14 06:38:54 -08:00
class MockRustBackend : ZcashRustBackendWelding {
2021-05-28 15:45:18 -07:00
2021-04-19 10:16:24 -07:00
static func getNearestRewindHeight ( dbData : URL , height : Int32 ) -> Int32 {
- 1
}
2021-04-08 10:18:16 -07:00
static func clearUtxos ( dbData : URL , address : String , sinceHeight : BlockHeight ) throws -> Int32 {
- 1
}
2021-04-02 15:18:16 -07:00
static func initAccountsTable ( dbData : URL , uvks : [ UnifiedViewingKey ] ) throws -> Bool {
false
}
static func getVerifiedTransparentBalance ( dbData : URL , address : String ) throws -> Int64 {
- 1
}
static func getTransparentBalance ( dbData : URL , address : String ) throws -> Int64 {
- 1
}
static func putUnspentTransparentOutput ( dbData : URL , address : String , txid : [ UInt8 ] , index : Int , script : [ UInt8 ] , value : Int64 , height : BlockHeight ) throws -> Bool {
false
}
static func downloadedUtxoBalance ( dbData : URL , address : String ) throws -> WalletBalance {
throw RustWeldingError . genericError ( message : " unimplemented " )
}
static func createToAddress ( dbData : URL , account : Int32 , extsk : String , to : String , value : Int64 , memo : String ? , spendParamsPath : String , outputParamsPath : String ) -> Int64 {
- 1
}
static func shieldFunds ( dbCache : URL , dbData : URL , account : Int32 , tsk : String , extsk : String , memo : String ? , spendParamsPath : String , outputParamsPath : String ) -> Int64 {
- 1
}
static func deriveTransparentAddressFromSeed ( seed : [ UInt8 ] , account : Int , index : Int ) throws -> String ? {
throw KeyDerivationErrors . unableToDerive
}
static func deriveTransparentPrivateKeyFromSeed ( seed : [ UInt8 ] , account : Int , index : Int ) throws -> String ? {
throw KeyDerivationErrors . unableToDerive
}
static func deriveTransparentAddressFromSecretKey ( _ tsk : String ) throws -> String ? {
throw KeyDerivationErrors . unableToDerive
}
static func derivedTransparentAddressFromPublicKey ( _ pubkey : String ) throws -> String {
throw KeyDerivationErrors . unableToDerive
}
static func deriveUnifiedViewingKeyFromSeed ( _ seed : [ UInt8 ] , numberOfAccounts : Int ) throws -> [ UnifiedViewingKey ] {
throw KeyDerivationErrors . unableToDerive
}
2021-02-22 11:43:28 -08:00
static func isValidExtendedFullViewingKey ( _ key : String ) throws -> Bool {
false
}
2020-12-11 13:07:51 -08:00
static func deriveTransparentPrivateKeyFromSeed ( seed : [ UInt8 ] ) throws -> String ? {
nil
}
2020-10-14 15:50:26 -07:00
static func initAccountsTable ( dbData : URL , exfvks : [ String ] ) throws -> Bool {
false
}
2020-10-09 13:58:36 -07:00
static func deriveTransparentAddressFromSeed ( seed : [ UInt8 ] ) throws -> String ? {
nil
}
static func deriveExtendedFullViewingKeys ( seed : [ UInt8 ] , accounts : Int32 ) throws -> [ String ] ? {
nil
}
static func deriveExtendedSpendingKeys ( seed : [ UInt8 ] , accounts : Int32 ) throws -> [ String ] ? {
nil
}
static func deriveShieldedAddressFromSeed ( seed : [ UInt8 ] , accountIndex : Int32 ) throws -> String ? {
nil
}
static func deriveShieldedAddressFromViewingKey ( _ extfvk : String ) throws -> String ? {
nil
}
2020-02-26 08:54:48 -08:00
2020-06-09 17:23:46 -07:00
static func consensusBranchIdFor ( height : Int32 ) throws -> Int32 {
- 1
}
2019-11-14 06:38:54 -08:00
static var mockDataDb = false
static var mockAcounts = false
static var mockError : RustWeldingError ?
static var mockLastError : String ?
static var mockAccounts : [ String ] ?
static var mockAddresses : [ String ] ?
static var mockBalance : Int64 ?
static var mockVerifiedBalance : Int64 ?
static var mockMemo : String ?
static var mockSentMemo : String ?
static var mockValidateCombinedChainSuccessRate : Float ?
static var mockValidateCombinedChainFailAfterAttempts : Int ?
static var mockValidateCombinedChainKeepFailing = false
static var mockValidateCombinedChainFailureHeight : BlockHeight = 0
static var mockScanblocksSuccessRate : Float ?
2019-12-03 09:11:24 -08:00
static var mockCreateToAddress : Int64 ?
2019-11-14 06:38:54 -08:00
static var rustBackend = ZcashRustBackend . self
static func lastError ( ) -> RustWeldingError ? {
mockError ? ? rustBackend . lastError ( )
}
static func getLastError ( ) -> String ? {
mockLastError ? ? rustBackend . getLastError ( )
}
2020-02-26 08:54:48 -08:00
static func isValidShieldedAddress ( _ address : String ) throws -> Bool {
true
}
static func isValidTransparentAddress ( _ address : String ) throws -> Bool {
true
}
2019-11-14 06:38:54 -08:00
static func initDataDb ( dbData : URL ) throws {
if ! mockDataDb {
try rustBackend . initDataDb ( dbData : dbData )
}
}
static func initAccountsTable ( dbData : URL , seed : [ UInt8 ] , accounts : Int32 ) -> [ String ] ? {
mockAccounts ? ? rustBackend . initAccountsTable ( dbData : dbData , seed : seed , accounts : accounts )
}
static func initBlocksTable ( dbData : URL , height : Int32 , hash : String , time : UInt32 , saplingTree : String ) throws {
if ! mockDataDb {
try rustBackend . initBlocksTable ( dbData : dbData , height : height , hash : hash , time : time , saplingTree : saplingTree )
}
}
static func getAddress ( dbData : URL , account : Int32 ) -> String ? {
mockAddresses ? [ Int ( account ) ] ? ? rustBackend . getAddress ( dbData : dbData , account : account )
}
static func getBalance ( dbData : URL , account : Int32 ) -> Int64 {
mockBalance ? ? rustBackend . getBalance ( dbData : dbData , account : account )
}
static func getVerifiedBalance ( dbData : URL , account : Int32 ) -> Int64 {
mockVerifiedBalance ? ? rustBackend . getVerifiedBalance ( dbData : dbData , account : account )
}
static func getReceivedMemoAsUTF8 ( dbData : URL , idNote : Int64 ) -> String ? {
mockMemo ? ? rustBackend . getReceivedMemoAsUTF8 ( dbData : dbData , idNote : idNote )
}
static func getSentMemoAsUTF8 ( dbData : URL , idNote : Int64 ) -> String ? {
mockSentMemo ? ? getSentMemoAsUTF8 ( dbData : dbData , idNote : idNote )
}
static func validateCombinedChain ( dbCache : URL , dbData : URL ) -> Int32 {
if let rate = self . mockValidateCombinedChainSuccessRate {
if shouldSucceed ( successRate : rate ) {
return validationResult ( dbCache : dbCache , dbData : dbData )
} else {
return Int32 ( mockValidateCombinedChainFailureHeight )
}
} else if let attempts = self . mockValidateCombinedChainFailAfterAttempts {
self . mockValidateCombinedChainFailAfterAttempts = attempts - 1
if attempts > 0 {
return validationResult ( dbCache : dbCache , dbData : dbData )
} else {
if attempts = = 0 {
return Int32 ( mockValidateCombinedChainFailureHeight )
} else if attempts < 0 && mockValidateCombinedChainKeepFailing {
return Int32 ( mockValidateCombinedChainFailureHeight )
} else {
return validationResult ( dbCache : dbCache , dbData : dbData )
}
}
}
return rustBackend . validateCombinedChain ( dbCache : dbCache , dbData : dbData )
}
private static func validationResult ( dbCache : URL , dbData : URL ) -> Int32 {
if mockDataDb {
return - 1
} else {
return rustBackend . validateCombinedChain ( dbCache : dbCache , dbData : dbData )
}
}
static func rewindToHeight ( dbData : URL , height : Int32 ) -> Bool {
mockDataDb ? true : rustBackend . rewindToHeight ( dbData : dbData , height : height )
}
2021-05-28 15:45:18 -07:00
static func scanBlocks ( dbCache : URL , dbData : URL , limit : UInt32 ) -> Bool {
2019-11-14 06:38:54 -08:00
if let rate = mockScanblocksSuccessRate {
if shouldSucceed ( successRate : rate ) {
return mockDataDb ? true : rustBackend . scanBlocks ( dbCache : dbCache , dbData : dbData )
} else {
return false
}
}
return rustBackend . scanBlocks ( dbCache : dbCache , dbData : dbData )
}
2020-06-09 17:23:46 -07:00
static func createToAddress ( dbData : URL , account : Int32 , extsk : String , consensusBranchId : Int32 , to : String , value : Int64 , memo : String ? , spendParamsPath : String , outputParamsPath : String ) -> Int64 {
2021-04-02 15:18:16 -07:00
// m o c k C r e a t e T o A d d r e s s ? ? r u s t B a c k e n d . c r e a t e T o A d d r e s s ( d b D a t a : d b D a t a , a c c o u n t : a c c o u n t , e x t s k : e x t s k , c o n s e n s u s B r a n c h I d : c o n s e n s u s B r a n c h I d , t o : t o , v a l u e : v a l u e , m e m o : m e m o , s p e n d P a r a m s P a t h : s p e n d P a r a m s P a t h , o u t p u t P a r a m s P a t h : o u t p u t P a r a m s P a t h )
- 1
2019-11-14 06:38:54 -08:00
}
static func shouldSucceed ( successRate : Float ) -> Bool {
let random = Float . random ( in : 0.0 . . . 1.0 )
return random <= successRate
}
2020-02-26 08:54:48 -08:00
static func deriveExtendedFullViewingKey ( _ spendingKey : String ) throws -> String ? {
nil
}
static func deriveExtendedFullViewingKeys ( seed : String , accounts : Int32 ) throws -> [ String ] ? {
nil
}
static func deriveExtendedSpendingKeys ( seed : String , accounts : Int32 ) throws -> [ String ] ? {
nil
}
2020-04-06 08:54:31 -07:00
static func decryptAndStoreTransaction ( dbData : URL , tx : [ UInt8 ] ) -> Bool {
false
}
2019-11-14 06:38:54 -08:00
}