Merge pull request #291 from zcash/network-agnostic-build
Network agnostic build
This commit is contained in:
commit
7f41511855
|
@ -1,6 +1,6 @@
|
||||||
language: swift
|
language: swift
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode12.2
|
osx_image: xcode12.5
|
||||||
xcode_workspace: ./Example/ZcashLightClientSample/ZcashLightClientSample.xcworkspace
|
xcode_workspace: ./Example/ZcashLightClientSample/ZcashLightClientSample.xcworkspace
|
||||||
xcode_scheme: ZcashLightClientSample
|
xcode_scheme: ZcashLightClientSample
|
||||||
xcode_destination: platform=iOS Simulator,OS=14.2,name=iPhone 8
|
xcode_destination: platform=iOS Simulator,OS=14.2,name=iPhone 8
|
||||||
|
@ -9,9 +9,6 @@ addons:
|
||||||
packages:
|
packages:
|
||||||
- rustup-init
|
- rustup-init
|
||||||
- sourcery
|
- sourcery
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- ZCASH_NETWORK_ENVIRONMENT: TESTNET
|
|
||||||
install:
|
install:
|
||||||
- ${TRAVIS_BUILD_DIR}/Scripts/travis/rust_setup.sh
|
- ${TRAVIS_BUILD_DIR}/Scripts/travis/rust_setup.sh
|
||||||
- ${TRAVIS_BUILD_DIR}/Scripts/travis/ZcashLightClientSample_setup.sh
|
- ${TRAVIS_BUILD_DIR}/Scripts/travis/ZcashLightClientSample_setup.sh
|
||||||
|
@ -19,4 +16,4 @@ install:
|
||||||
- curl https://z.cash/downloads/sapling-output.params > ${TRAVIS_BUILD_DIR}/ZcashLightClientKitTests/sapling-spend.params
|
- curl https://z.cash/downloads/sapling-output.params > ${TRAVIS_BUILD_DIR}/ZcashLightClientKitTests/sapling-spend.params
|
||||||
script:
|
script:
|
||||||
- swiftlint
|
- swiftlint
|
||||||
- travis_wait 60 xcodebuild -quiet -UseModernBuildSystem=NO -workspace ./Example/ZcashLightClientSample/ZcashLightClientSample.xcworkspace -scheme ZcashLightClientSample -destination platform\=iOS\ Simulator,OS\=14.2,name\=iPhone\ 8 build
|
- travis_wait 60 xcodebuild -quiet -UseModernBuildSystem=NO -workspace ./Example/ZcashLightClientSample/ZcashLightClientSample.xcworkspace -scheme ZcashLightClientSample -destination platform\=iOS\ Simulator,OS\=14.5,name\=iPhone\ 8 build
|
||||||
|
|
|
@ -703,7 +703,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libzcashlc"
|
name = "libzcashlc"
|
||||||
version = "0.0.6"
|
version = "0.0.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58",
|
"base58",
|
||||||
"bitvec 0.18.5",
|
"bitvec 0.18.5",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "libzcashlc"
|
name = "libzcashlc"
|
||||||
version = "0.0.6"
|
version = "0.0.7"
|
||||||
authors = ["Jack Grigg <jack@z.cash>",
|
authors = ["Jack Grigg <jack@z.cash>",
|
||||||
"Francisco Gindre <francisco@z.cash>",
|
"Francisco Gindre <francisco@z.cash>",
|
||||||
]
|
]
|
||||||
|
@ -50,5 +50,5 @@ zcash_primitives = {git = "https://github.com/nuttycom/librustzcash", branch = "
|
||||||
zcash_proofs = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa" }
|
zcash_proofs = {git = "https://github.com/nuttycom/librustzcash", branch = "autoshield-poc-daa" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
mainnet = ["zcash_client_sqlite/mainnet", "zcash_client_backend/transparent-inputs", "zcash_primitives/transparent-inputs"]
|
mainnet = ["zcash_client_sqlite/mainnet"]
|
||||||
testnet = ["zcash_client_backend/transparent-inputs", "zcash_primitives/transparent-inputs"]
|
testnet = []
|
|
@ -0,0 +1,99 @@
|
||||||
|
//
|
||||||
|
// DerivatioToolTestnetTests.swift
|
||||||
|
// ZcashLightClientKit-Unit-DerivationToolTests
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/26/21.
|
||||||
|
//
|
||||||
|
// swift-format-ignore-file
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
|
class DerivatioToolTestnetTests: XCTestCase {
|
||||||
|
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" //TODO: Parameterize this from environment?
|
||||||
|
var seedData: Data = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==")!
|
||||||
|
let testRecipientAddress = "ztestsapling1475xtm56czrzmleqzzlu4cxvjjfsy2p6rv78q07232cpsx5ee52k0mn5jyndq09mampkgvrxnwg" //TODO: Parameterize this from environment
|
||||||
|
|
||||||
|
let expectedSpendingKey = "secret-extended-key-test1qdxykmuaqqqqpqqg3x5c02p4rhw0rtszr8ln4xl7g6wg6qzsqgn445qsu3cq4vd6lk8xce3d4jw7s8ln5yjp6fqv2g0nzue2hc0kv5t004vklvlenncscq9flwh5vf5qnv0hnync72n7gjn70u47765v3kyrxytx50g730svvmhhlazn5rj8mshh470fkrmzg4xarhrqlygg8f486307ujhndwhsw2h7ddzf89k3534aeu0ypz2tjgrzlcqtat380vhe8awm03f58cqe49swv"
|
||||||
|
|
||||||
|
let expectedViewingKey = "zxviewtestsapling1qdxykmuaqqqqpqqg3x5c02p4rhw0rtszr8ln4xl7g6wg6qzsqgn445qsu3cq4vd6l5smlqrckkl2x5rnrauzc4gp665q3zyw0qf2sfdsx5wpp832htfavqk72uchuuvq2dpmgk8jfaza5t5l56u66fpx0sr8ewp9s3wj2txavmhhlazn5rj8mshh470fkrmzg4xarhrqlygg8f486307ujhndwhsw2h7ddzf89k3534aeu0ypz2tjgrzlcqtat380vhe8awm03f58cqgegsaj"
|
||||||
|
|
||||||
|
let derivationTool = DerivationTool(networkType: NetworkType.testnet)
|
||||||
|
let expectedTransparentAddress = "tmXuTnE11JojToagTqxXUn6KvdxDE3iLKbp"
|
||||||
|
func testDeriveViewingKeysFromSeed() throws {
|
||||||
|
let accounts: Int = 1
|
||||||
|
let seedBytes = [UInt8](seedData)
|
||||||
|
let viewingKeys = try derivationTool.deriveViewingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
||||||
|
|
||||||
|
XCTAssertEqual(viewingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
||||||
|
|
||||||
|
guard let viewingKey = viewingKeys.first else {
|
||||||
|
XCTFail("no viewing key generated")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
XCTAssertEqual(expectedViewingKey, viewingKey)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveViewingKeyFromSpendingKeys() throws {
|
||||||
|
XCTAssertEqual(expectedViewingKey, try derivationTool.deriveViewingKey(spendingKey: expectedSpendingKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveSpendingKeysFromSeed() throws {
|
||||||
|
let accounts: Int = 1
|
||||||
|
let seedBytes = [UInt8](seedData)
|
||||||
|
|
||||||
|
let spendingKeys = try derivationTool.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
||||||
|
XCTAssertEqual(spendingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
||||||
|
|
||||||
|
guard let spendingKey = spendingKeys.first else {
|
||||||
|
XCTFail("no viewing key generated")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
XCTAssertEqual(expectedSpendingKey, spendingKey)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveShieldedAddressFromSeed() throws {
|
||||||
|
let seedBytes = [UInt8](seedData)
|
||||||
|
|
||||||
|
let shieldedAddress = try derivationTool.deriveShieldedAddress(seed: seedBytes, accountIndex: 0)
|
||||||
|
XCTAssertEqual(shieldedAddress, testRecipientAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveShieldedAddressFromViewingKey() throws {
|
||||||
|
XCTAssertEqual(try derivationTool.deriveShieldedAddress(viewingKey: expectedViewingKey), testRecipientAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveTransparentAddressFromSeed() throws {
|
||||||
|
XCTAssertEqual(try derivationTool.deriveTransparentAddress(seed: [UInt8](seedData)), expectedTransparentAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIsValidViewingKey() throws {
|
||||||
|
XCTAssertTrue(try derivationTool.isValidExtendedViewingKey(self.expectedViewingKey))
|
||||||
|
|
||||||
|
XCTAssertFalse(try derivationTool.isValidExtendedViewingKey("zxviews1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkysswfhjk79n8l99f2grd26dqg6dy3jcmxsaypxfsu6ara6vsk3x8l544uaksstx9zre879mdg7s9a7zurrx6pf5qg2n323js2s3zlu8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszcq7kwxy"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveSecretKeyFromSeed() throws {
|
||||||
|
XCTAssertEqual(try derivationTool.deriveTransparentPrivateKey(seed: [UInt8](seedData)), "L2BCTxmSDiBRb33kGFd4pwGhp9r3FZqG3LZihgTkkg1J14vwtDbq")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveUnifiedKeysFromSeed() throws {
|
||||||
|
let unifiedKeys = try derivationTool.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 1)
|
||||||
|
XCTAssertEqual(unifiedKeys.count, 1)
|
||||||
|
|
||||||
|
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
||||||
|
|
||||||
|
XCTAssertEqual(expectedTransparentAddress, try derivationTool.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testDeriveQuiteALotOfUnifiedKeysFromSeed() throws {
|
||||||
|
let unifiedKeys = try derivationTool.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 10)
|
||||||
|
XCTAssertEqual(unifiedKeys.count, 10)
|
||||||
|
|
||||||
|
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
||||||
|
|
||||||
|
XCTAssertEqual(expectedTransparentAddress, try derivationTool.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
import XCTest
|
import XCTest
|
||||||
import ZcashLightClientKit
|
import ZcashLightClientKit
|
||||||
|
|
||||||
class DerivationToolTests: XCTestCase {
|
class DerivationToolMainnetTests: XCTestCase {
|
||||||
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" //TODO: Parameterize this from environment?
|
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" //TODO: Parameterize this from environment?
|
||||||
var seedData: Data = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==")!
|
var seedData: Data = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==")!
|
||||||
let testRecipientAddress = "zs1vp7kvlqr4n9gpehztr76lcn6skkss9p8keqs3nv8avkdtjrcctrvmk9a7u494kluv756jeee5k0" //TODO: Parameterize this from environment
|
let testRecipientAddress = "zs1vp7kvlqr4n9gpehztr76lcn6skkss9p8keqs3nv8avkdtjrcctrvmk9a7u494kluv756jeee5k0" //TODO: Parameterize this from environment
|
||||||
|
@ -17,11 +17,12 @@ class DerivationToolTests: XCTestCase {
|
||||||
|
|
||||||
let expectedViewingKey = "zxviews1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkysswfhjk79n8l99f2grd26dqg6dy3jcmxsaypxfsu6ara6vsk3x8l544uaksstx9zre879mdg7s9a7zurrx6pf5qg2n323js2s3zlu8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszcq7kwxy"
|
let expectedViewingKey = "zxviews1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkysswfhjk79n8l99f2grd26dqg6dy3jcmxsaypxfsu6ara6vsk3x8l544uaksstx9zre879mdg7s9a7zurrx6pf5qg2n323js2s3zlu8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszcq7kwxy"
|
||||||
|
|
||||||
|
let derivationTool = DerivationTool(networkType: NetworkType.mainnet)
|
||||||
let expectedTransparentAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
let expectedTransparentAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
||||||
func testDeriveViewingKeysFromSeed() throws {
|
func testDeriveViewingKeysFromSeed() throws {
|
||||||
let accounts: Int = 1
|
let accounts: Int = 1
|
||||||
let seedBytes = [UInt8](seedData)
|
let seedBytes = [UInt8](seedData)
|
||||||
let viewingKeys = try DerivationTool.default.deriveViewingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
let viewingKeys = try derivationTool.deriveViewingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
||||||
|
|
||||||
XCTAssertEqual(viewingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
XCTAssertEqual(viewingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
||||||
|
|
||||||
|
@ -34,14 +35,14 @@ class DerivationToolTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveViewingKeyFromSpendingKeys() throws {
|
func testDeriveViewingKeyFromSpendingKeys() throws {
|
||||||
XCTAssertEqual(expectedViewingKey, try DerivationTool.default.deriveViewingKey(spendingKey: expectedSpendingKey))
|
XCTAssertEqual(expectedViewingKey, try derivationTool.deriveViewingKey(spendingKey: expectedSpendingKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveSpendingKeysFromSeed() throws {
|
func testDeriveSpendingKeysFromSeed() throws {
|
||||||
let accounts: Int = 1
|
let accounts: Int = 1
|
||||||
let seedBytes = [UInt8](seedData)
|
let seedBytes = [UInt8](seedData)
|
||||||
|
|
||||||
let spendingKeys = try DerivationTool.default.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
let spendingKeys = try derivationTool.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: accounts)
|
||||||
XCTAssertEqual(spendingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
XCTAssertEqual(spendingKeys.count, accounts, "the number of viewing keys have to match the number of account requested to derive")
|
||||||
|
|
||||||
guard let spendingKey = spendingKeys.first else {
|
guard let spendingKey = spendingKeys.first else {
|
||||||
|
@ -55,44 +56,44 @@ class DerivationToolTests: XCTestCase {
|
||||||
func testDeriveShieldedAddressFromSeed() throws {
|
func testDeriveShieldedAddressFromSeed() throws {
|
||||||
let seedBytes = [UInt8](seedData)
|
let seedBytes = [UInt8](seedData)
|
||||||
|
|
||||||
let shieldedAddress = try DerivationTool.default.deriveShieldedAddress(seed: seedBytes, accountIndex: 0)
|
let shieldedAddress = try derivationTool.deriveShieldedAddress(seed: seedBytes, accountIndex: 0)
|
||||||
XCTAssertEqual(shieldedAddress, testRecipientAddress)
|
XCTAssertEqual(shieldedAddress, testRecipientAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveShieldedAddressFromViewingKey() throws {
|
func testDeriveShieldedAddressFromViewingKey() throws {
|
||||||
XCTAssertEqual(try DerivationTool.default.deriveShieldedAddress(viewingKey: expectedViewingKey), testRecipientAddress)
|
XCTAssertEqual(try derivationTool.deriveShieldedAddress(viewingKey: expectedViewingKey), testRecipientAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveTransparentAddressFromSeed() throws {
|
func testDeriveTransparentAddressFromSeed() throws {
|
||||||
XCTAssertEqual(try DerivationTool.default.deriveTransparentAddress(seed: [UInt8](seedData)), expectedTransparentAddress)
|
XCTAssertEqual(try derivationTool.deriveTransparentAddress(seed: [UInt8](seedData)), expectedTransparentAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIsValidViewingKey() throws {
|
func testIsValidViewingKey() throws {
|
||||||
XCTAssertTrue(try DerivationTool.default.isValidExtendedViewingKey("zxviews1q0dm7hkzqqqqpqplzv3f50rl4vay8uy5zg9e92f62lqg6gzu63rljety32xy5tcyenzuu3n386ws772nm6tp4sads8n37gff6nxmyz8dn9keehmapk0spc6pzx5uxepgu52xnwzxxnuja5tv465t9asppnj3eqncu3s7g3gzg5x8ss4ypkw08xwwyj7ky5skvnd9ldwj2u8fz2ry94s5q8p9lyp3j96yckudmp087d2jr2rnfuvjp7f56v78vpe658vljjddj7s645q399jd7"))
|
XCTAssertTrue(try derivationTool.isValidExtendedViewingKey("zxviews1q0dm7hkzqqqqpqplzv3f50rl4vay8uy5zg9e92f62lqg6gzu63rljety32xy5tcyenzuu3n386ws772nm6tp4sads8n37gff6nxmyz8dn9keehmapk0spc6pzx5uxepgu52xnwzxxnuja5tv465t9asppnj3eqncu3s7g3gzg5x8ss4ypkw08xwwyj7ky5skvnd9ldwj2u8fz2ry94s5q8p9lyp3j96yckudmp087d2jr2rnfuvjp7f56v78vpe658vljjddj7s645q399jd7"))
|
||||||
|
|
||||||
XCTAssertFalse(try DerivationTool.default.isValidExtendedViewingKey("zxviews1q0dm7hkzky5skvnd9ldwj2u8fz2ry94s5q8p9lyp3j96yckudmp087d2jr2rnfuvjp7f56v78vpe658vljjddj7s645q399jd7"))
|
XCTAssertFalse(try derivationTool.isValidExtendedViewingKey("zxviews1q0dm7hkzky5skvnd9ldwj2u8fz2ry94s5q8p9lyp3j96yckudmp087d2jr2rnfuvjp7f56v78vpe658vljjddj7s645q399jd7"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveSecretKeyFromSeed() throws {
|
func testDeriveSecretKeyFromSeed() throws {
|
||||||
XCTAssertEqual(try DerivationTool.default.deriveTransparentPrivateKey(seed: [UInt8](seedData)), "KwqfQoTCuQdCLvzpAEtkt1o8J62WJuZXD3cGRAf1bgmPWuLamHLo")
|
XCTAssertEqual(try derivationTool.deriveTransparentPrivateKey(seed: [UInt8](seedData)), "KwqfQoTCuQdCLvzpAEtkt1o8J62WJuZXD3cGRAf1bgmPWuLamHLo")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveUnifiedKeysFromSeed() throws {
|
func testDeriveUnifiedKeysFromSeed() throws {
|
||||||
let unifiedKeys = try DerivationTool.default.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 1)
|
let unifiedKeys = try derivationTool.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 1)
|
||||||
XCTAssertEqual(unifiedKeys.count, 1)
|
XCTAssertEqual(unifiedKeys.count, 1)
|
||||||
|
|
||||||
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
||||||
|
|
||||||
XCTAssertEqual(expectedTransparentAddress, try DerivationTool.default.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
XCTAssertEqual(expectedTransparentAddress, try derivationTool.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDeriveQuiteALotOfUnifiedKeysFromSeed() throws {
|
func testDeriveQuiteALotOfUnifiedKeysFromSeed() throws {
|
||||||
let unifiedKeys = try DerivationTool.default.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 10)
|
let unifiedKeys = try derivationTool.deriveUnifiedViewingKeysFromSeed([UInt8](seedData), numberOfAccounts: 10)
|
||||||
XCTAssertEqual(unifiedKeys.count, 10)
|
XCTAssertEqual(unifiedKeys.count, 10)
|
||||||
|
|
||||||
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
XCTAssertEqual(unifiedKeys[0].extfvk, expectedViewingKey)
|
||||||
|
|
||||||
XCTAssertEqual(expectedTransparentAddress, try DerivationTool.default.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
XCTAssertEqual(expectedTransparentAddress, try derivationTool.deriveTransparentAddressFromPublicKey(unifiedKeys[0].extpub))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -26,6 +26,7 @@ end
|
||||||
target 'ZcashLightClientSample-Mainnet' do
|
target 'ZcashLightClientSample-Mainnet' do
|
||||||
inherit! :search_paths
|
inherit! :search_paths
|
||||||
use_frameworks!
|
use_frameworks!
|
||||||
|
pod 'MnemonicSwift', '~> 2.0.0'
|
||||||
pod "KRProgressHUD"
|
pod "KRProgressHUD"
|
||||||
pod 'PaginatedTableView'
|
pod 'PaginatedTableView'
|
||||||
pod 'NotificationBubbles'
|
pod 'NotificationBubbles'
|
||||||
|
@ -41,9 +42,7 @@ post_install do |installer|
|
||||||
if target.name == 'ZcashLightClientKit-Unit-Tests'
|
if target.name == 'ZcashLightClientKit-Unit-Tests'
|
||||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = "13.0"
|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = "13.0"
|
||||||
end
|
end
|
||||||
if target.name == 'ZcashLightClientKit'
|
|
||||||
config.build_settings['ZCASH_NETWORK_ENVIRONMENT'] = ENV["ZCASH_NETWORK_ENVIRONMENT"]
|
|
||||||
end
|
|
||||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -68,13 +68,13 @@ PODS:
|
||||||
- SwiftNIOFoundationCompat (< 3, >= 2.19.0)
|
- SwiftNIOFoundationCompat (< 3, >= 2.19.0)
|
||||||
- SwiftNIOTLS (< 3, >= 2.19.0)
|
- SwiftNIOTLS (< 3, >= 2.19.0)
|
||||||
- SwiftProtobuf (1.16.0)
|
- SwiftProtobuf (1.16.0)
|
||||||
- ZcashLightClientKit (0.12.0-alpha.10):
|
- ZcashLightClientKit (0.12.0-alpha.12):
|
||||||
- gRPC-Swift (= 1.0.0)
|
- gRPC-Swift (= 1.0.0)
|
||||||
- SQLite.swift (~> 0.12.2)
|
- SQLite.swift (~> 0.12.2)
|
||||||
- ZcashLightClientKit/DerivationToolTests (0.12.0-alpha.10):
|
- ZcashLightClientKit/DerivationToolTests (0.12.0-alpha.12):
|
||||||
- gRPC-Swift (= 1.0.0)
|
- gRPC-Swift (= 1.0.0)
|
||||||
- SQLite.swift (~> 0.12.2)
|
- SQLite.swift (~> 0.12.2)
|
||||||
- ZcashLightClientKit/Tests (0.12.0-alpha.10):
|
- ZcashLightClientKit/Tests (0.12.0-alpha.12):
|
||||||
- gRPC-Swift (= 1.0.0)
|
- gRPC-Swift (= 1.0.0)
|
||||||
- SQLite.swift (~> 0.12.2)
|
- SQLite.swift (~> 0.12.2)
|
||||||
|
|
||||||
|
@ -153,8 +153,8 @@ SPEC CHECKSUMS:
|
||||||
SwiftNIOTLS: 4f8df225f03393f08e0b47b4d876ae38167f8a27
|
SwiftNIOTLS: 4f8df225f03393f08e0b47b4d876ae38167f8a27
|
||||||
SwiftNIOTransportServices: 896c9a4ac98698d32aa2feea7657ade219ae80bb
|
SwiftNIOTransportServices: 896c9a4ac98698d32aa2feea7657ade219ae80bb
|
||||||
SwiftProtobuf: 4e16842b83c6fda06b10fac50d73b3f1fce8ab7b
|
SwiftProtobuf: 4e16842b83c6fda06b10fac50d73b3f1fce8ab7b
|
||||||
ZcashLightClientKit: cbd3df0c6736cbcb228b5cdc39baad40346ffba3
|
ZcashLightClientKit: 386288e87e90446638c2314a7b4f3f1ffeee40b5
|
||||||
|
|
||||||
PODFILE CHECKSUM: 315a67042788e1eccd948b2b8fe580222fd83cd9
|
PODFILE CHECKSUM: 0e90dc69ac4c19fd97c0ce4835ece810d79ade23
|
||||||
|
|
||||||
COCOAPODS: 1.10.1
|
COCOAPODS: 1.10.1
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
0D4EBA312396CFD70041B507 /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4EBA302396CFD70041B507 /* SendViewController.swift */; };
|
0D4EBA312396CFD70041B507 /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4EBA302396CFD70041B507 /* SendViewController.swift */; };
|
||||||
0D6CE8BD252E3C4A0005D707 /* SaplingParametersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6CE8BC252E3C4A0005D707 /* SaplingParametersViewController.swift */; };
|
0D6CE8BD252E3C4A0005D707 /* SaplingParametersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6CE8BC252E3C4A0005D707 /* SaplingParametersViewController.swift */; };
|
||||||
0D756A94236C761E009B041B /* GetAddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D756A93236C761E009B041B /* GetAddressViewController.swift */; };
|
0D756A94236C761E009B041B /* GetAddressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D756A93236C761E009B041B /* GetAddressViewController.swift */; };
|
||||||
|
0D76121726B1D5F5001CA417 /* Mainnet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D76121526B1D5ED001CA417 /* Mainnet.swift */; };
|
||||||
|
0D76121926B1D66D001CA417 /* Testnet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D76121826B1D66D001CA417 /* Testnet.swift */; };
|
||||||
|
0D76121A26B1E8F6001CA417 /* SampleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D49A18B241698A800CC0649 /* SampleLogger.swift */; };
|
||||||
0D7A4A83236CCD88001F4DD8 /* SyncBlocksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7A4A82236CCD88001F4DD8 /* SyncBlocksViewController.swift */; };
|
0D7A4A83236CCD88001F4DD8 /* SyncBlocksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7A4A82236CCD88001F4DD8 /* SyncBlocksViewController.swift */; };
|
||||||
0D7C85E523AD5A9B006878FC /* SampleStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7C85E423AD5A9B006878FC /* SampleStorage.swift */; };
|
0D7C85E523AD5A9B006878FC /* SampleStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7C85E423AD5A9B006878FC /* SampleStorage.swift */; };
|
||||||
0D8BB45223B1DA0700D5E2A1 /* GetBalanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD3DC6238D88B100DD3EC4 /* GetBalanceViewController.swift */; };
|
0D8BB45223B1DA0700D5E2A1 /* GetBalanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DCD3DC6238D88B100DD3EC4 /* GetBalanceViewController.swift */; };
|
||||||
|
@ -75,6 +78,8 @@
|
||||||
0D4EBA302396CFD70041B507 /* SendViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendViewController.swift; sourceTree = "<group>"; };
|
0D4EBA302396CFD70041B507 /* SendViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendViewController.swift; sourceTree = "<group>"; };
|
||||||
0D6CE8BC252E3C4A0005D707 /* SaplingParametersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaplingParametersViewController.swift; sourceTree = "<group>"; };
|
0D6CE8BC252E3C4A0005D707 /* SaplingParametersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaplingParametersViewController.swift; sourceTree = "<group>"; };
|
||||||
0D756A93236C761E009B041B /* GetAddressViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetAddressViewController.swift; sourceTree = "<group>"; };
|
0D756A93236C761E009B041B /* GetAddressViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetAddressViewController.swift; sourceTree = "<group>"; };
|
||||||
|
0D76121526B1D5ED001CA417 /* Mainnet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mainnet.swift; sourceTree = "<group>"; };
|
||||||
|
0D76121826B1D66D001CA417 /* Testnet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testnet.swift; sourceTree = "<group>"; };
|
||||||
0D7A4A82236CCD88001F4DD8 /* SyncBlocksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncBlocksViewController.swift; sourceTree = "<group>"; };
|
0D7A4A82236CCD88001F4DD8 /* SyncBlocksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncBlocksViewController.swift; sourceTree = "<group>"; };
|
||||||
0D7C85E423AD5A9B006878FC /* SampleStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleStorage.swift; sourceTree = "<group>"; };
|
0D7C85E423AD5A9B006878FC /* SampleStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleStorage.swift; sourceTree = "<group>"; };
|
||||||
0D8BB46C23B1DA0700D5E2A1 /* ZcashLightClientSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZcashLightClientSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
0D8BB46C23B1DA0700D5E2A1 /* ZcashLightClientSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZcashLightClientSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -189,6 +194,15 @@
|
||||||
path = "Get Address";
|
path = "Get Address";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
0D76121426B1D5D7001CA417 /* Constants */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0D76121526B1D5ED001CA417 /* Mainnet.swift */,
|
||||||
|
0D76121826B1D66D001CA417 /* Testnet.swift */,
|
||||||
|
);
|
||||||
|
path = Constants;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
0D7A4A81236CCCDB001F4DD8 /* Sync Blocks */ = {
|
0D7A4A81236CCCDB001F4DD8 /* Sync Blocks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -224,6 +238,7 @@
|
||||||
0D907F142322CC5900D641FE /* ZcashLightClientSample */ = {
|
0D907F142322CC5900D641FE /* ZcashLightClientSample */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
0D76121426B1D5D7001CA417 /* Constants */,
|
||||||
0D1BE47D2581933C00F78BE3 /* Get UTXOs */,
|
0D1BE47D2581933C00F78BE3 /* Get UTXOs */,
|
||||||
0D1BE44F2581583D00F78BE3 /* Derivation Tool */,
|
0D1BE44F2581583D00F78BE3 /* Derivation Tool */,
|
||||||
0D6CE8BB252E3C1A0005D707 /* Sapling Parameters */,
|
0D6CE8BB252E3C1A0005D707 /* Sapling Parameters */,
|
||||||
|
@ -659,6 +674,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
0D76121726B1D5F5001CA417 /* Mainnet.swift in Sources */,
|
||||||
0D8BB45223B1DA0700D5E2A1 /* GetBalanceViewController.swift in Sources */,
|
0D8BB45223B1DA0700D5E2A1 /* GetBalanceViewController.swift in Sources */,
|
||||||
0D8BB45323B1DA0700D5E2A1 /* GetAddressViewController.swift in Sources */,
|
0D8BB45323B1DA0700D5E2A1 /* GetAddressViewController.swift in Sources */,
|
||||||
0D8BB45423B1DA0700D5E2A1 /* ViewController.swift in Sources */,
|
0D8BB45423B1DA0700D5E2A1 /* ViewController.swift in Sources */,
|
||||||
|
@ -672,6 +688,7 @@
|
||||||
0D8BB45C23B1DA0700D5E2A1 /* SampleStorage.swift in Sources */,
|
0D8BB45C23B1DA0700D5E2A1 /* SampleStorage.swift in Sources */,
|
||||||
0D8BB45D23B1DA0700D5E2A1 /* TransactionsDataSource.swift in Sources */,
|
0D8BB45D23B1DA0700D5E2A1 /* TransactionsDataSource.swift in Sources */,
|
||||||
0D8BB45E23B1DA0700D5E2A1 /* PaginatedTransactionsViewController.swift in Sources */,
|
0D8BB45E23B1DA0700D5E2A1 /* PaginatedTransactionsViewController.swift in Sources */,
|
||||||
|
0D76121A26B1E8F6001CA417 /* SampleLogger.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -684,6 +701,7 @@
|
||||||
0D907F182322CC5900D641FE /* ViewController.swift in Sources */,
|
0D907F182322CC5900D641FE /* ViewController.swift in Sources */,
|
||||||
0DDFB33C236B743000AED892 /* LatestHeightViewController.swift in Sources */,
|
0DDFB33C236B743000AED892 /* LatestHeightViewController.swift in Sources */,
|
||||||
0DBF8F9523A80F5A0010B85F /* TransactionDetailViewController.swift in Sources */,
|
0DBF8F9523A80F5A0010B85F /* TransactionDetailViewController.swift in Sources */,
|
||||||
|
0D76121926B1D66D001CA417 /* Testnet.swift in Sources */,
|
||||||
0DA58B942397DDD9004596EA /* TransactionsTableViewController.swift in Sources */,
|
0DA58B942397DDD9004596EA /* TransactionsTableViewController.swift in Sources */,
|
||||||
0D4EBA312396CFD70041B507 /* SendViewController.swift in Sources */,
|
0D4EBA312396CFD70041B507 /* SendViewController.swift in Sources */,
|
||||||
0D7A4A83236CCD88001F4DD8 /* SyncBlocksViewController.swift in Sources */,
|
0D7A4A83236CCD88001F4DD8 /* SyncBlocksViewController.swift in Sources */,
|
||||||
|
|
|
@ -33,11 +33,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
if let wallet = wallet {
|
if let wallet = wallet {
|
||||||
return wallet
|
return wallet
|
||||||
} else {
|
} else {
|
||||||
let unifiedViewingKeys = try! DerivationTool.default.deriveUnifiedViewingKeysFromSeed(DemoAppConfig.seed, numberOfAccounts: 1)
|
let unifiedViewingKeys = try! DerivationTool(networkType: ZCASH_NETWORK.networkType).deriveUnifiedViewingKeysFromSeed(DemoAppConfig.seed, numberOfAccounts: 1)
|
||||||
let wallet = Initializer(cacheDbURL:try! __cacheDbURL(),
|
let wallet = Initializer(cacheDbURL:try! __cacheDbURL(),
|
||||||
dataDbURL: try! __dataDbURL(),
|
dataDbURL: try! __dataDbURL(),
|
||||||
pendingDbURL: try! __pendingDbURL(),
|
pendingDbURL: try! __pendingDbURL(),
|
||||||
endpoint: DemoAppConfig.endpoint,
|
endpoint: DemoAppConfig.endpoint,
|
||||||
|
network: ZCASH_NETWORK,
|
||||||
spendParamsURL: try! __spendParamsURL(),
|
spendParamsURL: try! __spendParamsURL(),
|
||||||
outputParamsURL: try! __outputParamsURL(),
|
outputParamsURL: try! __outputParamsURL(),
|
||||||
viewingKeys: unifiedViewingKeys,
|
viewingKeys: unifiedViewingKeys,
|
||||||
|
@ -48,7 +49,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
try! wallet.initialize()
|
try! wallet.initialize()
|
||||||
var storage = SampleStorage.shared
|
var storage = SampleStorage.shared
|
||||||
storage!.seed = Data(DemoAppConfig.seed)
|
storage!.seed = Data(DemoAppConfig.seed)
|
||||||
storage!.privateKey = try! DerivationTool.default.deriveSpendingKeys(seed: DemoAppConfig.seed, numberOfAccounts: 1)[0]
|
storage!.privateKey = try! DerivationTool(networkType: ZCASH_NETWORK.networkType).deriveSpendingKeys(seed: DemoAppConfig.seed, numberOfAccounts: 1)[0]
|
||||||
self.wallet = wallet
|
self.wallet = wallet
|
||||||
return wallet
|
return wallet
|
||||||
}
|
}
|
||||||
|
@ -152,15 +153,15 @@ func __documentsDirectory() throws -> URL {
|
||||||
}
|
}
|
||||||
|
|
||||||
func __cacheDbURL() throws -> URL {
|
func __cacheDbURL() throws -> URL {
|
||||||
try __documentsDirectory().appendingPathComponent(ZcashSDK.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_CACHES_DB_NAME, isDirectory: false)
|
try __documentsDirectory().appendingPathComponent(ZCASH_NETWORK.constants.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_CACHES_DB_NAME, isDirectory: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func __dataDbURL() throws -> URL {
|
func __dataDbURL() throws -> URL {
|
||||||
try __documentsDirectory().appendingPathComponent(ZcashSDK.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_DATA_DB_NAME, isDirectory: false)
|
try __documentsDirectory().appendingPathComponent(ZCASH_NETWORK.constants.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_DATA_DB_NAME, isDirectory: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func __pendingDbURL() throws -> URL {
|
func __pendingDbURL() throws -> URL {
|
||||||
try __documentsDirectory().appendingPathComponent(ZcashSDK.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_PENDING_DB_NAME)
|
try __documentsDirectory().appendingPathComponent(ZCASH_NETWORK.constants.DEFAULT_DB_NAME_PREFIX+ZcashSDK.DEFAULT_PENDING_DB_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
func __spendParamsURL() throws -> URL {
|
func __spendParamsURL() throws -> URL {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// Mainnet.swift
|
||||||
|
// ZcashLightClientSample
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/28/21.
|
||||||
|
// Copyright © 2021 Electric Coin Company. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ZcashLightClientKit
|
||||||
|
|
||||||
|
let ZCASH_NETWORK = ZcashNetworkBuilder.network(for: .mainnet)
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// Testnet.swift
|
||||||
|
// ZcashLightClientSample
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/28/21.
|
||||||
|
// Copyright © 2021 Electric Coin Company. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ZcashLightClientKit
|
||||||
|
|
||||||
|
let ZCASH_NETWORK = ZcashNetworkBuilder.network(for: .testnet)
|
|
@ -13,17 +13,15 @@ struct DemoAppConfig {
|
||||||
static var host = ZcashSDK.isMainnet ? "lightwalletd.electriccoin.co" : "lightwalletd.testnet.electriccoin.co"
|
static var host = ZcashSDK.isMainnet ? "lightwalletd.electriccoin.co" : "lightwalletd.testnet.electriccoin.co"
|
||||||
static var port: Int = 9067
|
static var port: Int = 9067
|
||||||
static var birthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000
|
static var birthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000
|
||||||
static var network = ZcashSDK.isMainnet ? ZcashNetwork.mainNet : ZcashNetwork.testNet
|
|
||||||
static var seed = try! Mnemonic.deterministicSeedBytes(from: "live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor")
|
static var seed = try! Mnemonic.deterministicSeedBytes(from: "live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor")
|
||||||
static var address: String {
|
static var address: String {
|
||||||
"\(host):\(port)"
|
"\(host):\(port)"
|
||||||
}
|
}
|
||||||
|
|
||||||
static var processorConfig: CompactBlockProcessor.Configuration {
|
static var processorConfig: CompactBlockProcessor.Configuration = {
|
||||||
var config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL())
|
CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), walletBirthday: Self.birthdayHeight, network: ZCASH_NETWORK)
|
||||||
config.walletBirthday = self.birthdayHeight
|
}()
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
static var endpoint: LightWalletEndpoint {
|
static var endpoint: LightWalletEndpoint {
|
||||||
return LightWalletEndpoint(address: self.host, port: self.port, secure: true)
|
return LightWalletEndpoint(address: self.host, port: self.port, secure: true)
|
||||||
|
@ -31,7 +29,13 @@ struct DemoAppConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum ZcashNetwork {
|
extension ZcashSDK {
|
||||||
case mainNet
|
static var isMainnet: Bool {
|
||||||
case testNet
|
switch ZCASH_NETWORK.networkType {
|
||||||
|
case .mainnet:
|
||||||
|
return true
|
||||||
|
case .testnet:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,19 +81,19 @@ class DerivationToolViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deriveFrom(seedPhrase: String) throws {
|
func deriveFrom(seedPhrase: String) throws {
|
||||||
|
|
||||||
|
|
||||||
let seedBytes = try Mnemonic.deterministicSeedBytes(from: seedPhrase)
|
let seedBytes = try Mnemonic.deterministicSeedBytes(from: seedPhrase)
|
||||||
guard let spendingKey = try DerivationTool.default.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
let derivationTool = DerivationTool(networkType: ZCASH_NETWORK.networkType)
|
||||||
|
guard let spendingKey = try derivationTool.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
||||||
throw DerivationErrors.couldNotDeriveSpendingKeys(underlyingError: DerivationErrors.unknown)
|
throw DerivationErrors.couldNotDeriveSpendingKeys(underlyingError: DerivationErrors.unknown)
|
||||||
}
|
}
|
||||||
guard let viewingKey = try DerivationTool.default.deriveViewingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
guard let viewingKey = try derivationTool.deriveViewingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
||||||
throw DerivationErrors.couldNotDeriveViewingKeys(underlyingError: DerivationErrors.unknown)
|
throw DerivationErrors.couldNotDeriveViewingKeys(underlyingError: DerivationErrors.unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
let shieldedAddress = try DerivationTool.default.deriveShieldedAddress(viewingKey: viewingKey)
|
let shieldedAddress = try derivationTool.deriveShieldedAddress(viewingKey: viewingKey)
|
||||||
|
|
||||||
let transparentAddress = try DerivationTool.default.deriveTransparentAddress(seed: seedBytes)
|
let transparentAddress = try derivationTool.deriveTransparentAddress(seed: seedBytes)
|
||||||
|
|
||||||
|
|
||||||
updateLabels(spendingKey: spendingKey,
|
updateLabels(spendingKey: spendingKey,
|
||||||
|
|
|
@ -15,11 +15,11 @@ class GetAddressViewController: UIViewController {
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
let derivationTool = DerivationTool(networkType: ZCASH_NETWORK.networkType)
|
||||||
// Do any additional setup after loading the view.
|
// Do any additional setup after loading the view.
|
||||||
|
|
||||||
zAddressLabel.text = (try? DerivationTool.default.deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)) ?? "No Addresses found"
|
zAddressLabel.text = (try? derivationTool.deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)) ?? "No Addresses found"
|
||||||
tAddressLabel.text = (try? DerivationTool.default.deriveTransparentAddress(seed: DemoAppConfig.seed)) ?? "could not derive t-address"
|
tAddressLabel.text = (try? derivationTool.deriveTransparentAddress(seed: DemoAppConfig.seed)) ?? "could not derive t-address"
|
||||||
spendingKeyLabel.text = SampleStorage.shared.privateKey ?? "No Spending Key found"
|
spendingKeyLabel.text = SampleStorage.shared.privateKey ?? "No Spending Key found"
|
||||||
zAddressLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(addressTapped(_:))))
|
zAddressLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(addressTapped(_:))))
|
||||||
zAddressLabel.isUserInteractionEnabled = true
|
zAddressLabel.isUserInteractionEnabled = true
|
||||||
|
@ -60,7 +60,7 @@ class GetAddressViewController: UIViewController {
|
||||||
|
|
||||||
@IBAction func addressTapped(_ gesture: UIGestureRecognizer) {
|
@IBAction func addressTapped(_ gesture: UIGestureRecognizer) {
|
||||||
loggerProxy.event("copied to clipboard")
|
loggerProxy.event("copied to clipboard")
|
||||||
UIPasteboard.general.string = try? DerivationTool.default.deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)
|
UIPasteboard.general.string = try? DerivationTool(networkType: ZCASH_NETWORK.networkType).deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)
|
||||||
let alert = UIAlertController(title: "", message: "Address Copied to clipboard", preferredStyle: UIAlertController.Style.alert)
|
let alert = UIAlertController(title: "", message: "Address Copied to clipboard", preferredStyle: UIAlertController.Style.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
@ -68,7 +68,7 @@ class GetAddressViewController: UIViewController {
|
||||||
|
|
||||||
@IBAction func tAddressTapped(_ gesture: UIGestureRecognizer) {
|
@IBAction func tAddressTapped(_ gesture: UIGestureRecognizer) {
|
||||||
loggerProxy.event("copied to clipboard")
|
loggerProxy.event("copied to clipboard")
|
||||||
UIPasteboard.general.string = try? DerivationTool.default.deriveTransparentAddress(seed: DemoAppConfig.seed)
|
UIPasteboard.general.string = try? DerivationTool(networkType: ZCASH_NETWORK.networkType).deriveTransparentAddress(seed: DemoAppConfig.seed)
|
||||||
let alert = UIAlertController(title: "", message: "Address Copied to clipboard", preferredStyle: UIAlertController.Style.alert)
|
let alert = UIAlertController(title: "", message: "Address Copied to clipboard", preferredStyle: UIAlertController.Style.alert)
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
|
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
|
||||||
self.present(alert, animated: true, completion: nil)
|
self.present(alert, animated: true, completion: nil)
|
||||||
|
|
|
@ -26,10 +26,10 @@ class GetUTXOsViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUI() {
|
func updateUI() {
|
||||||
let tAddress = try! DerivationTool.default.deriveTransparentAddress(seed: DemoAppConfig.seed)
|
let tAddress = try! DerivationTool(networkType: ZCASH_NETWORK.networkType).deriveTransparentAddress(seed: DemoAppConfig.seed)
|
||||||
self.transparentAddressLabel.text = tAddress
|
self.transparentAddressLabel.text = tAddress
|
||||||
|
|
||||||
let balance = try! AppDelegate.shared.sharedSynchronizer.getTransparentBalance(address: tAddress)
|
let balance = try! AppDelegate.shared.sharedSynchronizer.getTransparentBalance(accountIndex: 0)
|
||||||
|
|
||||||
self.totalBalanceLabel.text = String(balance.total.asHumanReadableZecBalance())
|
self.totalBalanceLabel.text = String(balance.total.asHumanReadableZecBalance())
|
||||||
self.verifiedBalanceLabel.text = String(balance.verified.asHumanReadableZecBalance())
|
self.verifiedBalanceLabel.text = String(balance.verified.asHumanReadableZecBalance())
|
||||||
|
@ -38,9 +38,10 @@ class GetUTXOsViewController: UIViewController {
|
||||||
@IBAction func shieldFunds(_ sender: Any) {
|
@IBAction func shieldFunds(_ sender: Any) {
|
||||||
do {
|
do {
|
||||||
let seed = DemoAppConfig.seed
|
let seed = DemoAppConfig.seed
|
||||||
let sk = try DerivationTool.default.deriveSpendingKeys(seed: seed, numberOfAccounts: 1).first!
|
let derivationTool = DerivationTool(networkType: ZCASH_NETWORK.networkType)
|
||||||
|
let sk = try derivationTool.deriveSpendingKeys(seed: seed, numberOfAccounts: 1).first!
|
||||||
|
|
||||||
let tsk = try DerivationTool.default.deriveTransparentPrivateKey(seed: seed)
|
let tsk = try derivationTool.deriveTransparentPrivateKey(seed: seed)
|
||||||
KRProgressHUD.showMessage("🛡 Shielding 🛡")
|
KRProgressHUD.showMessage("🛡 Shielding 🛡")
|
||||||
AppDelegate.shared.sharedSynchronizer.shieldFunds(spendingKey: sk, transparentSecretKey: tsk, memo: "shielding is fun!", from: 0) { (result) in
|
AppDelegate.shared.sharedSynchronizer.shieldFunds(spendingKey: sk, transparentSecretKey: tsk, memo: "shielding is fun!", from: 0) { (result) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
60
README.md
60
README.md
|
@ -43,16 +43,13 @@ use_frameworks!
|
||||||
pod 'ZcashLightClientKit'
|
pod 'ZcashLightClientKit'
|
||||||
````
|
````
|
||||||
|
|
||||||
### Set Testnet or Mainnet environment
|
|
||||||
Before building, make sure that your environment has the variable `ZCASH_NETWORK_ENVIRONMENT` set to `MAINNET` or `TESTNET`.
|
|
||||||
|
|
||||||
### Custom build phases warning
|
### Custom build phases warning
|
||||||
When running `pod install` you will see this warning upon success:
|
When running `pod install` you will see this warning upon success:
|
||||||
```` bash
|
```` bash
|
||||||
[!] ZcashLightClientKit has added 2 script phases. Please inspect before executing a build.
|
[!] ZcashLightClientKit has added 2 script phases. Please inspect before executing a build.
|
||||||
See `https://guides.cocoapods.org/syntax/podspec.html#script_phases` for more information.
|
See `https://guides.cocoapods.org/syntax/podspec.html#script_phases` for more information.
|
||||||
````
|
````
|
||||||
Integrating Rust code with Swift code and delivering it in a consistent and (build) reproducible way, is hard. We've taken the lead to get that burden off your shoulders as much as possible by leveraging the `prepare_command` and `script_phases` features from Cocoapods to carefully generate the `TESTNET` and `MAINNET` builds as simple and less error prone as we could think it could be. Which started as some simple vanilla scripts, ended up being some kind of "Build System" on its own. Nothing is written on stone, and we accept collaborations and improvements in this matter too.
|
Integrating Rust code with Swift code and delivering it in a consistent and (build) reproducible way, is hard. We've taken the lead to get that burden off your shoulders as much as possible by leveraging the `prepare_command` and `script_phases` features from Cocoapods to carefully generate a build for the Rust layer.
|
||||||
|
|
||||||
## Build system
|
## Build system
|
||||||
|
|
||||||
|
@ -68,8 +65,7 @@ ZcashLightClientKit needs files to be present at pod installation time, but that
|
||||||
|
|
||||||
- `${ZCASH_POD_SRCROOT}/zcashlc/libzcashlc.a` this is the librustzcash build .a file itself
|
- `${ZCASH_POD_SRCROOT}/zcashlc/libzcashlc.a` this is the librustzcash build .a file itself
|
||||||
- `lib/libzcashlc.a` (as vendored library that will be added as an asset by xcodeproj)
|
- `lib/libzcashlc.a` (as vendored library that will be added as an asset by xcodeproj)
|
||||||
- `ZcashSDK.generated.swift` which contains sensitive values for the SDK that change depending on the network environment we are building for
|
|
||||||
- `WalletBirthday+saplingtree.generated.swift` helper functions to import existing wallets
|
|
||||||
|
|
||||||
**2. Build Phase**
|
**2. Build Phase**
|
||||||
|
|
||||||
|
@ -78,37 +74,17 @@ The build Phase scripts executes within the Xcode Build Step and has all the kno
|
||||||
```` ruby
|
```` ruby
|
||||||
s.script_phase = {
|
s.script_phase = {
|
||||||
:name => 'Build generate constants and build librustzcash',
|
:name => 'Build generate constants and build librustzcash',
|
||||||
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_zcashsdk_constants.sh && sh ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
||||||
:execution_position => :before_compile
|
:execution_position => :before_compile
|
||||||
}
|
}
|
||||||
````
|
````
|
||||||
|
|
||||||
This step will generate files needed on the next steps and build the librustzcash with Xcode but *not using cargo's built-in Xcode integration*
|
This step will generate files needed on the next steps and build the librustzcash with Xcode but *not using cargo's built-in Xcode integration*
|
||||||
|
|
||||||
**a. Generating ZcashSDK constants**
|
** Building librustzcash and integrating it to the pod structure**
|
||||||
|
|
||||||
To run this you need `Sourcery`. We use `Stencil` templates to create these files based on the `ZCASH_NETWORK_ENVIRONMENT` value of your choice. You can either integrate sourcery with cocoapods or as part of your environment.
|
|
||||||
|
|
||||||
All generated files will be located in the Pods source root within the `Generated` folder. `ZCASH_SDK_GENERATED_SOURCES_FOLDER` represents that path in the build system.
|
|
||||||
|
|
||||||
**b. Building librustzcash and integrating it to the pod structure**
|
|
||||||
|
|
||||||
Where the magic happens. Here we will make sure that everything is set up properly to start building librustzcash. When on mainnet, the build will append a parameter to include mainnet features.
|
Where the magic happens. Here we will make sure that everything is set up properly to start building librustzcash. When on mainnet, the build will append a parameter to include mainnet features.
|
||||||
|
|
||||||
|
|
||||||
**Safeguards points**:
|
|
||||||
if it appears that you are about to build something smelly, we will let you know. Combining testnet and mainnet values and artifacts and viceversa leads to unstable builds and may cause loss of funds if ran on production.
|
|
||||||
```
|
|
||||||
if [ existing_build_mismatch = true ]; then
|
|
||||||
# clean
|
|
||||||
echo "build mismatch. You previously build a Different network environment. It appears that your build could be inconsistent if proceeding. Please clean your Pods/ folder and clean your build before running your next build."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
```
|
|
||||||
**3. Xcode clean integration**
|
|
||||||
|
|
||||||
When performing a clean, we will clean the rust build folders.
|
|
||||||
|
|
||||||
### Scripts
|
### Scripts
|
||||||
|
|
||||||
On the Scripts folder you will find the following files:
|
On the Scripts folder you will find the following files:
|
||||||
|
@ -118,12 +94,11 @@ On the Scripts folder you will find the following files:
|
||||||
|-/generate_test_constants.sh
|
|-/generate_test_constants.sh
|
||||||
|-/build_librustzcash_xcode.sh
|
|-/build_librustzcash_xcode.sh
|
||||||
|-/build_librustzcash.sh
|
|-/build_librustzcash.sh
|
||||||
|-/generate_zcashsdk_constants.sh
|
|
||||||
|-/script_commons.sh
|
|-/script_commons.sh
|
||||||
````
|
````
|
||||||
|
|
||||||
#### prepare_zcash_sdk.sh
|
#### prepare_zcash_sdk.sh
|
||||||
This script is run by the Cocoapods 'preapare_command'.
|
This script is run by the Cocoapods 'prepare_command'.
|
||||||
|
|
||||||
```` Ruby
|
```` Ruby
|
||||||
s.prepare_command = <<-CMD
|
s.prepare_command = <<-CMD
|
||||||
|
@ -194,22 +169,7 @@ We don't like reinventing the wheel, so we gently borrowed swift lint rules from
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### No network environment....
|
#### clean pod install
|
||||||
if you see this message when building:
|
|
||||||
```No network environment. Set ZCASH_NETWORK_ENVIRONMENT to MAINNET or TESTNET```
|
|
||||||
make sure your dev environment has this variable set before the build starts. *DO NOT CHANGE IT DURING THE BUILD PROCESS*.
|
|
||||||
|
|
||||||
If the variable was properly set *after* you've seen this message, you will need to either a) set it manually on the pod's target or b) doing a clean pod install and subsequent build.
|
|
||||||
|
|
||||||
#### a) setting the flag manually
|
|
||||||
1. on your workspace, select the Pods project
|
|
||||||
2. on the Targets pane, select ZcashLightClientKit
|
|
||||||
3. go to build settings
|
|
||||||
4. scroll down to see ZCASH_NETWORK_ENVIRONMENT and complete with TESTNET or MAINNET
|
|
||||||
|
|
||||||
![how to complete network environment manually](docs/images/complete_environment_manually.png)
|
|
||||||
|
|
||||||
#### b) clean pod install
|
|
||||||
it's not necessary to delete the whole Pods/ directory and download all of your dependencies again
|
it's not necessary to delete the whole Pods/ directory and download all of your dependencies again
|
||||||
1. on your project root, locate the `Pods/` directory
|
1. on your project root, locate the `Pods/` directory
|
||||||
2. remove ZcashLightClientKit from it
|
2. remove ZcashLightClientKit from it
|
||||||
|
@ -228,14 +188,6 @@ if you get a build error similar to ```_function_name referenced from...```
|
||||||
3. run `pod install`
|
3. run `pod install`
|
||||||
4. build
|
4. build
|
||||||
|
|
||||||
### ZcashLightClientKitSample missing .params
|
|
||||||
ZcashLightClientKit has an external dependency on 2 files containing Sapling parameters. Although you can provide those files as you seem fit, the sample app requires them on the main bundle.
|
|
||||||
|
|
||||||
You can download these files from https://z.cash/downloads/sapling-spend.params
|
|
||||||
and https://z.cash/downloads/sapling-output.params and then move them to the correct folder, which is specified on the error itself.
|
|
||||||
|
|
||||||
![how to fix missing params files](docs/images/output_params_error.png)
|
|
||||||
|
|
||||||
### can't find crate for ... target may not be installed
|
### can't find crate for ... target may not be installed
|
||||||
This error could be a side effect of having more then one rust toolchain installed.
|
This error could be a side effect of having more then one rust toolchain installed.
|
||||||
If you worked with ZcashLightClientKit 0.6.6 or below you might have had to set the compiler to 1.40.0 which can cause this compilation error to happen.
|
If you worked with ZcashLightClientKit 0.6.6 or below you might have had to set the compiler to 1.40.0 which can cause this compilation error to happen.
|
||||||
|
|
|
@ -3,16 +3,6 @@
|
||||||
BASEPATH="${PWD}"
|
BASEPATH="${PWD}"
|
||||||
TARGET_DIR="target"
|
TARGET_DIR="target"
|
||||||
|
|
||||||
FEATURE_FLAGS="--features=mainnet"
|
|
||||||
NETWORK_TYPE="TESTNET"
|
|
||||||
FLAVOR_FOLDER="Testnet"
|
|
||||||
|
|
||||||
|
|
||||||
if [ $1 = "--mainnet" ]; then
|
|
||||||
FEATURE_FLAGS="--features=mainnet"
|
|
||||||
NETWORK_TYPE="MAINNET"
|
|
||||||
FLAVOR_FOLDER="Mainnet"
|
|
||||||
fi
|
|
||||||
|
|
||||||
LIB_PATH="ZcashLightClientKit/$FLAVOR_FOLDER/zcashlc"
|
LIB_PATH="ZcashLightClientKit/$FLAVOR_FOLDER/zcashlc"
|
||||||
echo "++++ Building librustzcash $NETWORK_TYPE library ++++"
|
echo "++++ Building librustzcash $NETWORK_TYPE library ++++"
|
||||||
|
@ -22,7 +12,7 @@ if [ -f $TARGET_DIR ]; then
|
||||||
rm -rf $TARGET_DIR
|
rm -rf $TARGET_DIR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cargo build --release $FEATURE_FLAGS && cargo lipo --release
|
cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --release
|
||||||
|
|
||||||
|
|
||||||
if [ -f $LIB_PATH ]; then
|
if [ -f $LIB_PATH ]; then
|
||||||
|
|
|
@ -7,31 +7,12 @@ if [ ! -f $SCRIPT_COMMONS ]; then
|
||||||
fi
|
fi
|
||||||
source $SCRIPT_COMMONS
|
source $SCRIPT_COMMONS
|
||||||
|
|
||||||
if [ "$1" = "--testing" ]; then
|
|
||||||
export ZCASH_NETWORK_ENVIRONMENT=$ZCASH_TESTNET
|
|
||||||
echo "Testing flag detected, forcing $ZCASH_TESTNET"
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_environment
|
|
||||||
|
|
||||||
if [ "$ACTION" = "clean" ]; then
|
if [ "$ACTION" = "clean" ]; then
|
||||||
echo "CLEAN DETECTED"
|
echo "CLEAN DETECTED"
|
||||||
clean
|
clean
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ existing_build_mismatch = true ]; then
|
|
||||||
# clean
|
|
||||||
echo "Build mismatch. You previously built a different network environment. It appears that your build could be inconsistent if proceeding. Please clean your Pods/ folder and clean your build before running your next build."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if is_mainnet; then
|
|
||||||
FEATURE_FLAGS="--features=mainnet"
|
|
||||||
else
|
|
||||||
FEATURE_FLAGS="--features=testnet"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Building Rust backend"
|
echo "Building Rust backend"
|
||||||
echo ""
|
echo ""
|
||||||
echo "platform name"
|
echo "platform name"
|
||||||
|
@ -45,7 +26,7 @@ fi
|
||||||
echo "fix 'permission denied issue'"
|
echo "fix 'permission denied issue'"
|
||||||
chmod -R +w ${PODS_TARGET_SRCROOT}
|
chmod -R +w ${PODS_TARGET_SRCROOT}
|
||||||
|
|
||||||
echo "cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml $FEATURE_FLAGS --targets $ZCASH_ACTIVE_ARCHITECTURE --release"
|
echo "cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --targets $ZCASH_ACTIVE_ARCHITECTURE --release"
|
||||||
if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]; then
|
if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]; then
|
||||||
# Assume we're in Xcode, which means we're probably cross-compiling.
|
# Assume we're in Xcode, which means we're probably cross-compiling.
|
||||||
# In this case, we need to add an extra library search path for build scripts and proc-macros,
|
# In this case, we need to add an extra library search path for build scripts and proc-macros,
|
||||||
|
@ -55,7 +36,7 @@ if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]; then
|
||||||
export LIBRARY_PATH="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}"
|
export LIBRARY_PATH="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}"
|
||||||
fi
|
fi
|
||||||
if [ ! -f ${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME} ]; then
|
if [ ! -f ${ZCASH_LIB_RUST_BUILD_PATH}/universal/release/${ZCASH_LIB_RUST_NAME} ]; then
|
||||||
cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml $FEATURE_FLAGS --targets $ZCASH_ACTIVE_ARCHITECTURE --release
|
cargo lipo --manifest-path ${PODS_TARGET_SRCROOT}/Cargo.toml --targets $ZCASH_ACTIVE_ARCHITECTURE --release
|
||||||
persist_environment
|
persist_environment
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
SCRIPT_COMMONS="${PODS_TARGET_SRCROOT}/Scripts/script_commons.sh"
|
|
||||||
if [ -f $SCRIPT_COMMONS ]; then
|
|
||||||
source $SCRIPT_COMMONS
|
|
||||||
else
|
|
||||||
echo "Failed to load $SCRIPT_COMMONS"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! hash sourcery; then
|
|
||||||
echo "Sourcery not found on your PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
export ZCASH_SDK_TEMPLATE="${ZCASH_SRC_PATH}/Stencil"
|
|
||||||
|
|
||||||
echo "export ZCASH_SRC_PATH=${ZCASH_SRC_PATH}"
|
|
||||||
|
|
||||||
check_environment
|
|
||||||
|
|
||||||
if is_mainnet; then
|
|
||||||
SOURCERY_ARGS="--args dbprefix=ZcashSdk_mainnet_ --args ismainnet=true --args saplingActivationHeight=419_200"
|
|
||||||
else
|
|
||||||
SOURCERY_ARGS="--args dbprefix=ZcashSdk_testnet_ --args ismainnet=false --args saplingActivationHeight=280_000"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d $ZCASH_SDK_GENERATED_SOURCES_FOLDER ]; then
|
|
||||||
echo "clean up before generating new files: $ZCASH_SDK_GENERATED_SOURCES_FOLDER"
|
|
||||||
echo "rm -rf ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}/*.generated*"
|
|
||||||
rm -rf "${ZCASH_SDK_GENERATED_SOURCES_FOLDER}/*.generated*"
|
|
||||||
else
|
|
||||||
echo "mkdir -p -v $ZCASH_SDK_GENERATED_SOURCES_FOLDER"
|
|
||||||
mkdir -p -v ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Set +w to ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}"
|
|
||||||
chmod -R +w ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}
|
|
||||||
|
|
||||||
echo "sourcery --prune --verbose --templates ${ZCASH_SDK_TEMPLATE} --sources ${ZCASH_SRC_PATH} --output ${ZCASH_SDK_GENERATED_SOURCES_FOLDER} $SOURCERY_ARGS "
|
|
||||||
|
|
||||||
sourcery --prune --verbose --templates ${ZCASH_SDK_TEMPLATE} --sources ${ZCASH_SRC_PATH} --output ${ZCASH_SDK_GENERATED_SOURCES_FOLDER} $SOURCERY_ARGS
|
|
||||||
|
|
|
@ -26,22 +26,3 @@ echo "**************************************************************************
|
||||||
echo " touch ${ZCASH_POD_ROOT}/zcashlc/zcashlc.h"
|
echo " touch ${ZCASH_POD_ROOT}/zcashlc/zcashlc.h"
|
||||||
echo "***************************************************************************"
|
echo "***************************************************************************"
|
||||||
touch ${ZCASH_POD_SRCROOT}/zcashlc/zcashlc.h
|
touch ${ZCASH_POD_SRCROOT}/zcashlc/zcashlc.h
|
||||||
|
|
||||||
echo "make ${ZCASH_SDK_GENERATED_SOURCES_FOLDER} folder"
|
|
||||||
mkdir -p ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}
|
|
||||||
|
|
||||||
echo "**********************************************"
|
|
||||||
echo "* create empty ZcashSDK.generated.swift file *"
|
|
||||||
echo "**********************************************"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "touch ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}/ZcashSDK.generated.swift"
|
|
||||||
touch ${ZCASH_SDK_GENERATED_SOURCES_FOLDER}/ZcashSDK.generated.swift
|
|
||||||
|
|
||||||
echo "****************************************************************"
|
|
||||||
echo "* create empty WalletBirthday+saplingtree.generated.swift file *"
|
|
||||||
echo "****************************************************************"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "touch $ZCASH_SDK_GENERATED_SOURCES_FOLDER/WalletBirthday+saplingtree.generated.swift"
|
|
||||||
touch $ZCASH_SDK_GENERATED_SOURCES_FOLDER/WalletBirthday+saplingtree.generated.swift
|
|
|
@ -4,14 +4,12 @@ export PATH="$HOME/.cargo/bin:$PATH"
|
||||||
export RUST_LIB_PATH="${PODS_TARGET_SRCROOT}/lib"
|
export RUST_LIB_PATH="${PODS_TARGET_SRCROOT}/lib"
|
||||||
export ZCASH_POD_SCRIPTS="${PODS_TARGET_SRCROOT}/Scripts"
|
export ZCASH_POD_SCRIPTS="${PODS_TARGET_SRCROOT}/Scripts"
|
||||||
export ZCASH_LIB_RUST_BUILD_PATH="${PODS_TARGET_SRCROOT}/target"
|
export ZCASH_LIB_RUST_BUILD_PATH="${PODS_TARGET_SRCROOT}/target"
|
||||||
export ZCASH_BUILD_TYPE_MAINNET_FLAG=".mainnet_build"
|
|
||||||
export ZCASH_BUILD_TYPE_TESTNET_FLAG=".testnet_build"
|
|
||||||
export ZCASH_LIB_RUST_NAME="libzcashlc.a"
|
export ZCASH_LIB_RUST_NAME="libzcashlc.a"
|
||||||
export ZCASH_TESTNET="TESTNET"
|
|
||||||
export ZCASH_MAINNET="MAINNET"
|
|
||||||
export ZCASH_SRC_PATH="${PODS_TARGET_SRCROOT}/ZcashLightClientKit"
|
export ZCASH_SRC_PATH="${PODS_TARGET_SRCROOT}/ZcashLightClientKit"
|
||||||
export ZCASH_SDK_RUST_LIB_PATH="${ZCASH_SRC_PATH}/zcashlc"
|
export ZCASH_SDK_RUST_LIB_PATH="${ZCASH_SRC_PATH}/zcashlc"
|
||||||
export ZCASH_SDK_GENERATED_SOURCES_FOLDER="${ZCASH_SRC_PATH}/Generated"
|
|
||||||
|
|
||||||
function clean {
|
function clean {
|
||||||
echo "CLEAN DETECTED"
|
echo "CLEAN DETECTED"
|
||||||
|
@ -23,76 +21,3 @@ function clean {
|
||||||
rm -rf "${ZCASH_LIB_RUST_BUILD_PATH}"
|
rm -rf "${ZCASH_LIB_RUST_BUILD_PATH}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_environment {
|
|
||||||
|
|
||||||
if [[ $ZCASH_NETWORK_ENVIRONMENT != $ZCASH_MAINNET ]] && [[ $ZCASH_NETWORK_ENVIRONMENT != $ZCASH_TESTNET ]]; then
|
|
||||||
echo "No network environment. Set ZCASH_NETWORK_ENVIRONMENT to $ZCASH_MAINNET or $ZCASH_TESTNET"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $ZCASH_SDK_GENERATED_SOURCES_FOLDER ]]; then
|
|
||||||
echo "No 'ZCASH_SDK_GENERATED_SOURCES_FOLDER' variable present. Delete Pods/ and run 'pod install --verbose'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "**** Building for $ZCASH_NETWORK_ENVIRONMENT environment ****"
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_mainnet {
|
|
||||||
if [[ $ZCASH_NETWORK_ENVIRONMENT = $ZCASH_MAINNET ]]; then
|
|
||||||
true
|
|
||||||
else
|
|
||||||
false
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
# Return success (0) if there is a build mismatch, else failure (1) if no mismatch.
|
|
||||||
function existing_build_mismatch {
|
|
||||||
#if build exists check that corresponds to the current network environment
|
|
||||||
if [! -d $ZCASH_LIB_RUST_BUILD_PATH ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# there's a MAINNET Flag and MAINNET ENVIRONMENT
|
|
||||||
if [ -f "$ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_MAINNET_FLAG" ] && [[ "$ZCASH_NETWORK_ENVIRONMENT" = "$ZCASH_MAINNET" ]]
|
|
||||||
then
|
|
||||||
return 1 # no build mismatch
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_MAINNET_FLAG" ] && [[ "$ZCASH_NETWORK_ENVIRONMENT" = "$ZCASH_TESTNET" ]]
|
|
||||||
then
|
|
||||||
warn_mismatch $ZCASH_MAINNET $ZCASH_NETWORK_ENVIRONMENT
|
|
||||||
return 0 # build mismatch in place
|
|
||||||
fi
|
|
||||||
|
|
||||||
# There's a TESTNET flag and we are on TESTNET ENVIRONMENT
|
|
||||||
if [ -f "$ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_TESTNET_FLAG" ] && [[ "$ZCASH_NETWORK_ENVIRONMENT" = "$ZCASH_TESTNET" ]]
|
|
||||||
then
|
|
||||||
return 1 # no build mismatch
|
|
||||||
fi
|
|
||||||
# There's a TESTNET flag and we are on a MAINNET Environment
|
|
||||||
if [ -f "$ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_TESTNET_FLAG" ] && [[ "$ZCASH_NETWORK_ENVIRONMENT" = "$ZCASH_MAINNET" ]]
|
|
||||||
then
|
|
||||||
warn_mismatch $ZCASH_TESTNET $ZCASH_NETWORK_ENVIRONMENT
|
|
||||||
return 0 # build mismatch in place
|
|
||||||
fi
|
|
||||||
echo "=== NO BUILD FLAG, CHECKING ENVIRONMENT ==="
|
|
||||||
check_environment
|
|
||||||
return 1 # no build mismatch
|
|
||||||
}
|
|
||||||
|
|
||||||
function warn_mismatch {
|
|
||||||
echo "*** WARNING: *** build mismatch. Found ${0} but environment is ${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function persist_environment {
|
|
||||||
check_environment
|
|
||||||
|
|
||||||
if [ $ZCASH_NETWORK_ENVIRONMENT = "$ZCASH_MAINNET" ]
|
|
||||||
then
|
|
||||||
touch $ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_MAINNET_FLAG
|
|
||||||
elif [[ "$ZCASH_NETWORK_ENVIRONMENT" = "$ZCASH_TESTNET" ]]
|
|
||||||
then
|
|
||||||
touch $ZCASH_LIB_RUST_BUILD_PATH/$ZCASH_BUILD_TYPE_TESTNET_FLAG
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = 'ZcashLightClientKit'
|
s.name = 'ZcashLightClientKit'
|
||||||
s.version = '0.12.0-alpha.10'
|
s.version = '0.12.0-alpha.12'
|
||||||
s.summary = 'Zcash Light Client wallet SDK for iOS'
|
s.summary = 'Zcash Light Client wallet SDK for iOS'
|
||||||
|
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
|
@ -30,11 +30,9 @@ Pod::Spec.new do |s|
|
||||||
|
|
||||||
s.script_phase = {
|
s.script_phase = {
|
||||||
:name => 'Build generate constants and build librustzcash',
|
:name => 'Build generate constants and build librustzcash',
|
||||||
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_zcashsdk_constants.sh && sh ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
||||||
:execution_position => :before_compile,
|
:execution_position => :before_compile,
|
||||||
:output_files => [
|
|
||||||
'${PODS_TARGET_SRCROOT}/ZcashLightClientKit/Generated/WalletBirthday+saplingtree.generated.swift',
|
|
||||||
'${PODS_TARGET_SRCROOT}/ZcashLightClientKit/Generated/ZcashSDK.generated.swift']
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.test_spec 'Tests' do | test_spec |
|
s.test_spec 'Tests' do | test_spec |
|
||||||
|
@ -42,7 +40,7 @@ Pod::Spec.new do |s|
|
||||||
test_spec.ios.resources = 'ZcashLightClientKitTests/**/*.{db,params}'
|
test_spec.ios.resources = 'ZcashLightClientKitTests/**/*.{db,params}'
|
||||||
test_spec.script_phase = {
|
test_spec.script_phase = {
|
||||||
:name => 'Build generate constants and build librustzcash',
|
:name => 'Build generate constants and build librustzcash',
|
||||||
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_test_constants.sh && ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh --testing',
|
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_test_constants.sh && ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
||||||
:execution_position => :before_compile
|
:execution_position => :before_compile
|
||||||
}
|
}
|
||||||
test_spec.dependency 'gRPC-Swift', '= 1.0.0'
|
test_spec.dependency 'gRPC-Swift', '= 1.0.0'
|
||||||
|
@ -53,7 +51,7 @@ Pod::Spec.new do |s|
|
||||||
test_spec.source_files = 'DerivationToolTests/**/*.{swift}'
|
test_spec.source_files = 'DerivationToolTests/**/*.{swift}'
|
||||||
test_spec.script_phase = {
|
test_spec.script_phase = {
|
||||||
:name => 'Build generate constants and build librustzcash',
|
:name => 'Build generate constants and build librustzcash',
|
||||||
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_test_constants.sh && ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh --testing',
|
:script => 'sh ${PODS_TARGET_SRCROOT}/Scripts/generate_test_constants.sh && ${PODS_TARGET_SRCROOT}/Scripts/build_librustzcash_xcode.sh',
|
||||||
:execution_position => :before_compile
|
:execution_position => :before_compile
|
||||||
}
|
}
|
||||||
test_spec.dependency 'gRPC-Swift', '= 1.0.0'
|
test_spec.dependency 'gRPC-Swift', '= 1.0.0'
|
||||||
|
|
|
@ -25,13 +25,15 @@ class MigrationManager {
|
||||||
var cacheDb: ConnectionProvider
|
var cacheDb: ConnectionProvider
|
||||||
var dataDb: ConnectionProvider
|
var dataDb: ConnectionProvider
|
||||||
var pendingDb: ConnectionProvider
|
var pendingDb: ConnectionProvider
|
||||||
|
var network: NetworkType
|
||||||
init(cacheDbConnection: ConnectionProvider,
|
init(cacheDbConnection: ConnectionProvider,
|
||||||
dataDbConnection: ConnectionProvider,
|
dataDbConnection: ConnectionProvider,
|
||||||
pendingDbConnection: ConnectionProvider) {
|
pendingDbConnection: ConnectionProvider,
|
||||||
|
networkType: NetworkType) {
|
||||||
self.cacheDb = cacheDbConnection
|
self.cacheDb = cacheDbConnection
|
||||||
self.dataDb = dataDbConnection
|
self.dataDb = dataDbConnection
|
||||||
self.pendingDb = pendingDbConnection
|
self.pendingDb = pendingDbConnection
|
||||||
|
self.network = networkType
|
||||||
}
|
}
|
||||||
|
|
||||||
static let latestDataDbMigrationVersion: Int32 = DataDbMigrations.version1.rawValue
|
static let latestDataDbMigrationVersion: Int32 = DataDbMigrations.version1.rawValue
|
||||||
|
@ -149,7 +151,7 @@ class MigrationManager {
|
||||||
LoggerProxy.debug(message)
|
LoggerProxy.debug(message)
|
||||||
throw StorageError.migrationFailedWithMessage(message: message)
|
throw StorageError.migrationFailedWithMessage(message: message)
|
||||||
}
|
}
|
||||||
let derivationTool = DerivationTool.default
|
let derivationTool = DerivationTool(networkType: self.network)
|
||||||
|
|
||||||
for tuple in zip(accounts, viewingKeys) {
|
for tuple in zip(accounts, viewingKeys) {
|
||||||
let tAddr = try derivationTool.deriveTransparentAddressFromPublicKey(tuple.1.extpub)
|
let tAddr = try derivationTool.deriveTransparentAddressFromPublicKey(tuple.1.extpub)
|
||||||
|
@ -177,7 +179,9 @@ class MigrationManager {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let uvks = try DerivationTool.default.deriveUnifiedViewingKeysFromSeed(seedBytes, numberOfAccounts: accounts.count)
|
let derivationTool = DerivationTool(networkType: self.network)
|
||||||
|
|
||||||
|
let uvks = try derivationTool.deriveUnifiedViewingKeysFromSeed(seedBytes, numberOfAccounts: accounts.count)
|
||||||
|
|
||||||
try performVersion1Migration(viewingKeys: uvks)
|
try performVersion1Migration(viewingKeys: uvks)
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,9 +90,6 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
||||||
}
|
}
|
||||||
let latestDownloaded = try storage.latestHeight()
|
let latestDownloaded = try storage.latestHeight()
|
||||||
let startHeight = max(self.startHeight ?? BlockHeight.empty(), latestDownloaded)
|
let startHeight = max(self.startHeight ?? BlockHeight.empty(), latestDownloaded)
|
||||||
guard startHeight >= ZcashSDK.SAPLING_ACTIVATION_HEIGHT else {
|
|
||||||
throw CompactBlockStreamDownloadOperationError.startHeightMissing
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cancelable = self.service.blockStream(startHeight: startHeight, endHeight: latestHeight) { [weak self] result in
|
self.cancelable = self.service.blockStream(startHeight: startHeight, endHeight: latestHeight) { [weak self] result in
|
||||||
switch result {
|
switch result {
|
||||||
|
@ -106,7 +103,11 @@ class CompactBlockStreamDownloadOperation: ZcashOperation {
|
||||||
self?.fail(error: e)
|
self?.fail(error: e)
|
||||||
}
|
}
|
||||||
case .failure(let e):
|
case .failure(let e):
|
||||||
self?.fail(error: e)
|
if case .userCancelled = e {
|
||||||
|
self?.done = true
|
||||||
|
} else {
|
||||||
|
self?.fail(error: e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} handler: {[weak self] block in
|
} handler: {[weak self] block in
|
||||||
|
@ -181,16 +182,14 @@ class CompactBlockBatchDownloadOperation: ZcashOperation {
|
||||||
}
|
}
|
||||||
self.startedHandler?()
|
self.startedHandler?()
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
let localDownloadedHeight = try self.storage.latestHeight()
|
||||||
|
|
||||||
guard startHeight >= ZcashSDK.SAPLING_ACTIVATION_HEIGHT else {
|
if localDownloadedHeight != BlockHeight.empty() && localDownloadedHeight > startHeight {
|
||||||
throw CompactBlockBatchDownloadOperationError.startHeightMissing
|
|
||||||
}
|
|
||||||
|
|
||||||
var localDownloadedHeight = try self.storage.latestHeight()
|
|
||||||
if localDownloadedHeight != startHeight {
|
|
||||||
LoggerProxy.warn("provided startHeight (\(startHeight)) differs from local latest downloaded height (\(localDownloadedHeight))")
|
LoggerProxy.warn("provided startHeight (\(startHeight)) differs from local latest downloaded height (\(localDownloadedHeight))")
|
||||||
startHeight = localDownloadedHeight + 1
|
startHeight = localDownloadedHeight + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentHeight = startHeight
|
var currentHeight = startHeight
|
||||||
self.progressDelegate?.progressUpdated(.download(BlockProgress(startHeight: currentHeight, targetHeight: targetHeight, progressHeight: currentHeight)))
|
self.progressDelegate?.progressUpdated(.download(BlockProgress(startHeight: currentHeight, targetHeight: targetHeight, progressHeight: currentHeight)))
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class CompactBlockEnhancementOperation: ZcashOperation {
|
||||||
var repository: TransactionRepository
|
var repository: TransactionRepository
|
||||||
var maxRetries: Int = 5
|
var maxRetries: Int = 5
|
||||||
var retries: Int = 0
|
var retries: Int = 0
|
||||||
|
private(set) var network: NetworkType
|
||||||
weak var progressDelegate: CompactBlockProgressDelegate?
|
weak var progressDelegate: CompactBlockProgressDelegate?
|
||||||
private var dataDb: URL
|
private var dataDb: URL
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ class CompactBlockEnhancementOperation: ZcashOperation {
|
||||||
downloader: CompactBlockDownloading,
|
downloader: CompactBlockDownloading,
|
||||||
repository: TransactionRepository,
|
repository: TransactionRepository,
|
||||||
range: BlockRange,
|
range: BlockRange,
|
||||||
|
networkType: NetworkType,
|
||||||
progressDelegate: CompactBlockProgressDelegate? = nil) {
|
progressDelegate: CompactBlockProgressDelegate? = nil) {
|
||||||
rustBackend = rustWelding
|
rustBackend = rustWelding
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
|
@ -41,6 +43,7 @@ class CompactBlockEnhancementOperation: ZcashOperation {
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.range = range
|
self.range = range
|
||||||
self.progressDelegate = progressDelegate
|
self.progressDelegate = progressDelegate
|
||||||
|
self.network = networkType
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +115,7 @@ class CompactBlockEnhancementOperation: ZcashOperation {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
guard rustBackend.decryptAndStoreTransaction(dbData: dataDb, tx: rawBytes) else {
|
guard rustBackend.decryptAndStoreTransaction(dbData: dataDb, tx: rawBytes, networkType: network) else {
|
||||||
if let rustError = rustBackend.lastError() {
|
if let rustError = rustBackend.lastError() {
|
||||||
throw EnhancementError.decryptError(error: rustError)
|
throw EnhancementError.decryptError(error: rustError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public enum CompactBlockProcessorError: Error {
|
||||||
case criticalError
|
case criticalError
|
||||||
case invalidAccount
|
case invalidAccount
|
||||||
case wrongConsensusBranchId(expectedLocally: ConsensusBranchID, found: ConsensusBranchID)
|
case wrongConsensusBranchId(expectedLocally: ConsensusBranchID, found: ConsensusBranchID)
|
||||||
case networkMismatch(expected: ZcashSDK.NetworkType, found: ZcashSDK.NetworkType)
|
case networkMismatch(expected: NetworkType, found: NetworkType)
|
||||||
case saplingActivationMismatch(expected: BlockHeight, found: BlockHeight)
|
case saplingActivationMismatch(expected: BlockHeight, found: BlockHeight)
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -228,20 +228,23 @@ public class CompactBlockProcessor {
|
||||||
public var maxBackoffInterval = ZcashSDK.DEFAULT_MAX_BACKOFF_INTERVAL
|
public var maxBackoffInterval = ZcashSDK.DEFAULT_MAX_BACKOFF_INTERVAL
|
||||||
public var rewindDistance = ZcashSDK.DEFAULT_REWIND_DISTANCE
|
public var rewindDistance = ZcashSDK.DEFAULT_REWIND_DISTANCE
|
||||||
public var walletBirthday: BlockHeight
|
public var walletBirthday: BlockHeight
|
||||||
|
private(set) var network: ZcashNetwork
|
||||||
private(set) var saplingActivation: BlockHeight
|
private(set) var saplingActivation: BlockHeight
|
||||||
|
|
||||||
init (
|
init (
|
||||||
cacheDb: URL,
|
cacheDb: URL,
|
||||||
dataDb: URL,
|
dataDb: URL,
|
||||||
downloadBatchSize: Int,
|
downloadBatchSize: Int,
|
||||||
retries: Int,
|
retries: Int,
|
||||||
maxBackoffInterval: TimeInterval,
|
maxBackoffInterval: TimeInterval,
|
||||||
rewindDistance: Int,
|
rewindDistance: Int,
|
||||||
walletBirthday: BlockHeight,
|
walletBirthday: BlockHeight,
|
||||||
saplingActivation: BlockHeight
|
saplingActivation: BlockHeight,
|
||||||
|
network: ZcashNetwork
|
||||||
) {
|
) {
|
||||||
self.cacheDb = cacheDb
|
self.cacheDb = cacheDb
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
|
self.network = network
|
||||||
self.downloadBatchSize = downloadBatchSize
|
self.downloadBatchSize = downloadBatchSize
|
||||||
self.retries = retries
|
self.retries = retries
|
||||||
self.maxBackoffInterval = maxBackoffInterval
|
self.maxBackoffInterval = maxBackoffInterval
|
||||||
|
@ -250,11 +253,12 @@ public class CompactBlockProcessor {
|
||||||
self.saplingActivation = saplingActivation
|
self.saplingActivation = saplingActivation
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(cacheDb: URL, dataDb: URL, walletBirthday: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT){
|
public init(cacheDb: URL, dataDb: URL, walletBirthday: BlockHeight, network: ZcashNetwork){
|
||||||
self.cacheDb = cacheDb
|
self.cacheDb = cacheDb
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
self.walletBirthday = walletBirthday
|
self.walletBirthday = walletBirthday
|
||||||
self.saplingActivation = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
self.saplingActivation = network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
|
self.network = network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -313,7 +317,7 @@ public class CompactBlockProcessor {
|
||||||
private var transactionRepository: TransactionRepository
|
private var transactionRepository: TransactionRepository
|
||||||
private var accountRepository: AccountRepository
|
private var accountRepository: AccountRepository
|
||||||
private var rustBackend: ZcashRustBackendWelding.Type
|
private var rustBackend: ZcashRustBackendWelding.Type
|
||||||
var config: Configuration = Configuration.standard {
|
var config: Configuration {
|
||||||
willSet {
|
willSet {
|
||||||
self.stop()
|
self.stop()
|
||||||
}
|
}
|
||||||
|
@ -348,7 +352,7 @@ public class CompactBlockProcessor {
|
||||||
- Throws CompactBlockProcessorError.invalidConfiguration if block height is invalid or if processor is already started
|
- Throws CompactBlockProcessorError.invalidConfiguration if block height is invalid or if processor is already started
|
||||||
*/
|
*/
|
||||||
func setStartHeight(_ startHeight: BlockHeight) throws {
|
func setStartHeight(_ startHeight: BlockHeight) throws {
|
||||||
guard self.state == .stopped, startHeight >= ZcashSDK.SAPLING_ACTIVATION_HEIGHT else {
|
guard self.state == .stopped, startHeight >= config.network.constants.SAPLING_ACTIVATION_HEIGHT else {
|
||||||
throw CompactBlockProcessorError.invalidConfiguration
|
throw CompactBlockProcessorError.invalidConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +391,8 @@ public class CompactBlockProcessor {
|
||||||
backend: initializer.rustBackend,
|
backend: initializer.rustBackend,
|
||||||
config: Configuration(cacheDb: initializer.cacheDbURL,
|
config: Configuration(cacheDb: initializer.cacheDbURL,
|
||||||
dataDb: initializer.dataDbURL,
|
dataDb: initializer.dataDbURL,
|
||||||
walletBirthday: initializer.walletBirthday.height),
|
walletBirthday: initializer.walletBirthday.height,
|
||||||
|
network: initializer.network),
|
||||||
repository: initializer.transactionRepository,
|
repository: initializer.transactionRepository,
|
||||||
accountRepository: initializer.accountRepository)
|
accountRepository: initializer.accountRepository)
|
||||||
}
|
}
|
||||||
|
@ -493,6 +498,7 @@ public class CompactBlockProcessor {
|
||||||
do {
|
do {
|
||||||
try Self.validateServerInfo(info,
|
try Self.validateServerInfo(info,
|
||||||
saplingActivation: self.config.saplingActivation,
|
saplingActivation: self.config.saplingActivation,
|
||||||
|
localNetwork: self.config.network,
|
||||||
rustBackend: self.rustBackend)
|
rustBackend: self.rustBackend)
|
||||||
completionBlock()
|
completionBlock()
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -507,15 +513,16 @@ public class CompactBlockProcessor {
|
||||||
|
|
||||||
static func validateServerInfo(_ info: LightWalletdInfo,
|
static func validateServerInfo(_ info: LightWalletdInfo,
|
||||||
saplingActivation: BlockHeight,
|
saplingActivation: BlockHeight,
|
||||||
|
localNetwork: ZcashNetwork,
|
||||||
rustBackend: ZcashRustBackendWelding.Type) throws {
|
rustBackend: ZcashRustBackendWelding.Type) throws {
|
||||||
|
|
||||||
// check network types
|
// check network types
|
||||||
guard let remoteNetworkType = ZcashSDK.NetworkType(info.chainName) else {
|
guard let remoteNetworkType = NetworkType.forChainName(info.chainName) else {
|
||||||
throw CompactBlockProcessorError.generalError(message: "Chain name does not match. Expected either 'test' or 'main' but received '\(info.chainName)'. this is probably an API or programming error")
|
throw CompactBlockProcessorError.generalError(message: "Chain name does not match. Expected either 'test' or 'main' but received '\(info.chainName)'. this is probably an API or programming error")
|
||||||
}
|
}
|
||||||
|
|
||||||
guard remoteNetworkType == ZcashSDK.networkType else {
|
guard remoteNetworkType == localNetwork.networkType else {
|
||||||
throw CompactBlockProcessorError.networkMismatch(expected: ZcashSDK.networkType, found: remoteNetworkType)
|
throw CompactBlockProcessorError.networkMismatch(expected: localNetwork.networkType, found: remoteNetworkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard saplingActivation == info.saplingActivationHeight else {
|
guard saplingActivation == info.saplingActivationHeight else {
|
||||||
|
@ -523,7 +530,7 @@ public class CompactBlockProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check branch id
|
// check branch id
|
||||||
let localBranch = try rustBackend.consensusBranchIdFor(height: Int32(info.blockHeight))
|
let localBranch = try rustBackend.consensusBranchIdFor(height: Int32(info.blockHeight), networkType: localNetwork.networkType)
|
||||||
|
|
||||||
guard let remoteBranchID = ConsensusBranchID.fromString(info.consensusBranchID)
|
guard let remoteBranchID = ConsensusBranchID.fromString(info.consensusBranchID)
|
||||||
else {
|
else {
|
||||||
|
@ -564,7 +571,7 @@ public class CompactBlockProcessor {
|
||||||
|
|
||||||
let lastDownloaded = try downloader.lastDownloadedBlockHeight()
|
let lastDownloaded = try downloader.lastDownloadedBlockHeight()
|
||||||
let height = Int32(height ?? lastDownloaded)
|
let height = Int32(height ?? lastDownloaded)
|
||||||
let nearestHeight = rustBackend.getNearestRewindHeight(dbData: config.dataDb, height: height)
|
let nearestHeight = rustBackend.getNearestRewindHeight(dbData: config.dataDb, height: height, networkType: self.config.network.networkType)
|
||||||
|
|
||||||
guard nearestHeight > 0 else {
|
guard nearestHeight > 0 else {
|
||||||
let error = rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error getting nearest rewind height for height: \(height)")
|
let error = rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error getting nearest rewind height for height: \(height)")
|
||||||
|
@ -574,7 +581,7 @@ public class CompactBlockProcessor {
|
||||||
|
|
||||||
// FIXME: this should be done on the rust layer
|
// FIXME: this should be done on the rust layer
|
||||||
let rewindHeight = max(Int32(nearestHeight - 1) , Int32(config.walletBirthday))
|
let rewindHeight = max(Int32(nearestHeight - 1) , Int32(config.walletBirthday))
|
||||||
guard rustBackend.rewindToHeight(dbData: config.dataDb, height: rewindHeight) else {
|
guard rustBackend.rewindToHeight(dbData: config.dataDb, height: rewindHeight, networkType: self.config.network.networkType) else {
|
||||||
let error = rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)")
|
let error = rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)")
|
||||||
fail(error)
|
fail(error)
|
||||||
throw error
|
throw error
|
||||||
|
@ -649,7 +656,7 @@ public class CompactBlockProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let validateChainOperation = CompactBlockValidationOperation(rustWelding: self.rustBackend, cacheDb: cfg.cacheDb, dataDb: cfg.dataDb)
|
let validateChainOperation = CompactBlockValidationOperation(rustWelding: self.rustBackend, cacheDb: cfg.cacheDb, dataDb: cfg.dataDb, networkType: self.config.network.networkType)
|
||||||
|
|
||||||
let downloadValidateAdapterOperation = BlockOperation { [weak validateChainOperation, weak downloadBlockOperation] in
|
let downloadValidateAdapterOperation = BlockOperation { [weak validateChainOperation, weak downloadBlockOperation] in
|
||||||
validateChainOperation?.error = downloadBlockOperation?.error
|
validateChainOperation?.error = downloadBlockOperation?.error
|
||||||
|
@ -698,7 +705,7 @@ public class CompactBlockProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scanBlocksOperation = CompactBlockBatchScanningOperation(rustWelding: rustBackend, cacheDb: config.cacheDb, dataDb: config.dataDb, transactionRepository: transactionRepository, range: range, progressDelegate: self)
|
let scanBlocksOperation = CompactBlockBatchScanningOperation(rustWelding: rustBackend, cacheDb: config.cacheDb, dataDb: config.dataDb, transactionRepository: transactionRepository, range: range, networkType: self.config.network.networkType, progressDelegate: self)
|
||||||
|
|
||||||
let validateScanningAdapterOperation = BlockOperation { [weak scanBlocksOperation, weak validateChainOperation] in
|
let validateScanningAdapterOperation = BlockOperation { [weak scanBlocksOperation, weak validateChainOperation] in
|
||||||
scanBlocksOperation?.error = validateChainOperation?.error
|
scanBlocksOperation?.error = validateChainOperation?.error
|
||||||
|
@ -727,7 +734,7 @@ public class CompactBlockProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let enhanceOperation = CompactBlockEnhancementOperation(rustWelding: rustBackend, dataDb: config.dataDb, downloader: downloader, repository: transactionRepository, range: range.blockRange())
|
let enhanceOperation = CompactBlockEnhancementOperation(rustWelding: rustBackend, dataDb: config.dataDb, downloader: downloader, repository: transactionRepository, range: range.blockRange(), networkType: self.config.network.networkType)
|
||||||
|
|
||||||
enhanceOperation.startedHandler = {
|
enhanceOperation.startedHandler = {
|
||||||
LoggerProxy.debug("Started Enhancing range: \(range)")
|
LoggerProxy.debug("Started Enhancing range: \(range)")
|
||||||
|
@ -760,7 +767,7 @@ public class CompactBlockProcessor {
|
||||||
enhanceOperation?.error = scanBlocksOperation?.error
|
enhanceOperation?.error = scanBlocksOperation?.error
|
||||||
}
|
}
|
||||||
|
|
||||||
let fetchOperation = FetchUnspentTxOutputsOperation(accountRepository: accountRepository, downloader: self.downloader, rustbackend: rustBackend, dataDb: config.dataDb, startHeight: config.walletBirthday)
|
let fetchOperation = FetchUnspentTxOutputsOperation(accountRepository: accountRepository, downloader: self.downloader, rustbackend: rustBackend, dataDb: config.dataDb, startHeight: config.walletBirthday, networkType: self.config.network.networkType)
|
||||||
|
|
||||||
fetchOperation.startedHandler = { [weak self] in
|
fetchOperation.startedHandler = { [weak self] in
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
@ -855,7 +862,7 @@ public class CompactBlockProcessor {
|
||||||
// rewind
|
// rewind
|
||||||
|
|
||||||
let rewindHeight = determineLowerBound(errorHeight: height, consecutiveErrors: consecutiveChainValidationErrors, walletBirthday: self.config.walletBirthday)
|
let rewindHeight = determineLowerBound(errorHeight: height, consecutiveErrors: consecutiveChainValidationErrors, walletBirthday: self.config.walletBirthday)
|
||||||
guard rustBackend.rewindToHeight(dbData: config.dataDb, height: Int32(rewindHeight)) else {
|
guard rustBackend.rewindToHeight(dbData: config.dataDb, height: Int32(rewindHeight), networkType: self.config.network.networkType) else {
|
||||||
fail(rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)"))
|
fail(rustBackend.lastError() ?? RustWeldingError.genericError(message: "unknown error rewinding to height \(height)"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1053,9 +1060,12 @@ public extension CompactBlockProcessor.Configuration {
|
||||||
/**
|
/**
|
||||||
Standard configuration for most compact block processors
|
Standard configuration for most compact block processors
|
||||||
*/
|
*/
|
||||||
static var standard: CompactBlockProcessor.Configuration {
|
static func standard(for network: ZcashNetwork, walletBirthday: BlockHeight) -> CompactBlockProcessor.Configuration {
|
||||||
let pathProvider = DefaultResourceProvider()
|
let pathProvider = DefaultResourceProvider(network: network)
|
||||||
return CompactBlockProcessor.Configuration(cacheDb: pathProvider.cacheDbURL, dataDb: pathProvider.dataDbURL)
|
return CompactBlockProcessor.Configuration(cacheDb: pathProvider.cacheDbURL,
|
||||||
|
dataDb: pathProvider.dataDbURL,
|
||||||
|
walletBirthday: walletBirthday,
|
||||||
|
network: network)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,7 +1113,7 @@ extension CompactBlockProcessor.State: Equatable {
|
||||||
|
|
||||||
extension CompactBlockProcessor {
|
extension CompactBlockProcessor {
|
||||||
public func utxoCacheBalance(tAddress: String) throws -> WalletBalance {
|
public func utxoCacheBalance(tAddress: String) throws -> WalletBalance {
|
||||||
try rustBackend.downloadedUtxoBalance(dbData: config.dataDb, address: tAddress)
|
try rustBackend.downloadedUtxoBalance(dbData: config.dataDb, address: tAddress, networkType: config.network.networkType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,7 +1173,7 @@ extension CompactBlockProcessor {
|
||||||
|
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
do {
|
do {
|
||||||
guard try self.rustBackend.clearUtxos(dbData: dataDb, address: tAddress, sinceHeight: startHeight - 1) >= 0 else {
|
guard try self.rustBackend.clearUtxos(dbData: dataDb, address: tAddress, sinceHeight: startHeight - 1, networkType: self.config.network.networkType) >= 0 else {
|
||||||
result(.failure(CompactBlockProcessorError.generalError(message: "attempted to clear utxos but -1 was returned")))
|
result(.failure(CompactBlockProcessorError.generalError(message: "attempted to clear utxos but -1 was returned")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1191,7 +1201,8 @@ extension CompactBlockProcessor {
|
||||||
index: utxo.index,
|
index: utxo.index,
|
||||||
script: utxo.script.bytes,
|
script: utxo.script.bytes,
|
||||||
value: Int64(utxo.valueZat),
|
value: Int64(utxo.valueZat),
|
||||||
height: utxo.height) ? refreshed.append(utxo) : skipped.append(utxo)
|
height: utxo.height,
|
||||||
|
networkType: self.config.network.networkType) ? refreshed.append(utxo) : skipped.append(utxo)
|
||||||
} catch {
|
} catch {
|
||||||
LoggerProxy.info("failed to put utxo - error: \(error)")
|
LoggerProxy.info("failed to put utxo - error: \(error)")
|
||||||
skipped.append(utxo)
|
skipped.append(utxo)
|
||||||
|
@ -1305,7 +1316,7 @@ extension CompactBlockProcessor {
|
||||||
|
|
||||||
let info = try service.getInfo()
|
let info = try service.getInfo()
|
||||||
|
|
||||||
try CompactBlockProcessor.validateServerInfo(info, saplingActivation: config.saplingActivation, rustBackend: rustBackend)
|
try CompactBlockProcessor.validateServerInfo(info, saplingActivation: config.saplingActivation, localNetwork: config.network, rustBackend: rustBackend)
|
||||||
|
|
||||||
// get latest block height
|
// get latest block height
|
||||||
let latestDownloadedBlockHeight: BlockHeight = max(config.walletBirthday,try downloader.lastDownloadedBlockHeight())
|
let latestDownloadedBlockHeight: BlockHeight = max(config.walletBirthday,try downloader.lastDownloadedBlockHeight())
|
||||||
|
@ -1323,4 +1334,3 @@ extension CompactBlockProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ class CompactBlockScanningOperation: ZcashOperation {
|
||||||
private var cacheDb: URL
|
private var cacheDb: URL
|
||||||
private var dataDb: URL
|
private var dataDb: URL
|
||||||
private var limit: UInt32
|
private var limit: UInt32
|
||||||
init(rustWelding: ZcashRustBackendWelding.Type, cacheDb: URL, dataDb: URL, limit: UInt32 = 0) {
|
private var network: NetworkType
|
||||||
|
init(rustWelding: ZcashRustBackendWelding.Type, cacheDb: URL, dataDb: URL, limit: UInt32 = 0, networkType: NetworkType) {
|
||||||
rustBackend = rustWelding
|
rustBackend = rustWelding
|
||||||
self.cacheDb = cacheDb
|
self.cacheDb = cacheDb
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
self.limit = limit
|
self.limit = limit
|
||||||
|
self.network = networkType
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ class CompactBlockScanningOperation: ZcashOperation {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.startedHandler?()
|
self.startedHandler?()
|
||||||
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb, dbData: self.dataDb, limit: limit) else {
|
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb, dbData: self.dataDb, limit: limit, networkType: network) else {
|
||||||
self.error = self.rustBackend.lastError() ?? ZcashOperationError.unknown
|
self.error = self.rustBackend.lastError() ?? ZcashOperationError.unknown
|
||||||
LoggerProxy.debug("block scanning failed with error: \(String(describing: self.error))")
|
LoggerProxy.debug("block scanning failed with error: \(String(describing: self.error))")
|
||||||
self.fail()
|
self.fail()
|
||||||
|
@ -112,6 +114,7 @@ class CompactBlockBatchScanningOperation: ZcashOperation {
|
||||||
private var batchSize: UInt32
|
private var batchSize: UInt32
|
||||||
private var blockRange: CompactBlockRange
|
private var blockRange: CompactBlockRange
|
||||||
private var transactionRepository: TransactionRepository
|
private var transactionRepository: TransactionRepository
|
||||||
|
private var network: NetworkType
|
||||||
|
|
||||||
init(rustWelding: ZcashRustBackendWelding.Type,
|
init(rustWelding: ZcashRustBackendWelding.Type,
|
||||||
cacheDb: URL,
|
cacheDb: URL,
|
||||||
|
@ -119,6 +122,7 @@ class CompactBlockBatchScanningOperation: ZcashOperation {
|
||||||
transactionRepository: TransactionRepository,
|
transactionRepository: TransactionRepository,
|
||||||
range: CompactBlockRange,
|
range: CompactBlockRange,
|
||||||
batchSize: UInt32 = 100,
|
batchSize: UInt32 = 100,
|
||||||
|
networkType: NetworkType,
|
||||||
progressDelegate: CompactBlockProgressDelegate? = nil) {
|
progressDelegate: CompactBlockProgressDelegate? = nil) {
|
||||||
rustBackend = rustWelding
|
rustBackend = rustWelding
|
||||||
self.cacheDb = cacheDb
|
self.cacheDb = cacheDb
|
||||||
|
@ -127,6 +131,7 @@ class CompactBlockBatchScanningOperation: ZcashOperation {
|
||||||
self.blockRange = range
|
self.blockRange = range
|
||||||
self.batchSize = batchSize
|
self.batchSize = batchSize
|
||||||
self.progressDelegate = progressDelegate
|
self.progressDelegate = progressDelegate
|
||||||
|
self.network = networkType
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +144,7 @@ class CompactBlockBatchScanningOperation: ZcashOperation {
|
||||||
do {
|
do {
|
||||||
if batchSize == 0 {
|
if batchSize == 0 {
|
||||||
let scanStartTime = Date()
|
let scanStartTime = Date()
|
||||||
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb, dbData: self.dataDb, limit: batchSize) else {
|
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb, dbData: self.dataDb, limit: batchSize, networkType: network) else {
|
||||||
self.scanFailed(self.rustBackend.lastError() ?? ZcashOperationError.unknown)
|
self.scanFailed(self.rustBackend.lastError() ?? ZcashOperationError.unknown)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -164,7 +169,10 @@ class CompactBlockBatchScanningOperation: ZcashOperation {
|
||||||
}
|
}
|
||||||
let previousScannedHeight = lastScannedHeight
|
let previousScannedHeight = lastScannedHeight
|
||||||
let scanStartTime = Date()
|
let scanStartTime = Date()
|
||||||
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb, dbData: self.dataDb, limit: batchSize) else {
|
guard self.rustBackend.scanBlocks(dbCache: self.cacheDb,
|
||||||
|
dbData: self.dataDb,
|
||||||
|
limit: batchSize,
|
||||||
|
networkType: network) else {
|
||||||
self.scanFailed(self.rustBackend.lastError() ?? ZcashOperationError.unknown)
|
self.scanFailed(self.rustBackend.lastError() ?? ZcashOperationError.unknown)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,16 @@ class CompactBlockValidationOperation: ZcashOperation {
|
||||||
|
|
||||||
private var cacheDb: URL
|
private var cacheDb: URL
|
||||||
private var dataDb: URL
|
private var dataDb: URL
|
||||||
|
private var network: NetworkType
|
||||||
|
|
||||||
init(rustWelding: ZcashRustBackendWelding.Type, cacheDb: URL, dataDb: URL) {
|
init(rustWelding: ZcashRustBackendWelding.Type,
|
||||||
|
cacheDb: URL,
|
||||||
|
dataDb: URL,
|
||||||
|
networkType: NetworkType) {
|
||||||
rustBackend = rustWelding
|
rustBackend = rustWelding
|
||||||
self.cacheDb = cacheDb
|
self.cacheDb = cacheDb
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
|
self.network = networkType
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +41,7 @@ class CompactBlockValidationOperation: ZcashOperation {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.startedHandler?()
|
self.startedHandler?()
|
||||||
let result = self.rustBackend.validateCombinedChain(dbCache: cacheDb, dbData: dataDb)
|
let result = self.rustBackend.validateCombinedChain(dbCache: cacheDb, dbData: dataDb, networkType: self.network)
|
||||||
switch result {
|
switch result {
|
||||||
case 0:
|
case 0:
|
||||||
let error = CompactBlockValidationError.failedWithError(rustBackend.lastError())
|
let error = CompactBlockValidationError.failedWithError(rustBackend.lastError())
|
||||||
|
|
|
@ -22,18 +22,21 @@ class FetchUnspentTxOutputsOperation: ZcashOperation {
|
||||||
private var downloader: CompactBlockDownloading
|
private var downloader: CompactBlockDownloading
|
||||||
private var rustbackend: ZcashRustBackendWelding.Type
|
private var rustbackend: ZcashRustBackendWelding.Type
|
||||||
private var startHeight: BlockHeight
|
private var startHeight: BlockHeight
|
||||||
|
private var network: NetworkType
|
||||||
private var dataDb: URL
|
private var dataDb: URL
|
||||||
|
|
||||||
init(accountRepository: AccountRepository,
|
init(accountRepository: AccountRepository,
|
||||||
downloader: CompactBlockDownloading,
|
downloader: CompactBlockDownloading,
|
||||||
rustbackend: ZcashRustBackendWelding.Type,
|
rustbackend: ZcashRustBackendWelding.Type,
|
||||||
dataDb: URL,
|
dataDb: URL,
|
||||||
startHeight: BlockHeight) {
|
startHeight: BlockHeight,
|
||||||
|
networkType: NetworkType) {
|
||||||
self.dataDb = dataDb
|
self.dataDb = dataDb
|
||||||
self.accountRepository = accountRepository
|
self.accountRepository = accountRepository
|
||||||
self.downloader = downloader
|
self.downloader = downloader
|
||||||
self.rustbackend = rustbackend
|
self.rustbackend = rustbackend
|
||||||
self.startHeight = startHeight
|
self.startHeight = startHeight
|
||||||
|
self.network = networkType
|
||||||
}
|
}
|
||||||
|
|
||||||
override func main() {
|
override func main() {
|
||||||
|
@ -46,7 +49,10 @@ class FetchUnspentTxOutputsOperation: ZcashOperation {
|
||||||
let tAddresses = try accountRepository.getAll().map({ $0.transparentAddress })
|
let tAddresses = try accountRepository.getAll().map({ $0.transparentAddress })
|
||||||
do {
|
do {
|
||||||
for tAddress in tAddresses {
|
for tAddress in tAddresses {
|
||||||
guard try self.rustbackend.clearUtxos(dbData: dataDb, address: tAddress, sinceHeight: startHeight - 1) >= 0 else {
|
guard try self.rustbackend.clearUtxos(dbData: dataDb,
|
||||||
|
address: tAddress,
|
||||||
|
sinceHeight: startHeight - 1,
|
||||||
|
networkType: network) >= 0 else {
|
||||||
let rustError = rustbackend.lastError() ?? RustWeldingError.genericError(message: "attempted to clear utxos but -1 was returned")
|
let rustError = rustbackend.lastError() ?? RustWeldingError.genericError(message: "attempted to clear utxos but -1 was returned")
|
||||||
|
|
||||||
throw rustError
|
throw rustError
|
||||||
|
@ -80,7 +86,8 @@ class FetchUnspentTxOutputsOperation: ZcashOperation {
|
||||||
index: utxo.index,
|
index: utxo.index,
|
||||||
script: utxo.script.bytes,
|
script: utxo.script.bytes,
|
||||||
value: Int64(utxo.valueZat),
|
value: Int64(utxo.valueZat),
|
||||||
height: utxo.height) ? refreshed.append(utxo) : skipped.append(utxo)
|
height: utxo.height,
|
||||||
|
networkType: network) ? refreshed.append(utxo) : skipped.append(utxo)
|
||||||
} catch {
|
} catch {
|
||||||
LoggerProxy.error("failed to put utxo - error: \(error)")
|
LoggerProxy.error("failed to put utxo - error: \(error)")
|
||||||
skipped.append(utxo)
|
skipped.append(utxo)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// WalletBirthday+Constants.swift
|
||||||
|
// ZcashLightClientKit
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/28/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension WalletBirthday {
|
||||||
|
static func birthday(with height: BlockHeight, network: ZcashNetwork) -> WalletBirthday {
|
||||||
|
switch network.networkType {
|
||||||
|
case .mainnet:
|
||||||
|
return mainnetBirthday(with: height)
|
||||||
|
case .testnet:
|
||||||
|
return testnetBirthday(with: height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,498 @@
|
||||||
|
//
|
||||||
|
// WalletBirthday+mainnet.swift
|
||||||
|
// ZcashLightClientKit
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/28/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension WalletBirthday {
|
||||||
|
static func mainnetBirthday(with height: BlockHeight) -> WalletBirthday {
|
||||||
|
switch height {
|
||||||
|
case BlockHeight.min ..< 640_000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 419_200,
|
||||||
|
hash: "00000000025a57200d898ac7f21e26bf29028bbe96ec46e05b2c17cc9db9e4f3",
|
||||||
|
time: 1540779337,
|
||||||
|
tree: "000000"
|
||||||
|
)
|
||||||
|
case 640_000 ..< 643_500:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 640000,
|
||||||
|
hash: "00000000016cd930734753f5acce6274b391f14330c793e54e7bd9f942d17114",
|
||||||
|
time: 1574051743,
|
||||||
|
tree: "0165aed8451b6a6c0a66294267976be6d171f2acf83c2b5b94d976cb32062cfa6301cd5b1e5ce12e7d82d07c1b83f7746ef2be8d0c56f90f82b71a1e422a1ffb400710000142f5056f23557ba4cbc562067d43fdc07477fa740c6a13a4ed6d0667b7c1b5510000000001ee9dbe0b8d268efe7e8a88ae7b0ac91923bd71ee81bba0e35e3b9504be59aa250001a2178e94504352c0dd7d6f711b814f8a332239f688568f1719808fd1d385831e0001967ca804f328397d98bd5e1f36786a9d44b06192e70a38026909fb4ce251943e000001fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 643_500 ..< 663000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 643_500,
|
||||||
|
hash: "000000000041005fd724ff6e29bd1738bed69a4d9ca028e124029525350bd789",
|
||||||
|
time: 1574579149,
|
||||||
|
tree: "01999fc372390699b15f71d41745abe6a2ea0db4ffa8894d3c5fe30b9261a1a43a01585112668685bd6783cb01b72d17dc86c6d740c27cccf66b75e959e4e4f5ea3710019b7f6b4457a97eadbe1a39bfcc6ba0a56d37010d0d799e1e652fc29733103e04016a0b4d2705e1feb2021d80e5785608536dde05aea5ef676a5427244228b19e2d00010973d03ad5f79fcac64ab3ffbdaaac1a24b74a3617770bf960fb004cbd422439000001984bfce9361025cc38574f944a3ed7b074b3bf88cfce6f14c4a9be4d91d6dc730105871ec1e3737a39bceb00b0c2d253ff36f472e92c361e7ef360d49ea8dc4c4200000001c145105e1bf401668a8f23ca70c47ee92d23bd366072020c83d26b855eeafd6d0001fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 663000 ..< 663150:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 663000,
|
||||||
|
hash: "0000000000bd422264b700bb33cab167ab42392c89db0e7c8ce30d57f346fe69",
|
||||||
|
time: 1576810013,
|
||||||
|
tree: "0102f02a8cd23e35502f8efa55893c7a145168ac3fa00d4bd032b55097bbe0335a01b57c362e3c834f2216c72ae0d8a335fd2397cc80073d0f5b29c419028bc6c94c100000000157bfd70afa37c8bf0c60c9e160d2145bdfbcf07837b0ff90bf8a5108722cc85400000000011bc9521263584de20822f9483e7edb5af54150c4823c775b2efc6a1eded9625501a6030f8d4b588681eddb66cad63f09c5c7519db49500fc56ebd481ce5e903c22000163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 663150 ..< 663700:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 663150,
|
||||||
|
hash: "0000000002fd3be4c24c437bd22620901617125ec2a3a6c902ec9a6c06f734fc",
|
||||||
|
time: 1576821833,
|
||||||
|
tree: "01ec6278a1bed9e1b080fd60ef50eb17411645e3746ff129283712bc4757ecc833001001b4e1d4a26ac4a2810b57a14f4ffb69395f55dde5674ecd2462af96f9126e054701a36afb68534f640938bdffd80dfcb3f4d5e232488abbf67d049b33a761e7ed6901a16e35205fb7fe626a9b13fc43e1d2b98a9c241f99f93d5e93a735454073025401f5b9bcbf3d0e3c83f95ee79299e8aeadf30af07717bda15ffb7a3d00243b58570001fa6d4c2390e205f81d86b85ace0b48f3ce0afb78eeef3e14c70bcfd7c5f0191c0000011bc9521263584de20822f9483e7edb5af54150c4823c775b2efc6a1eded9625501a6030f8d4b588681eddb66cad63f09c5c7519db49500fc56ebd481ce5e903c22000163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 663700 ..< 670000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 663700,
|
||||||
|
hash: "0000000000d387fab4c980e9a5b42ec35a39879706398c78fbce873d61f1b26c",
|
||||||
|
time: 1576863287,
|
||||||
|
tree: "014bd3b38c782ea2e66c053afd4c29c84fa27003b71de5f9778a631558ee7a1410001001534a90ede3e8dcb7115c84e86b2d184c0f46d5b21023a7292ecfade5e956e66500000001daeb30618bfdfa00999f2989795562775c3fdf95ce279d106c0e608fedc9ea31000001686ac0ccce56b47cab1dd4fceb48812f72d6ac6fff3a2ae5a9dcf27eda409a0b011bc9521263584de20822f9483e7edb5af54150c4823c775b2efc6a1eded9625501a6030f8d4b588681eddb66cad63f09c5c7519db49500fc56ebd481ce5e903c22000163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 670000 ..< 680000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 670000,
|
||||||
|
hash: "000000000086313791aca867bf60fc7434fe2b3fc56926ef46223c6b6b05b5fd",
|
||||||
|
time: 1577338346,
|
||||||
|
tree: "01e38b18dcf2de5e9ca5c12a1329176b37219546cfabd9333a9536d2d3ef6cba3e01c159856a741f9da500a9c83935ee7323d63f589a117e66874612e70cdf7a9f4b1001db5e89b8cbf677a87375395940f4715de1bb951f05efbbc4fb34bb1990dd80600155dbaaf5b93f338d1c629fe2a77328c7609c59c6a767a6ccfcc14d3c8c7d826100000001d9e9451fe610b3374b30c711f62a29700ecd2b02e096f02085b896d3fdc3886401006895fa87a8083ae5d0d38df876e764486c67a684706f7750ee19c872dc5d2e01f5cc54720296c3379ac6fb0aa3ed6824bcc40894b3f40d9d2e2d1ed3e6080c3501e9fc6273cadcc40df45ee63984330cfe702a1e7b4c324516d1a80ebcacc4d4170125719ebec43e9148ecc5cfdb2359074badb6fc7759817f6afab999570a75a2000171b36f07e48c45e39f1cc02a99023236f1df60ae924b5ef14ddacc7885994e2b0163f4eec5a2fe00a5f45e71e1542ff01e937d2210c99f03addcce5314a5278b2d0163ab01f46a3bb6ea46f5a19d5bdd59eb3f81e19cfa6d10ab0fd5566c7a16992601fa6980c053d84f809b6abcf35690f03a11f87b28e3240828e32e3f57af41e54e01319312241b0031e3a255b0d708750b4cb3f3fe79e3503fe488cc8db1dd00753801754bb593ea42d231a7ddf367640f09bbf59dc00f2c1d2003cc340e0c016b5b13"
|
||||||
|
)
|
||||||
|
case 680000 ..< 690000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 680000,
|
||||||
|
hash: "0000000001f2e08db1ea7ce567a5cd745de87c2eafbd769346b8212cc922d517",
|
||||||
|
time: 1578091375,
|
||||||
|
tree: "01bc7b45da508ff7e4b3dbc1184a42a646a18ad0c73907d9462199354f3490ec00001101cf1bc2f3ef2e491a4c04cede4efa561dcb4e9c56562adaa79b96ec8e54b43643000001419a6936943299e8d695fb98c78153499682d1c332efa1fbd19ce3c996be713b01e3743cb66129e262add8996fc588df0b1a33366df4e5d618ec14d0bc8129f537000000000141b1ff5b5fdad24aafa550d42cb9f99c85f6175b3d65060079bb9638cacf654e0141754203644e6f3d5faf15f16492efec723da55b2db473b34299c5582e883e46000000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 690000 ..< 692345:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 690000,
|
||||||
|
hash: "0000000000b1e6422ecd9292951b36ebb94e8926bbd33df8445b574b4be14f79",
|
||||||
|
time: 1578845180,
|
||||||
|
tree: "0117ffc074ef0f54651b2bc78d594e5ff786d9828ae78b1db972cd479669e8dd2401cc1b37d13f3b7d1fa2ead08493d275bfca976dd482e8dd879bf62b987652f63811013d84614158c7810753cc663f7a3da757f84f77744a24490eb07ce07af1daa92e0000017472a22c4064648ff260cbec8d85c273c5cd190dab7800f4978d473322dab1200001c7a1fd3786de051015c90f39143f3cfb89f2ea8bb5155520547ecfbefcdc382a0000000001d0c515cd513b49e397bf96d895a941aed4869ff2ff925939a34572c078dc16470121c1efd29f85680334050ee2a7e0d09fde474f90e573d85b7c9d337a5465625a0000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 692345 ..< 693400:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 692345,
|
||||||
|
hash: "0000000002584662ea3fb1969a65f05cf1e0c82581b885fbd723eed6ba818e99",
|
||||||
|
time: 1579021581,
|
||||||
|
tree: "01a30b15d800be77c5c959f57466a2c6dcf3e583010c1308a6956e23ec1b4658180140ead0f57ec26315bc14ac9a03ee843f34d080f41d2a682d824a02d73569446011000001d4d84c0e533c23813285e3849abff78ff36d2fc4b82c35061aed5e20a13c1859000191e51cd5f2f0afa0de7cd18fde39feb724bdc225fc25a9c75acbae1b641a7719016c33f322bc0205623943faa2a270b2925176cfc642da9625bd567e06b13c4d14000193726f6855f49bda4fb05a256bfcb17bf6ebac59b69ef9bfa73d69ac65ab2c2e01875259d77037ad0de128f071d2b85dfefd4d14c29e3fbd573abf843ebe5d830d0001d0c515cd513b49e397bf96d895a941aed4869ff2ff925939a34572c078dc16470121c1efd29f85680334050ee2a7e0d09fde474f90e573d85b7c9d337a5465625a0000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 693400 ..< 700000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 693400,
|
||||||
|
hash: "0000000001708386101e361d211b2a14f3571d0b81f5962b452d563444c7f06a",
|
||||||
|
time: 1579101218,
|
||||||
|
tree: "0110939e236e3f13fbf9a044dc4e8d0094b777ee950dca49cb0722556b08fbef2f0197c4a6daa51f5c699ba5f0c3e53b657e54e3d728e60edaf76b4e2215d6aa2d661100000001ef66b21ca159b57a3d54147b0011c096d20cb3aa9590becf8f026c9edadba61a01750454b0edee9cc2f1eaf6d34cb8e495679048008d8cf6c1ab4321bddb828a2901f3dab23e140f2c400b4d4b5e6003ba2c7b316721b0d2858c8e0fcd1f5acbfd4b01eb786638efecd4413cfaadc48a0275035b2d484b92e305cb086c581a07390d21000001a4711f58e3fa6f5d38e2f54ab424c3014c119629fab5ee8a4ed2814d7b17036d01d0c515cd513b49e397bf96d895a941aed4869ff2ff925939a34572c078dc16470121c1efd29f85680334050ee2a7e0d09fde474f90e573d85b7c9d337a5465625a0000000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 700000 ..< 710000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 700000,
|
||||||
|
hash: "0000000000c057d167a20ae61b1f77996bc72631dee6ffb11095f0d312230ddc",
|
||||||
|
time: 1579598443,
|
||||||
|
tree: "01c6b273aee226912526622b91e48a0ff5caf71f1f47569aff8a1c145102b02328012758ab750e1cb4f933ebca089d23ead6032151a38266aa020ae84557bb61844811016443e86acd06140aa932467bcc7235704cf95081e2e5faaf031112a9abd5f930016d1847eb52f8218773e3d2dd8eb19950dbe693484098d763010d7c338337cf68018117bb5e4ad68438572aaa55cb7d66b4b86b9d8310fbb4e36db7982dcc28591400012c4e84168b1c9a322f6035ddb5989fea843045d22182ee9ce45a6a8f6831954301abf6a411ff1708af6252bf921625f28931c567d92833d7ed2b2b14efd6b06e5001d1f934bce5476ef5d21b384c7dddfcbd8c1f630435acbf26a094bc46757f5d3501e6a69ddf114c92d39370a24e840c46ed42fc54a63986d3aa916a08c2a922c73b0001a626bb2ed07614f7228f79d5fbccf541699895842341602c639ab7516b1c9a1a0000019be74b905f0e99399af0fda6832324ceeeaf57551b11b42c73bcb7cd215ab91400000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 710000 ..< 720000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 710000,
|
||||||
|
hash: "00000000003adcad055353d33a0962103e284bc47577c62580535a1dd6be7cf6",
|
||||||
|
time: 1580351806,
|
||||||
|
tree: "01bf61bd9326bba72206cc0ac82791fe316277907ba76773b5ae01ea7df948ae04001101200905d2485346e39f07fd989ba05211195251968d6bcb41b8280bc94733bc5d01e44932d89c5309ac906072235443f573a92dcda2acf608c1851af01dbeab19350000000001a73367559bf511fc5212ab3f0f6754a9b7ca59a3da68588e3763c801c031bd1501eb94b48e208bdbd42bb4815940b2f9f5187cc5e42c196f461f7bc6d020ed670f0001f00ddf03aca4e8c2620ff274939a1f1cd6a4eceb147e8aa6a8ba83717d60182700010576ef08575c3dd49296ba7c2ddd914715c4f9a7316da4ae8f5600dafa1b1c39019be74b905f0e99399af0fda6832324ceeeaf57551b11b42c73bcb7cd215ab91400000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 720000 ..< 730000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 720000,
|
||||||
|
hash: "000000000225bab0e1491d6abfa4a41c174bc7d0167411e2cb2ebd960dae5158",
|
||||||
|
time: 1581104786,
|
||||||
|
tree: "0147c6af2c835328a4c17eff07f76102dc57716a13ce3d3a4f48367c3f2384fe2901e01e9b45be2ad8bedab63db1963c2b8d85e1ed20b6327cf2c55c211234e8a3351101134f80e61b548e384e87f823187d2734b07c516d48eea33a533c6cf7aa47052200000000000000017ce48111238d9e81b7e4147286578f2d686d71b1ec0cae668f567f3fef65bc0b017895f4c380f5169dcb84c7154fe6fcf72d694d30f0ba2535437b443a2cb5ae18000000013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 730000 ..< 735000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 730000,
|
||||||
|
hash: "0000000002293b9e058e17fbc357c9b676d276eba338e033e357034c775ab320",
|
||||||
|
time: 1581858634,
|
||||||
|
tree: "019a59eba6efd060a61cde70daa7b34202e5fd55fcbf809eaf0aa3252e45810e48001101e106c6f8a17723af8793c1bd0f0e95dbcf5ef0bd80e20195422d8388db48cf24000001907e2c08367bfb45d196771ad267ec773c80ff4306aa7c4d2415ee22d211e90a00000001d72bda7061e4086bb885d6f26e39aa603a1f6db2e4fc71ae65a571c7a31ade27014df2a298ce5d7f8e88617b66ef7dc1fddd854e8dc623c3dc0faaa0eb93137d45017a48dab02dd9a014df0bd310657c3b8e854e24e1137f2ffcb1db693e38a4416d00011a5c078f7dd38704665b7270ebd90366fdd0edccdf284ca1f03c6d7e0536182800013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 735000 ..< 750000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 735000,
|
||||||
|
hash: "00000000015c597fab53f58b9e1ededbe8bd83ca0203788e2039eceeb0d65ca6",
|
||||||
|
time: 1582235356,
|
||||||
|
tree: "0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101daeffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe4100010bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024750065a4a0001a9e1bf4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 750000 ..< 775000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 750000,
|
||||||
|
hash: "00000000028522f87172ecefd79b5f54547c8a756976585f29e4dc182a19c46a",
|
||||||
|
time: 1583365678,
|
||||||
|
tree: "01a069618d376feebdbf39030c254a1a3cb46d19369837e44b6ad9afb43763167300110000010c256f47b493d8d94dd5ad09a6829a0a5e346400430b222072583afad8ce847101b261be33d5db156d09fa73031e8f37b4fe4193d21c909e2c8e58d86c7e48690a016b4a7608e90189275f7bb8e70f525c333431ceaa8de9d5b119e66ce2faeb79290000017d730339d1d4bf490eda3c1fca77d7b8a769fff083318ec46a81404fef45f046013ad81619e96171627f27cd6e7755c4d8261dc7017a65753f06c6cf9a29af116201474991dfe7d598257dae28820c6058e389a897e232e737c90a5427e8f24e355e0163734115d47b641de26abf2cad5c4ac1cb438869fc91d50e66444980647aed24000000017d066851cc49b2ea0cf9fb6af00adbb1cc3a0b15cb02d39e0a66f031b2dc1f230001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 775000 ..< 800000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 775000,
|
||||||
|
hash: "0000000001325ee365bb14184794c700485f4e40142678bba749a54ccbc91aaf",
|
||||||
|
time: 1585250621,
|
||||||
|
tree: "014f09c863f64727b7cada08271c34d1ea0ba728ad53ec979c25bcab5a902afd52001100000001a182b7bb8fd9e872892c872fc813b59bafc3b517e55a714ff7c4ae45870a1a4a00018133f585dd7c438f78ee970e97036a471897cd5cb8df897ca46b7f2ae6567b00019338310381f33bfdcfe40b56ca7aff105872e6284d2953c287891201e75a237201e99c0f7b97c5856efabcd2fb46ab456cf5d811c3c39aabbdbb40daa814bcad6701e97f12a640f75d28510cbb7d4cad99d46903017fa9caab9905c108ed13e3c62e00000001e07372caea187301a24f9dbbe3b6a8981bb4225b7f4b362b01000d4b0a0eb071011545fef7ddad5a52664dff5a73fbbb26c2cdf42aec9292349773079432d5bc46017d066851cc49b2ea0cf9fb6af00adbb1cc3a0b15cb02d39e0a66f031b2dc1f230001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 800000 ..< 820000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 800000,
|
||||||
|
hash: "00000000013f1f4e5634e896ebdbe63dec115547c1480de0d83c64426f913c27",
|
||||||
|
time: 1587134100,
|
||||||
|
tree: "01a8689663d3c4ff2bb9aaeb7b75e66a7c68705d147bea9fe67cf7f1ffa9a071720011000196bff8c908d7015ad5df6bc5f5268a157da076c5d2ba63d222f0353c8810320100000001b0a0c048035d6f3f229bedadb2fb7688d03bc49062eae092666a8a55883afb0d000000013a365306be60039724201a594b84cb24ae09ea92a3077722da662289471f6658000184abf3f567f42573deb9e2ae56557fb6a763f16f90577ba5511b55c090eb6f2e00014da3714363acb83872f51c87fed3d42a1093420c3cb96b74ad65966ce27e8c4e0001e2bf698f5ac10b44da560d11a5e1d5c191a82a968a2be0a6948aa8748b54516001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 820000 ..< 830000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 820000,
|
||||||
|
hash: "00000000001bde1cd7d26b21c7c0a4eccf3c16805c6e68f499398463fa91ed93",
|
||||||
|
time: 1588640783,
|
||||||
|
tree: "0127679ec6e5f7205bd7088782922da4afd0606bf5404faf74feeebe5f548d3639018f80d63358b79bdbdd5a19c6fe3c76e8542f6a1a309ed1dedad95fe3ca5016681101f1a4674cf60a7a56e52fde0a308481a4c9b77f059687b965dffcd67be7c4a83101ed990844ef4a7751262755367e6e16d5e351f190fca5f07124a8f71efee2cc1900000001e83b41c625d651681527f2a95ff2925b96f77c1311144e191da1a59303e39a4200000001f33bcadb822e6d55ba2fa044e2c790d957bc8dd7a6ea773d92114517a97ea76501e0b92e780e46114e308d615f417d051613215bc5974946a4b056013d6351f52401ae652143148288b1328e1b511803db03fbdf319ee20da5c7e49374331c525d3a0000011e76743978cad6dd5263d5a654db307368cb997b0c984ad51018d007c955972101e2bf698f5ac10b44da560d11a5e1d5c191a82a968a2be0a6948aa8748b54516001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 830000 ..< 840000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 830000,
|
||||||
|
hash: "00000000013284f6e727ed7cb6365726a044e050d0009ca4bcfbc7bdcd80f319",
|
||||||
|
time: 1589394076,
|
||||||
|
tree: "01a6bcb9b2f15aaa3e69ca0c0688c18b8859d54c9d6388f4d5fce8f72a2bfd990d0011019bcf88f0f1cf6d4cee6b74231c9466cd13b5e5390d4e05fdb1e4f4143cdf7a4f000000000145e054aa42c1c6f9a70581e04b05a565c9e6e2faf8885e9b76afcd841228715d01a20db43a61e0bc593598bc42c7b10c31194385c8fb00543cab4d4756b3eaf9030000014bb574ca908dc46d48278d9f5039b7d93217ea00eb63f682321503fe5b42b03f0001d6bdb5e3f2e34961d6f337c416704b74d0df45349b7b50e30cfaebea4934db1b0001e3586da44e3b0d6a0776f967e86c9bb7542b070ce52a7baac5a8e2a564780743011e76743978cad6dd5263d5a654db307368cb997b0c984ad51018d007c955972101e2bf698f5ac10b44da560d11a5e1d5c191a82a968a2be0a6948aa8748b54516001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
)
|
||||||
|
case 840000 ..< 850000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 840000,
|
||||||
|
hash: "00000000000a0b9a8753dfd46e1205590d35f4d365437a0d20d29317b33743c0",
|
||||||
|
time: 1590149064,
|
||||||
|
tree: "01101f7b8112735869abc0e74dac1f272935d09725ff03cd8cb63d472e112fa82a01d635e219273ade2859554e5191898ce9a79cb80f62c272dede1c2a71e183e21e120000000000000000000000000000000000011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 850000 ..< 861500:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 850000,
|
||||||
|
hash: "00000000007b5c713129e71fc1496bcc321cd6cd3efec262c9fd73eb90695faa",
|
||||||
|
time: 1590901979,
|
||||||
|
tree: "015063008b28e034d7515616a1d975646927df30ac4f13d96ecf3f7ec1ddd49b26001201ff3ab46b9dedd6374a80ddcc746a63b05f9dacd6dbd21f7e0df00ec6df0156520157bfc70827a774ac00c13012ac96a984d75c54a15605d741f647923d531021420000014d624d2cd2908d1a438f4a70ac392ba151c7167095553556f23ca5612475224001b97205b2715b57b9f04451df4474c73586e8fc438f989b057cb83c24e7c80d5d0001d0ce3df812f137bfb07e56795014bfc66297491dde457df799406286d7287e1c0001a8e22e1a09d435fcf20b2599688e7094ca46d2c273ffcdfee0ee80eb3e1e4d2901e469171a108b4c837f17a8f67f4d02ff9688acc825d2e1ce1ad3f8b24ff1346c0001a8ee7010fb0075cf00f14f7541c57cd0e18167ac8b98c1b20454d3618715811a00000000011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 861500 ..< 875000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 861500,
|
||||||
|
hash: "0000000000f1525a1691846ed82b5bde1d68f5472a88cdb46e2614a0471c2bb1",
|
||||||
|
time: 1591768624,
|
||||||
|
tree: "014c3e4b358ad1a1095473984cb037f6b3a326e7c4d6243371b96d774be49d3b6c012f872ee6f08d4348ac8784a055ceca2003b5652956970110ab8ac34662056a6812000184579254ecf2242817a5372a6c93e695d520ba6994a1549722ef6a1e06c4c241018cbbc978565f1f0505facf3761bd072a9bcf0734c49dff1f0f8a40ac0b02ae0301cdac68e2a12c011704388b381617237292c4a219b56b358999f3cf2196fff53d00000001c2fd85c8cb0e8ff63eaa7722a58aa6fbc6298afaca10e3bd3131e6cdf4f3fd1101931ad087d1cd97f85debd36de84dd1f8b3147d82e7c21bf8f68d9b444fe2c86d0001e99fdf5156ce831cafc19295c3239f54727ee3c8e6a9383da5e99f0d37384c690125cc58b7c9dcf14d773e7291fd53fb94371be34ada296701fcda2d1fa903da1f000129505087ffb37278c6371e20c51c2c5dfecc8317f6b0a676137f84467c4ba621000000011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 875000 ..< 900000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 875000,
|
||||||
|
hash: "000000000001f4b0caae8da2eed537aedd4a76d8671fa668bad870995861296a",
|
||||||
|
time: 1592786164,
|
||||||
|
tree: "019e1115ee6526f412ae2f8185b6f1e41e1288daf1c6e4629c32a12e1880211f64001201fd273a938cd5f5fcf70a758fab2d852efd000db4b6b7a8da860e8e48a5fe7614000000000001ff7f557fdde5c41e043e2fa0160e3b8a7fc0331462d1cec6fff3db133e3dc64c01a71c9ce180b19137b80b28137bb5a393bbc26b4b807faf4d57984d1f98b7fa45017d8e8e44760406694aab9880152fcf2d71a0d3967fbf001b77cd9751d61e1924019cc66c08d0b19b5fd3d69f32be1e76096ceeb1b830532eea9ec8aeea5d91076b0001c93ef42efb351f52c49ee3280457d8de5a657015eb9e5a28c6b63c020c18de13000001166bb2e71749ab956e549119ce9099df3dbb053409ff89d0d86a17d5b02d015d0000011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 900000 ..< 930000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 900000,
|
||||||
|
hash: "0000000000d99076161c66dd3e86db9f9390921cc8b0ad7d6eface3a5d8ecb1c",
|
||||||
|
time: 1594669980,
|
||||||
|
tree: "0162267b975eb64d5e602e9bfa63c56b1326e8eab6fa971847f2d4f8f27d26f90101cc33a70cde4e4e5f5347034f44b503e8660c7380e596961ccab15d7a64044371120140d08a6c2958e7283c3e95053eeb3e5cf502d5857a961e107c8b37ae00dcb30700019f7e8cf60fb1b31d852d6786fe74078ff1cae30fd982ed2ee11176f96103622301d3f9f17d782359f08d500309ded4ddc1488c86906f3bd742aa95b8de0f189524000001b64361426e35478691ef23c34cf977afab4962c0d7d1998b08ccac635149524201a73426649efdd3a6bda5f8a253a4823f8558dc16d8042ba071f13c0575a3955d0181e81df06e97ade7989e0ce8790f75f1d34e6cfeb4347205c4aaa7adf90a180e0001ecd87912a28cfbe4f34bf57bad9827e4013d8d4c8e85c48bfdd06c35eade9920010d393867f4f2bebf9f603bf827dd015aaf3a46dfa8b68d86cdce07aa4fbb97240001d3ddf137881180d7c5fd73d188c4346291168bde688643855eb3cd5f680f9c0001166bb2e71749ab956e549119ce9099df3dbb053409ff89d0d86a17d5b02d015d0000011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 930000 ..< 940000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 930000,
|
||||||
|
hash: "0000000000a5b606b5e99c3f155158993395d4b624e0ead68bdb3130fea8c720",
|
||||||
|
time: 1596931609,
|
||||||
|
tree: "012ee9cbe55d438e5fdf9fa2df34a989514d038fc50d5913303221392dc3b33257014c2cabd5f58b23406cbcde4034d5b62c3023f30ea9a0ea5ffafb66fb7e4f000e120116683075450cb081d897a78d86224019865ce7e3ead189e74286be307f43ac5c00000001b9da9a7344e04ad7be9cfbc57c89e840703264f5692060a5ea4f7c2e201f5e42000001a3db46e41c1c7e1026ee8b49b9a148f53b00a9c728f72b996c2dc8fafbe4cb2c0001bc597d37e5f726d22ddbe544885571ac89f5fc1746c3e7e198d0bbe85b77196a011439e56aa582ec419f2a0004222be95ea1762876ea33912c5830ab4e8bdc02660163a8ebc9ee4b289becb230ef62829a8c8b4820fcd11409f0b4c849190155a65f00000001f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 940000 ..< 950000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 940000,
|
||||||
|
hash: "00000000004f3d5203454e18248bc021a2afa1a30b6517f34cd9187f2b8e2489",
|
||||||
|
time: 1597685856,
|
||||||
|
tree: "01dd59466cdc00ee8ceb305d15c25ef32aa2d96b7e4536e071c1d14e67aee9ee0b001200000001defc97883745ef01fbca65d4e5c0f8e22b7714b704a1c36fe8a851fdbfe3a1160178cf44f19dda025a44490dd37b96b83758d04cfa3b26476e129173e7c70cb103000167b3485f4aefed9426fc301de1138fedf6949fc806c54acc2b86d897cb6a2041000000000103e2fcbb87cd5fb954d55d094943fbac487ecda1384a8fa7dbf61097a9755e54014104c9c36ff1a2e7eda524840463de4e2c02f10412a33dd754564d76f458c525000001f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 940000 ..< 950000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 950000,
|
||||||
|
hash: "00000000016bed6cb8b8c2c09791cee821093484fd9ba0f3faad1e78e0d21c17",
|
||||||
|
time: 1598439138,
|
||||||
|
tree: "018b0ff026a6c3d70e5592d7b42fa829ec41c5a86faa2d12cbbcdf81e039cbee5301f4decddef8e3183dac4de8d1b9aa3918d7df9293aae3c1931f99a253149fb65312019066138ebf0e6cfefbe9cd7876aada7d3f27834d604f827b56b7a56e1a7b551d0000018d080dcdf356c41f5a86d2062ca9e617965faae9b9a7ea678d3799f526a353130001a5ba52f3a03ce38d7d48afc3d2c9e6d65e90dba09b53ad3d3a5921267375de5d016b84dd3e9242073d7069f797bc81a4ccbe0d3847a3b3b4d1376d9e6d61446605015d52a3c83f77ec5c8e823143e74569c0040e1cb58d2a170ce907ae010ba29c670001be5b81f3b1b8a035bd0894392b0b78bdae4c57f206d3875b933de545f65bd93b000000018e1d474609c9c09894638a0ab3e656aadccaf7ddf12bcc6b6ece44a4cc79e1140001f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 951700 ..< 960000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 951700,
|
||||||
|
hash: "0000000000e304a23ddbddd62d5fcd7e6b236afe22e529f1ba88f4dfffce432f",
|
||||||
|
time: 1598567019,
|
||||||
|
tree: "0154365cc76299ab7ddc51a9fe6fd63babdcbcafbe6d7b293c43493e4ee4dcaa2501fcbde4337c2a268da9e63035ea372706af6c3be6a7dca7ddb39e9f2293835f381201e7134cc658434206a1fc059bec482c4ea3abdb49f51f367dcfc6c854deb573410001e6dfa615206e90b438eedc5cb42ab5b8a1444ed442581f45813fd1a810cf246e000001f8a3271cd56cf8cb3b01b446cfd1e7afeab070a1d7a356da16858ff2d1636b4d01de38353596f623ce0028520063828e4720bfb4ecfcc3fc103d78fc0cbe7af64200000001064fdef5644d3f4f27cd28df0d3b8103c4822871e2883bc09dcf419f1444c85a0000018e1d474609c9c09894638a0ab3e656aadccaf7ddf12bcc6b6ece44a4cc79e1140001f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 960000 ..< 970000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 960000,
|
||||||
|
hash: "0000000000b5b5e0ba1c01f76b8105878ea3c2f11da53cb0ec684f5d94365421",
|
||||||
|
time: 1599193083,
|
||||||
|
tree: "014695c74583a750216dbc0aec38282d86fc17b595bb45a74bbee8fdbf46b5313e01c2253474715b00c618e635815bd16fb8e6368fdaa9bf8f4a1aca34ead6a7eb1c12000000010cf46f452fc9101af9ca34ae364a1c2e20bc05d454068cf1407a2ee3e0c9ca6700000001091c0b4153defbfad723bf14e1ccd07c0258ea1fcd6e9e8cf759834112ec3036000001c2c980c0777874ce748ca549838324eb775cb2ac7a8d42793edbb05ac15c5b4201162d1417d8b9659ec93ac26ba1a888719a43ab1fe0b46a33c05c2aa55fecb41b00018e1d474609c9c09894638a0ab3e656aadccaf7ddf12bcc6b6ece44a4cc79e1140001f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 970000 ..< 980000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 970000,
|
||||||
|
hash: "0000000001dca1d101526285476ddf0eef6d238d5b01b7fae8062edfc09812c3",
|
||||||
|
time: 1599946198,
|
||||||
|
tree: "01d9e6147caab719ae68cb20d976c78437634e2c999ef3a09c6ba35086d443703d00120001019d135be7b1db088c68bd76703ec2b45066bb1761619745362e61dcf55f644601d0c8f296479a73722c2e2a260ab7017b9a9e6d084b651289cfe6d3c7a00ff54e01f853ab39dbfc81e2aabefd231d3374ff794028168c725ad465e61205692fef4b014f13b6e4475cbd004b4d95aa8205ed7338224e13627ecbb19afd1937dcbc0818000185b4f1ddee3199cd1f7913b223c01c4623cd9d0e1b47df4e36aaca7717b6331f011d6c8ec914cc312ef0962d52240308b22a647f4cbd2d7c2fd420ad5fbcae5619011e43cbb05b8efc885531367e5f611fe7ce7514131be892cce3adad02e151f72b01f0d7e0d589c7e5f8fff0bdd5037aeb5d5d818d413262758c9915ded705e40f70000101d26ff60e77e23fb86a52da565c22d76f81df7f25d543ec0e58a0d692d4be2700000110b2bfd32a99e0b982a41a6dbaebf783bdb9d6af795f5f20056ce7317d15ce1101f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 980000 ..< 998500:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 980000,
|
||||||
|
hash: "00000000005de60d31b653cdf1637f1bad62af844c6c51f38557a4e8bb74e2d7",
|
||||||
|
time: 1600700163,
|
||||||
|
tree: "0184330bda72e9596256847a9597d7d9476aa3d69d9dad2149314751e708da206601cd8a1a61df1e80514cd2c0a7faac8b8d7ce27d6d96bb63cb7c61c1f33e7c654312014098788b75f26108d93f0429202ffffb6cf9ffffd7278383e4d8ad2af642264600011c035ed934a11c1b48e24b6be9b2d483e7747dd082f06abf75f9a092b34cd33c01be00394a99bd33304fc4343cd928857ae7c09c176452f40d9815f9ff3ba3865d013bd7218072e1588aea0568198d37e0d83ba75f155c863355974c4eb864de0103019ed27335bc5452e320ec22a30cfe61508929016157ff2a555181a9a0623e725801328208bea2c5c83487effab780cdb36b4b82e6e7290b06d98817a160f3d79d2800019ed6779a1724a107807baf4dda9481fb940f50d85db701dda43a0989c2d62535000001d1e806194dbe171d4ad1ef8c73c1a469130caced0e24b04b8acef91c42be7a56000107771e04f7d6371bfda40ef9e04419a25c6563dcd359c85bd501de28c3c7f3250110b2bfd32a99e0b982a41a6dbaebf783bdb9d6af795f5f20056ce7317d15ce1101f1c57245fff8dbc2d3efe5a0953eafdedeb06e18a3ad4f1e4042ee76623f803200011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 998500 ..< 1000000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 998500,
|
||||||
|
hash: "00000000014cf0915c4f105140e846c62ca6f2e321f4f717cf6762a35c6e8eb4",
|
||||||
|
time: 1602093677,
|
||||||
|
tree: "01b86ad8964b68a9a316a3038af14ac9e557a6eed614ee5d337c9fdb8887e9dc6001b71fbc815cc014a7f68648fcad5b9b72920b3d21cce406b5f593a0eab6d91f1212000001aede58c0641825b7531a8b296b9fdc7393090b87588893e8dd5160bd59b2e16300000000014fa30e43b641cf67c84cef81083b81bec3bd677f55def5c7bd948298e64690560134ac55ded091faef2ae8a1043704dfec41b1a95c4cedf1818574752bc40f2033000103ee02ae59c6688dcaadf1c4ff95e7b1a902837e4989a4c4994dce7dac6ecb20014ff8c0fe6bce02ac4ad684996bfa931d61c724015d797642819361d611ebd61201c7ae83949d9502b0eff10618124d335f046e4aae52c19ccad5567feceb342a5200000001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1000000 ..< 1010000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1000000,
|
||||||
|
hash: "000000000062eff9ae053020017bfef24e521a2704c5ec9ead2a4608ac70fc7a",
|
||||||
|
time: 1602206541,
|
||||||
|
tree: "01a4d1f92e2c051e039ca80b14a86d35c755d88ff9856a3c562da4ed14f77f5d0e0012000001f1ff712c8269b7eb11df56b23f8263d59bc4bb2bbc449973e1c85f399c433a0401e0e8b56e5d56de16c173d83c2d96d4e2f94ce0cbd323a53434c647deff020c08000129acf59ead19b76e487e47cf1d100e953acedc62afa6b384f91a620321b1585300018179961f79f609e6759032f3466067548244c3fe0bf31d275d1b6595bb2d486401b622d3f80d8231c44483faa2a27e96e06a2e08d099b26d15828e8f0bde0bd42001a8d1f585aeceb5c3f22ffb43014fe89db9f7efc080361d4fa4e8d596ab1224400103ee02ae59c6688dcaadf1c4ff95e7b1a902837e4989a4c4994dce7dac6ecb20014ff8c0fe6bce02ac4ad684996bfa931d61c724015d797642819361d611ebd61201c7ae83949d9502b0eff10618124d335f046e4aae52c19ccad5567feceb342a5200000001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1010000 ..< 1020000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1010000,
|
||||||
|
hash: "0000000000faa7ec382bf9c0c1abae839f663834f8f307a2141b1403bc85fcbb",
|
||||||
|
time: 1602960322,
|
||||||
|
tree: "01f89aad9f6ed7532fc8866580ad425ba2a63ade58b064be8448804ccf9a60fd68001201dd7166b177a37db095801301de34572e69cf151db80201ee08d677c8a1a7986f000001d30d2ef05fd6f29519da13f09623f440c0f8dcc8154c56dc7f881c77c3504f2201b3ae640c5770b95f68aa24c57c32c01713e450c63b1bc5535ebc81ef2a26b519018611a216a563b1cf44cb1b27821c076869676b7b341a5b4f2cef10e8896a364101091d319cbcb2ed9b4caef347a32268ca70012899b85cf438ecf4bd6d6700c04e01337e6de0bdb259c3bd864fec2617a2cd9e127a7e6ba4212a1a7b9ae8c65e2d1c01121f952ffbab89fac050c927d06f855f8baa39ceb1584a5144c32b45d6bbe35a0110188995758e67a4c8a9e71aaecc9a7bc94e085d189252b385eab74587424e5c0000011ed4073019f93951e17d7e19f48d922bb6f3a9aa1a4827e619e0ae791c9539240128e88325aeb1eaae03e9085f4128fb62f367aaf4a6340dadffe427c1d66aa445000001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1020000 ..< 1030000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1020000,
|
||||||
|
hash: "0000000000c3c4887bd6f5d3cbf9030914e6d1bdd51370ade6657e831d9e3377",
|
||||||
|
time: 1603714448,
|
||||||
|
tree: "014f6722b03c84e99cb0f198c604fec8c1c395fa726f403e239a66b124d4ee2f7200120001d6920ed4fa9340ece9cc4918f8b5aba3b0ebc5be16831e7d56e6acc93a7e73110001c6cc38510b51ef7ef6dfd1d48df4ef97de8a52f19a9964ecb53301de1057760d018c66fe955d1c4a7dbeae31896dda4cc0bc7824abdea432101fed279a628f5a4f000001935ddd089f29e35bd356a176191995f91239127eb93bff018a3447f80615a05100000182e624e6852072075532264ac2cc76bcc92327ce55e1dd464817d4c6b9637a6e018d5dcc90c3e7134891d77aee71063b8d542b337e4d43f55f0db9cef746f5a732000001bde7578541c07920c1bc94312596adfcee32519cb80a95bcd06a1272c127ff020001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1030000 ..< 1040000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1030000,
|
||||||
|
hash: "000000000216b8552281f6b73332ec873e0eb062f9b83ede4f3102af78446b7c",
|
||||||
|
time: 1604467637,
|
||||||
|
tree: "016f037481382b438c1a41d74153ee8a6131db5a9fcfa2526718e7b4fa1577e658001201622ea365daf3d6cbd5b712bb33b77764708d69f852b903f053c47569cabd930a0001e2175829e38f95f1b3415bdaa796a732d83da1b137e1b0aecfa9802b8c8e9a540001c783c98897bc46693d1d2d2891489663f0d9ff12b34f28b3db5a841236d9d76501d671aaba2921e416e7b7b81a89cb8e524cb6c49d89c575e04e0da0461799216f0001ba538b78350bfeae6538bfac75fe8709eb59bb72f6d74d64c92df41ac1e464560001ef2204037f952a1365afd291acf2361dcebda719b5e659de073ebe2f7f3eae1a01264c173c66e9b7c36ac9f7a6c928600107fa40f11b8d81862464f849885c50620189c3e3ed72b0d445f043e2d2d5ec23c693ef67b9a15488911ad35480a6041c6301f7f497a2f9ded8bb6d14d9f1bb83f43396270e1fc7e86c2c789d9b74b9d2d3070001bde7578541c07920c1bc94312596adfcee32519cb80a95bcd06a1272c127ff020001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1040000 ..< 1050000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1040000,
|
||||||
|
hash: "0000000000852680280d876e4870ca18242527eb247994047dfd4b2601fb1fd1",
|
||||||
|
time: 1605220381,
|
||||||
|
tree: "01d4ad84ae2c7072a2632e767ef7d38d6adb125d76b2780d0dc32eb607bf839b3a0012000001677d02da42c17e72416ef72a07d165a142d3ab2d1363b07219c44b220bc58843000001035218b5415347549dd0315585ee95b8b1f811d81aca93a551478e3b04d0a527015df8455e3415c857ca94d357d48e093391715644afcfec96656b0b33bbc8592e0001d722471e81e674f55400ad26e5730a88e4a63138cc741c0aa40961ec9ce8076e000001c4d6088cf30ed54a892b82679f9531247c8dcefd1501d47f45bc35095af2e7070001347a0b5c418e301923ccc684d984b80b8ac1f52888b6d6021f7fe3676eafda1201bde7578541c07920c1bc94312596adfcee32519cb80a95bcd06a1272c127ff020001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1050000 ..< 1060000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1050000,
|
||||||
|
hash: "000000000174c1aa6e70950d51e574311da9fe75b0ba66c38785c8934a00ad3d",
|
||||||
|
time: 1605974807,
|
||||||
|
tree: "019c0533c31d2d90c2ac6d8c9193bc9d57cb77ac24993a93202dd97ee8586dac72017ba6e3eae1efa5fec05a764fac9bd552caeba096e73840c4d6d71a46f3ca0f6b12016388275ca6bed5564c68f57c17aaa50e209a900b8f257b60c7e548d39946dc160000014d6580e971d6502e2ef9278cd5527f07c96ce26548d8e13e290708e517e6a40c0000000150d24a2ea34b9eeac3f79051e6ee9dbb8c482083a57ef1b1ccf5a1f164a00547000191cbb6ea3483a6a60f6598710cb210392b7469be8f650c7ea4491965e51fa51b01f0aa6de369775a9747bf7d5f034ee6a7604437f497ca45df942a45c53a99e93e0001e2aeb2d8da652922c8714924c41335140a40bd1c966dc611a9d88058839a881901347a0b5c418e301923ccc684d984b80b8ac1f52888b6d6021f7fe3676eafda1201bde7578541c07920c1bc94312596adfcee32519cb80a95bcd06a1272c127ff020001b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1060000 ..< 1070000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1060000,
|
||||||
|
hash: "0000000002a74e26908b2caab798d341430d83a012aefb113d9707acd6eb5162",
|
||||||
|
time: 1606729750,
|
||||||
|
tree: "014dccd8971611a03b3698c14e48f76d2526109374c0336a4aa0c0559567fafe0a01f0875252b1ec66c1835e362c19ec570b02b47c5a284477adc599f4868535370812018c94b59acb73c782a3b3b2d9c46babb6f6ef03e413b5816794518b839bb8d360011061c3e44c652e1ba70b85886fada65fc781b202335715489e21ebd64de8d92e01af2d971d01ebf43d4f1b99f500fe0a97e2068bf1ee03ac6e309316e7be88f221000143b8807fdc7a87ce8623370eeef95140aaf315c9e9df7bbf64a4faf34f4ba213000000011fe71b62cc883a426b1b623e3df4c91cae8de566fdc9a746253d6350bc48451c0001e15174bb37ccc2ad5cba5f9f879d459bec83e975afe6304d23980c0ab87fa34a0000000001891b1e6bfec42e97c79ec505c7ae1b584cf47d4ed8f6cdfcad815b02a5496f6701b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1070000 ..< 1080000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1080000,
|
||||||
|
hash: "0000000001a6faf5681b8565d50145fd84547b534c5f869e77cb802518d14341",
|
||||||
|
time: 1608237278,
|
||||||
|
tree: "01f3955ce270f5718bf68883ed37b3b9d2de8fd77be7bd95334fbedc6083f16026001200000001bd5dd7584bc157cebc9d63c7ee761ab453892482246aae3ef9db17de80b84a4b000195fa995a764f9afbd6c14984dbc72175f49f2259bcf0abc4a82ac92446532c44000168fb4180546c77370ff4175d40a29c357e5787f820e383028243ba623fce4e61017cd28108a3c64a8923444af9b7409eb5dda47d8536cf5aafc80abf62e9551b3501fc0832fb90a473de0da1ae7f62b03d547655aa82d1f279c5ab5a997d6472085901647f2444d093ad8668eac738fe0ff6b59b8191bcbc13dc53f581e64de755122a000101e8d7f1b32b8bc1ec539b93f6c2912c839a55c36c509711340a5cf6d1803a360103bcde16c3ed62026afcdeb7c33c7aae0bbaaa357e8d67a10457244bdacabf4f0001891b1e6bfec42e97c79ec505c7ae1b584cf47d4ed8f6cdfcad815b02a5496f6701b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1080000 ..< 1090000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1070000,
|
||||||
|
hash: "0000000000e69217b151ca8349e3c9f0c5406877554924d7a4f90fb6434bed9d",
|
||||||
|
time: 1607482606,
|
||||||
|
tree: "01ea25320fb5dffce1469a9018d2dbcd02bc16350761c1b24ef1f7c282ff3e70070179ccaff1ff2218010dfdb5e7cd8ab67c27c0f578fc94133fa2db58cba2a1b83112013d996c5be4fa4e5d75fb2f782f02dbaec8582a86a4a404397c2ed5bbb75b1660000153c736227e8f11677599ac536a2d19a2000035609833788b19062cbe075ea20200011a38e1599c81fa7039f159cee2ef7144f23c729ac1d235d1d81ea111ba1c8e520000000001aeda840e11db19f50b7b64c54de8a389e84a5e64e8c3ea8f4861503f587d9b2301802a64566b4a1fa471e350bd86ef0409f6b4712a8fdede1c537347f41506884100000103bcde16c3ed62026afcdeb7c33c7aae0bbaaa357e8d67a10457244bdacabf4f0001891b1e6bfec42e97c79ec505c7ae1b584cf47d4ed8f6cdfcad815b02a5496f6701b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1090000 ..< 1100000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1090000,
|
||||||
|
hash: "0000000000a48d9a9ec16a0ee42afba830507824086335e81290a55dfbbe0a0b",
|
||||||
|
time: 1608990684,
|
||||||
|
tree: "01bba893b54492e05be51cc957d99591f60e3c30b7bbc134f4a79e1219721d023901ed7c0412fd24ccb7919323fbfe9af815adcc0c4e29e581d5e10cf06ebc5af823120001f98603677f74513affc6586569aa76c60766b4249a25118ddcefef18698a2c6300000001dd255f2e4e75b7eef0d5b4c077025792a979fbe44e4b7fde9a1273a3c4d6450401aaf59d640c3cd74fd1cb67396250e4b536de1d300a3c17783ecfcb5ddeec9d3a0001d94a0cf0b8ea2f688b1e107cf6a013747f5f0af6543552291adda1c28668da6b0001ab131afe01856dc81300246b7df2fdc556fcf764cb3bdeea33e83507b706a0420000000185555efbf4f751c9c4a7068f9c1c3303bc33bc8bbd3847a6fa5b6d5b3d547f6101891b1e6bfec42e97c79ec505c7ae1b584cf47d4ed8f6cdfcad815b02a5496f6701b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1100000 ..< 1110000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1100000,
|
||||||
|
hash: "00000000022262ee215e5b6269cf159b4c9fb89b8a38f70873dde8dbc4c64669",
|
||||||
|
time: 1609745782,
|
||||||
|
tree: "012f5514d9c08767fcc3c8c2cb6d7e00cb68ff2eb69ccc869821f3c901a495fb5c0121aab76f6b245f76d9a89c82a5ba88c6b427bf0154f1689520e8a24fefba106812000001c2965bb8fd73128357ae46fd0451ff0d34a4b391a4a7d54c8d00dc00277b5b2c0001bb34e1eb64d2bad151a251de23fe7ab0d92c0d8125fb3c3aa8ce0a772ac1f83701c45242a1ce86ebb47c2abe6ef76f814b26f56b5883e5f0c520266563633e5d5600015b9ea4977075a83dad3e5e4547f93369f81807b960fa5d0377fea025dc47fd25000000000001103bcd926a1c140a15876ce5dd6bb4e0a32172f9fde5de340bd11fdd87d696670185555efbf4f751c9c4a7068f9c1c3303bc33bc8bbd3847a6fa5b6d5b3d547f6101891b1e6bfec42e97c79ec505c7ae1b584cf47d4ed8f6cdfcad815b02a5496f6701b7fc5791e3650729b7e1e38ee8c4ea9da612a07b4bf412cefaffbab7ac74c547011323ddf890bfd7b94fc609b0d191982cb426b8bf4d900d04709a8b9cb1a27625"
|
||||||
|
)
|
||||||
|
case 1110000 ..< 1120000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1110000,
|
||||||
|
hash: "00000000019dd5701deda91aee19f653d7d89983fec6253d5728b738ce1cc575",
|
||||||
|
time: 1610499871,
|
||||||
|
tree: "017f230e3a91ab56970595bc9037a6bb38b69390070076c46f9a3d364f96171701001300011ebe10c1b67824d2b71e48010a03f817d80963999e15e3b0364eeccac01e2e70011681651b3c5fe38d3c35445560b9a4599f9370e618c1e72f2b8a69efd47fc9720001ec4a3829e823478478cc46af80d6d4c6b947b422dea6b525b18986dde5698a370001b52370947e83349c731edf7c5ef43dc7f9b14ca47074dee8fd16b14c5663fe4a0001d5b32170d5ffab2c95ac01821260f970881c8a3fb5770aeac7739490135e152f0000000000000000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1120000 ..< 1130000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1120000,
|
||||||
|
hash: "0000000000dcdf40c671af85eec40424e0475fecb06355fb5e37efda51f5dee7",
|
||||||
|
time: 1611253575,
|
||||||
|
tree: "01da06acb487d1ceaf8db4dc5ad8183bc8b4e9a4b020188336624bcd83adb7884f0013000000000187183a83d396d7d50514a081195ee24703202e0ec9e3196eb3bdef5e34354548000001d446400bb7cf59eac909c183eb8685cf6cc4517496708ad2bffd07acc46ce524000001e240979184856d63a9bbf849eaf06963acfc861af5a44a30e82193792d58fb4100019498b9b148ee924288e2225a474f2c9a7739500cb3c4821a52679f6a0a26d41000000000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1130000 ..< 1140000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1130000,
|
||||||
|
hash: "000000000009bcbe15ce9e005c9ebda0a1c5213b9573ad29c3a86a1a9f3f6586",
|
||||||
|
time: 1612007546,
|
||||||
|
tree: "01cdb094138ff68752216908f08ac0978b612b5b928b1613ec79275071f1c968710013011f9339db47ecf1f7510683dc263074e79825ffb487fccdf81a9f4c748024024600012695a02e2d0d49c3cff6192b46d4c4cacbb86bbd4cd88b6bf65564070bea0f20000195556413de9fadd73e9d5ef1cfb905a021dfea4ffa2f1cb6204438c60d665b5b01c1125574436b79f9fc6364ec470f453570fe7ad0e313878b809a525224166d580199820bae76e624f5c06b7f744e6a6ed57dc03314e91aefd883648c7fe0ff1370014576446ae9961962903fbcd41c9d7ff2d8c41b77244ff39e2f1233286f95301001df16b424017aef9e9138169b7e183c2613ca6ebf9680fd27c9c280c194d0772f000001fd3610fa060d8eca861a55d6bf0042b7e11d67bdac285b4677c995f2b466276101e5f0a7191091bc4ea3b06cc6cef4644b426122d74b91cbece497f7bdaa19526401226d7b2448f34416550c5aa0730c58f1eb72ee60cb9e9d61bd66c81d31b5ef51000000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1140000 ..< 1150000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1140000,
|
||||||
|
hash: "00000000006d9c69d8c4d7818dd2b9b106078317c6e881eab86ba41e4a546337",
|
||||||
|
time: 1612761940,
|
||||||
|
tree: "012afd078f200a60fe586c8ebb81208bc6b656f2c24935ed9ae483606368c6101c001301e0a84c415504116132c953c1885150a6335bc3293aa17c89626e02406f944f39000000017c0a218b969475ad665bfdea14177bd73b8510d451bd1f533f29d5f86f92a14201faee45bdbbec94f64fd8b641b3e2c1c473880b14a86134d766b9ffae127f0506014815011726d11513734103e47971902e4e8c1245ab2b96107184f2978a13cb2501eecd48ee70785ed9d31c4edb6da31287fe1b42082466c787262133017fe3ab210183352b54c9e84bed4c1fb4c31dc1bf690e88aec9f477f6e00d51a4bc918cba32018b702b3a1bb47c1455d5ca00cdb6d2eb72256f421937dee7d5453e7108c8df3a00017c41a5948f315986b60909e07a15c2639fb1b13a968aaf322d654aa1e823f60b00000116316e325ad5299b583121e42838f9cb432a88a7042cfeca8d36f8f5e86e234f0000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1150000 ..< 1155000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1150000,
|
||||||
|
hash: "00000000012e01251034b1cf6ced448544f350f023280e3118cb23863affbb58",
|
||||||
|
time: 1613515993,
|
||||||
|
tree: "01a4948b191c1169242c0dfd9c287ce1ad06a681615ec99620fa5936bb05119d3000130001e9eb3a657f63031a386c64296e66b98374a0d74280132543535eb82180a5706801e0807fba775afd5acc8714c1c33ac709faee472841c3874ad477e57a01a01a4c0000000001dd716f606210678f0ce78fa535ba46a5cd1d0f22f7b237491e0136e71e51916400012278350ab0e251df819aa820ab100a1264bf5aa73c94bf5968730fa61668996001430989441afaafa2f64683ff0424b12b5051763ff094a88a4cc96cd00f09b8650113625bb6dc4092d25f906a05fd3e2f1a7c5df03381d0e0760aebc2ad0ecf0f0b01582a57901af4736388425e1bd26fff5b23fe6c74d10b1fd7145c46e57eeed609000116316e325ad5299b583121e42838f9cb432a88a7042cfeca8d36f8f5e86e234f0000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1153000 ..< 1160000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1153000,
|
||||||
|
hash: "0000000001d06618d059c2c1d9a0dde0369cac8af75c9520409715f2a766b259",
|
||||||
|
time: 1613742458,
|
||||||
|
tree: "017aa8d47888728be9104e9dee586acf733b86fb244c4d9abd4b23d3b8f15b5d0b0111cf472e9ddd29f30ad95cf4f0fb7e587cc589735cfc9ec5a36a11e7d3394c711301fb9760d76283fc1af4195cf7d08a1f661cd20ca5201585451e877af846aeb6010000000001dc7dabd7bcce76a04412dbc9ef145d3d10eda33b5f644738c51286e84112c00b014d1745efddec53a2c5f23adc231decbec7a03c72ab4fed682d0affaf29584403018f8c345bf75a7efb9521dfc3cd6192b05b01702fc9a88f9be949a92d9f429f6a017b5ccbfa88f3523ed78b79f0cd86b883a096fb9b829c2a13000c8dee9ac9c72c01deeb9380b9491c7e7d59075ad35b8c8b748ba7d0337a273c3ce2a4e4179c9a2000000001bf57fd5f3e010a317aae249ee1c4583acc2688c9c22f84710f0173cab1f151560116316e325ad5299b583121e42838f9cb432a88a7042cfeca8d36f8f5e86e234f0000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1160000 ..< 1170000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1153000,
|
||||||
|
hash: "0000000001a7bb6c535053418e8e9e1620c3e5611eebcb15218a0584754e8980",
|
||||||
|
time: 1614269669,
|
||||||
|
tree: "01ab89bc17a2fae59a5170033dea2302d8825a71a0e3fdb1a01d50c44fae59cf2a00130113607db0515d576fdaa165b61e9bbebf997bbf039ceb75aa04ccb3dffe492e5f000129140c523912d51834243412016078da091020f5c02bd498cba160342d20b92101f842c5a07a703b080c4d73cfa95460265b10bbb6c7dd5ba4cc50c7e24c4f380e0000000171df72fb201bb6c7f4fb3c9e06ac94ce0eb0f8c0259719d071587c3e5a74e00b00017010f179ca3f1dbb0865b00a418114dbdd67e031e430ee1bbea1b30081f14236016068bc4c06705014dae9c2a5f86f6734b08e39fb4ebd21366531dd93c0d0561d013ecba16781a5b5f4837c648de2a32f96c3d635a3b9e3630dc1bd1b1f4276be170001bf57fd5f3e010a317aae249ee1c4583acc2688c9c22f84710f0173cab1f151560116316e325ad5299b583121e42838f9cb432a88a7042cfeca8d36f8f5e86e234f0000000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1170000 ..< 1180000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1170000,
|
||||||
|
hash: "0000000001225d341f424c445c71b13872ff89300210594f3d9d405ead56f539",
|
||||||
|
time: 1615024297,
|
||||||
|
tree: "019968e9b4725455dea88d986b33458d199353a26f1349abbe7f39c3d72f82365701abcab1e8db711ee75949326fa6a0ad302776ff40036cfb4c1c770ea430a1af51130001352edbeb2884d8ed1f39c18125493783d76f495a88fdb32c7e5d7e61de1cfd7001b6966af9deaf4512b7922f65ad099fd11f1c3d34d80c93bf4e6d9aec18686d5201727534576ffd6b0cd7146d0e3516b3c9836e9ba5965e35b35033a3add146254901851e9189feb9e5f62c2df5049c930d0438083c86958cd179543156ada7da910f01392e342052ef08587ebf642bda8e3948b437b915a5d1856d59ced86d9e640a5e01199e767f23a7d41044303fe914e98c9b059b9ce0b85b37b7fa26e43d4fb5b72d000000000000000001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1180000 ..< 1190000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1180000,
|
||||||
|
hash: "0000000000521c0d55ce1765092caff595acb5d546147b192fa9272051f55f42",
|
||||||
|
time: 1615778593,
|
||||||
|
tree: "0102a70ba9e31d6c24be0fc283577072d815d418da5e1b14cc81923f7bed308460016d9d5c674c15bdaec54c70d528e94be910994213683e3aac2fc94092fd8b4a5b1301dce7f293aee6c2769fe616dd47d46e79b51568c8bc08c67198b20d28eaf12c6f000001ff83e392690a332103433465b2034df2ab6cf35c164149a3951bf0d2bcf2a96601d019ed97502d718643c32851eb1acf6307861a3fe0ce3174697b0c2df4568568011d8eb058dd0a73a4314e04f12a6de50dd18879ee891db5a20c890e1c707f6f01000001cda4d5ff76022119fed8ffb94b8d3a26a0db37a1a886a0f31a57d1c0ce03f106014fb59c2d5dd4cc176d226c57b48d4dfc4d200088d5b69cce675f84e885ee5c1b017d5b561bf80be788ebf12e901e4c544cad95e24d0b21e6145e1718ec9dbfe91101678fbb171e5715c63bfc888d345e755c69c6dbfc2818f05b6e6ca32211ffd44400000001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1190000 ..< 1200000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1190000,
|
||||||
|
hash: "00000000019caeb64ab8caa12e1dcdd9a8f391b063ec252887c91526b7ac5e0c",
|
||||||
|
time: 1616531745,
|
||||||
|
tree: "017ae2fbedf5cad68ee80df0ae9caef9e0168914780bfd14eae016e2fb89068071001301c78a8f9bfddd9a1f0076048c48d1d58298ac6f4368472a39b0b240d540117c4301b58c9284084704437af784307ab0a334dc9c7aef588bf7d26491274d79c4471301b0af0fff110293b555f17d5ced0a598693ff4cde3e680d988c6ccf498846753e01bb9d0f21f621448c03ee49de4ef3bf0faa4844544f9668197ef5921164d2401601a15d695922c5441e80aa770861f91a97dd460561515d32c9d06bd3c6f98ce26f000000014a772e6ce520bcedf07793ded6148fd3415ecbdd89c3efe183b6048f1fb4791c0001e281c5ec71bc1a301ad0d285f6f1aa2552907645b02f9d43160f5354c2be7c63012b4d8d83df48c8b5c35752268eb71a428aa05103809a887fb36519dedbc8de27017b610946256293c523b36cf95ec60f2c346d866d98d1276bbaba22e46815516d000001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1200000 ..< 1206000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1200000,
|
||||||
|
hash: "0000000000347d5011108fdcf667c93e622e8635c94e586556898e41db18d192",
|
||||||
|
time: 1617285467,
|
||||||
|
tree: "01dcc15a1314130c3ae61401ea76c0c1b32b0c44d8486fb6cb8764af9f6dc03d540132d6897fe6cbc340c786a129e69aaac499ba9ae33cebc0ae6163d02dd15db4061300000000011b153a8182d97d204f5ddf0cdbe66543d67ef3b25dac5602987d4dcb57f35c260001a3d62e7611681256eb34d5945fbbc085ccf1d04d6a507295c3c9724f6e899069017fd5efaf2ba1e3c53b0039674b6667e401c83834d53b0970c7ff3a6dad684a540001c77d47e4819c69c3a473b8e4c660bc73c2a4fc0a067e5ad21c6fba9aa031c96e00013729a1708bbe29fcd683e3e3337e8b8ded4fa6abb24cb7bef506168be7fe8a5b0001df26abb60966dedb257d90ef08aa7232474229e08e62ba390336a07c4775a7260001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1206000 ..< 1217000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1206000,
|
||||||
|
hash: "000000000078454a0d74d2df9ae2ca53ee37bfa21ba5d761a96dc426eb3603b8",
|
||||||
|
time: 1617738149,
|
||||||
|
tree: "01f423310ab6f632a457f8b91f6c16ba6a0c2b49297f54462e5588d1eb6aaaa0200147dbb8e70cbf50002af16e9e75ebd32c1e5f3f66b43e88001965be754ea82a3e13000001cb1695d6e381645c49c9706709438c8a40cb667b7eabbce3669f293d2738e24d00012a8f5a54b81bb34bbf0a8e8bbff5217f17a423bd379ab08a08506744a6c0272700019827b9160f8772351b07ea603a48a6085ebc61692243ae9dc6b5118c1b5be347000000014226899cc196086727c3a53560a6273406f499e19d1b57cfd6018be889630e0d000180541ee92782f67894645a8a976ccd0934e37c13fbbc7cbb501b7ba78d1a902301df26abb60966dedb257d90ef08aa7232474229e08e62ba390336a07c4775a7260001089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1217000 ..< 1220000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1217000,
|
||||||
|
hash: "000000000101d56be0c460d0e3cd780bf4eeeee79f98b2650ed61f2461ed0e61",
|
||||||
|
time: 1618567777,
|
||||||
|
tree: "0196abe4a8e73e641c8bde7f7d4c7455fc530758e5754b513ca76bc959757d773c0013010c2a76ab6a36beee5f415d06f0c4081b2569b8268123f00ac6a6cf95818dcf11000001f913b2dfda97da60e92d1cc81d0533f87794aa1dfd50bd668ffac7cfc1c1e2090001dd5879eeb7e652f8edf6458079cf06a4189700cb2dd6faaea03179a1d24d59050116769e0bf56d11a3fab9b728e76d131b177add630475992c0272ac1f6d14815e00019e4967e62633bd0d8084f78aa945c1a50bd571c71d06098f352a9d329c4d86110001a1e452b5cdaf030e7b4a75b30cbf4a920aa502d03c4b25af22c3ba815870a14700000001ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1220000 ..< 1230000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1220000,
|
||||||
|
hash: "0000000000751d7ffb3aac6f6a66ed01aa4e991a96162c1749dc556e50fe6df0",
|
||||||
|
time: 1618794113,
|
||||||
|
tree: "01c3bbf34ce189a5285144c79cc37c4e76385b803947819ea8bc43b1e8eb2c020801861a52e2fb19b150b0b7c7d7f879bd1ac4fa3a11ac9763db4f837f4db048896413013ddab8738a0cc8e00e96c7487d21a9771a7986b7e1e5d5fb0348d46caa18360c01d6b0010e9664a01a47a8acc9bf073255f6fb62f617cb491b249671da85001862000000012fe6dc35a5d51af73b73854855f9861775296a9c56d6aa9455be2762a101d7390168ee29d7b083e5af0d1895b2832a4fc63a9c7b6cea37b75d17d28e6f5842ee0c0159781dcd759c87f8bc8622bc19f9a8732c06b52897bfb6e0ddcbadb111d6a95601036e008ad224efaa9833fa9e790192dad7aab0ba71bf872430f48ba6aa0d1d1b00000169bce4bc91631cf6158d978b5ce6ad03f3e4cc3317c28964b575ca736f8b4d68000001ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1230000 ..< 1240000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1230000,
|
||||||
|
hash: "0000000001bcfbeb53fd5e9647168265bc5fc8e8622049b9cdd07098f0f51601",
|
||||||
|
time: 1619548843,
|
||||||
|
tree: "0164566f774ea1f6d7cf21a9fbf9cb3f2e7d1e400097417822a7c233422619c3710013000001bad8de55d9adf4d4ff08f4ad172a5ee80aa0049974c5227d2b07474078f73c2a01e8d5303b72f034efacb9b9aa0697aa5568bf6116f2fdc1e528c03b76ce569c340000000000015334d52667d65b8ff3dcfb3d6ed72c46ad19ea9112813aaf344a3e614eb9012600016cad8c39b711691f2bda74017894c657555a8bf7ef913931ac4f7ba0b48a30120121c25bceccda091622bfac1b7973ffaa638abe1f334b3b56f48dc93dc549c9070001ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1240000 ..< 1250000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1240000,
|
||||||
|
hash: "0000000002473bf56688195f05b6f5acea0f99506fca40ae72f2ab8c1fd7390d",
|
||||||
|
time: 1620303759,
|
||||||
|
tree: "017b7c743693588568510844e4bc181d12ab6433dced0542d149cbec2b96ba526500130001cb8eccc27eb266385f9e4b880ff337b2ebdf10238dac74414fde8937dfa2264b0001bb0cb6201a0d003f1e4df17cfd4815c382ced6bf038468873495ff5c9c25412501ba626167f23eb767c229a0498b37e8322326779a3a6454ebcefd639056b3e64400013ff350f9e880271ea2c713c509491605ea24589c369262c18c417fdf1027305e0000000001849b1538147707b1c880e7eee02f29ada52e8a5a6c3a9027087493f41bd8304a00018e7922ca798cd3e26d3369ca2425ec19baa7d79407a979ec1090ae48fdcd094a01ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1250000 ..< 1255000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1250000,
|
||||||
|
hash: "0000000000f3d2c352c395d66866032bcb67094228dd4a27e561b1c399ea612e",
|
||||||
|
time: 1621056898,
|
||||||
|
tree: "01c9a0dd6f6dfaaafe6ae4b432c2d1c41d2a73e564c8cb6d2c5ab637c7001a2456001300000000017da32b486a8ea9f13afb93b99d2b1de69aa969e7c2fd7b9ee958bece70c08d6b000001b3a4486b176dfcedc0b3d9287c0333ff464ecbd02bac7c89bcda7932e6a0a36100010d451c18b56877b8a11cb401ab7024c82b9669ede862a53e461087f57220035001a1c5260bc4dfe010510b8135209c6f64229965f71717f1e693abdcf88a58f36700012f0bf70e372e536fc3b76ecd7e2b69eebf2fbcf71b828c64b0a8b99390fbf754018e7922ca798cd3e26d3369ca2425ec19baa7d79407a979ec1090ae48fdcd094a01ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1255000 ..< 1300000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1255000,
|
||||||
|
hash: "0000000000f34f274737e653cc31122e8ba8ca9865c09b65b3c2ecfb2e9687fd",
|
||||||
|
time: 1621434019,
|
||||||
|
tree: "016f51c78a2c55fef567e8deac7cb82b1f62f9ee6f5fdea27fc6fd9d1955e30353013f25aaa8aedcf10cd63b622d8c7dc21eb7b30504f99952bbc8efb437ffc482131301d0fa036d389289e37709f7f01d09e689cf55e989ea9d07440d593f21929f960801f69330a08f076f55f5db32aab6f2d1a2ab23e52a9a4e4fbbd21b8204ff23e64d00012f1469ddab73380dc3302f1cdbefb508141e2689a83b754fd9970037eb04fe6a00000000014ba6ac078f45c360c912ef828c138e4bd7d4150cadb2a498a32ec3fe7e22cc720001638de702094b20c64bc4b046cf7724634096aa192b155d191934120653734414013027101973e524ee59f21261bbf9fc152a61856a00f876a7c2b4dec71d50e969012f0bf70e372e536fc3b76ecd7e2b69eebf2fbcf71b828c64b0a8b99390fbf754018e7922ca798cd3e26d3369ca2425ec19baa7d79407a979ec1090ae48fdcd094a01ece344ca21dbd3b681f167163d4792165efe8239390afc13378e50d044fee65a01089a1f9d50a037cc66aba4400b1703bcbb66f5f2993fd0dd3bb726e35940916700000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1300000 ..< 1310000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1300000,
|
||||||
|
hash: "00000000027222bdbcf9c5f807f851f97312ac6e0dbbc2b93f2be21a69c59d44",
|
||||||
|
time: 1624830312,
|
||||||
|
tree: "01f5a97e2679a2bb9103caf37b825f92fcd73fff836234844dfcf1815394522b2c01526587b9b9e8aeb0eb572d81fec1f5127b8278ba0f57e451bd6b796596940a2213000131c7ff90fafff6159b8fb6544a2bcbba6c102903158fce8f9a9d3c6654abb23300013555cb7f4f79badeaca9bf2dca5a8704f0929053d50e95c03002f9a4d5286c3a01ad3557e11c1607ec888dc84f5f8899c3c79fb1f50b613946452ec7dd5e53763c0001c4583f4482b949390dba355fc8fa63019c83acd644ddd633cb50211d236f870600000001088da0d78eefd0c222507927e403b972d0890d0c31e08b02268fbe39ac4a6e170001edf82d4e2b4893ea2028ca8c5149e50a4c358b856d73f2de2b9a22034fa78f22012ffde6dccbef68b60cd7b4e7a8fe7989f5954fa4bacad01b247d16b9bfa5084000000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1310000 ..< 1320000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1310000,
|
||||||
|
hash: "00000000011ced7ee934fe237a80b74f04901db85fa82a4eec008fbb11ecf2e5",
|
||||||
|
time: 1625583320,
|
||||||
|
tree: "014be5784c617834157df657bafbc419ca3930f25deddaa9f29fc17483b235524800130001cc95eae2b1c3759963275342e56f1b71cd0bb6a4e2c0405f0108eb96f668851201f559a0e5f1b41af70fd6daccb0a48c3c178dfd8d25c09ff5152abded864a264f000000010bf2a42d0faed94259d4747ef48adaedf5772ebc93211f89be1612c1a9644603019f067dfc649ee5291bdf3caf7a307fb939eceb716c5050b63f620f0e41e1724400000000000001b35fe4a943a47404f68db220c77b0573e13c3378a65c6f2396f93be7609d8f2a000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1320000 ..< 1330000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1320000,
|
||||||
|
hash: "00000000001dd2deed141caa32a167fc9c11dc2d95f76f7cdda9f50326411309",
|
||||||
|
time: 1626337252,
|
||||||
|
tree: "018095da27911b257bdeaa799f1c36be3767f8ef268e1f232263e88df0aa7b4f6300130001e4e456c3aa306bf54a77176e2462715076b3586fe36716bfc3ec113a239fdb3c0000014e4fa821d93b8944df3d5500fd71b3fca0f4c2a6add80137f7b3379fdc56a4260000000000011cc990619b9371b0240cf3038e8b3b0aaa6c50e78db250a77f0b4c63f49d811a019b4b90179cf9bf8c7556caacf6acb77ac97620777d2dff5be661e576cac55f22000001b35fe4a943a47404f68db220c77b0573e13c3378a65c6f2396f93be7609d8f2a000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1330000 ..< 1336316:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1330000,
|
||||||
|
hash: "0000000001126cdf85b463d086c6bf54d67094f6e17db3b08e38c2b4b16de926",
|
||||||
|
time: 1627091654,
|
||||||
|
tree: "016cc0651c73617064bf6de5962c99ec81fdce76d58ac2aab8b881e3b35991486d01593438b57eb9cfa76d5ea965b77a0304ff46163846c7c1ffb2695419a8dbfd4c1301e9766721a57a35e08763a27244291cb7db2ca67a711fd0569fd78aa675a21e1b019a9908d737043f786d7cdddbb22cb4d026c6c3221d34bd82bf4dc55acdd847640000000001de097ad39006362760b514f69a3aa88c66ada02085de26de23b522167df616320000000001a090ee174239a34a5d684425d09006d238c6075a61c5842d0fc26043f09ccd7001a2b7ee187c7b8ce18ebda8600bed7695b12f7d35ac971ed6ee67184a7ceebd490001b35fe4a943a47404f68db220c77b0573e13c3378a65c6f2396f93be7609d8f2a000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
case 1336316 ..< BlockHeight.max:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1336316,
|
||||||
|
hash: "000000000196f12f0d91c95f0acc391454bf81901e95645e5fcd1935bd59ae27",
|
||||||
|
time: 1627567384,
|
||||||
|
tree: "0178d99ba141a858548143bfc60443bc965c8abcf4c0be7eca28b7681dfbc64c400013000141a76d7e56cf73013cb8c6549f90601a3d0a0c4057ca4f2b5515986c29d8710b01c21a76fc8075ae365db50bff0a03d674ab8dddd6e167a1c61125168365b40e40013338e3fef636235ace2523ae0d458508e795d04d7c49a77fa32032f45c482714000001fadad4c3da753327273cff5f827ac6a2da9cdf9554fb8e4ae1d73b0beb2b4a5a00012510c0b1bbca57be1267cba3c8e8e28c7457a3580f32fef3ad1ab5c117263e6401ea5e9a0276d6f23b8da7c2006a85277d92badb145c62334243205676b2ec971f012965494015cdab2ce010c1ae4ea88306c286128275de391dcf57d3fa85be7e1b01a090ee174239a34a5d684425d09006d238c6075a61c5842d0fc26043f09ccd7001a2b7ee187c7b8ce18ebda8600bed7695b12f7d35ac971ed6ee67184a7ceebd490001b35fe4a943a47404f68db220c77b0573e13c3378a65c6f2396f93be7609d8f2a000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1336316,
|
||||||
|
hash: "000000000196f12f0d91c95f0acc391454bf81901e95645e5fcd1935bd59ae27",
|
||||||
|
time: 1627567384,
|
||||||
|
tree: "0178d99ba141a858548143bfc60443bc965c8abcf4c0be7eca28b7681dfbc64c400013000141a76d7e56cf73013cb8c6549f90601a3d0a0c4057ca4f2b5515986c29d8710b01c21a76fc8075ae365db50bff0a03d674ab8dddd6e167a1c61125168365b40e40013338e3fef636235ace2523ae0d458508e795d04d7c49a77fa32032f45c482714000001fadad4c3da753327273cff5f827ac6a2da9cdf9554fb8e4ae1d73b0beb2b4a5a00012510c0b1bbca57be1267cba3c8e8e28c7457a3580f32fef3ad1ab5c117263e6401ea5e9a0276d6f23b8da7c2006a85277d92badb145c62334243205676b2ec971f012965494015cdab2ce010c1ae4ea88306c286128275de391dcf57d3fa85be7e1b01a090ee174239a34a5d684425d09006d238c6075a61c5842d0fc26043f09ccd7001a2b7ee187c7b8ce18ebda8600bed7695b12f7d35ac971ed6ee67184a7ceebd490001b35fe4a943a47404f68db220c77b0573e13c3378a65c6f2396f93be7609d8f2a000125911f4524469c00ccb1ba69e64f0ee7380c8d17bbfc76ecd238421b86eb6e09000118f64df255c9c43db708255e7bf6bffd481e5c2f38fe9ed8f3d189f7f9cf2644"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
//
|
||||||
|
// WalletBirthday+testnet.swift
|
||||||
|
// ZcashLightClientKit
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/28/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension WalletBirthday {
|
||||||
|
static func testnetBirthday(with height: BlockHeight) -> WalletBirthday {
|
||||||
|
switch height {
|
||||||
|
case BlockHeight.min ..< 421720:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 280000,
|
||||||
|
hash: "000420e7fcc3a49d729479fb0b560dd7b8617b178a08e9e389620a9d1dd6361a",
|
||||||
|
time: 1535262293,
|
||||||
|
tree: "000000"
|
||||||
|
)
|
||||||
|
case 421720 ..< 425865:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 421720,
|
||||||
|
hash: "001ede53476a31a91da3313eddf4e41409fb7f4e003840700557b576024d09b4",
|
||||||
|
time: 1550762014,
|
||||||
|
tree: "015495a30aef9e18b9c774df6a9fcd583748c8bba1a6348e70f59bc9f0c2bc673b000f00000000018054b75173b577dc36f2c80dfc41f83d6716557597f74ec54436df32d4466d57000120f1825067a52ca973b07431199d5866a0d46ef231d08aa2f544665936d5b4520168d782e3d028131f59e9296c75de5a101898c5e53108e45baa223c608d6c3d3d01fb0a8d465b57c15d793c742df9470b116ddf06bd30d42123fdb7becef1fd63640001a86b141bdb55fd5f5b2e880ea4e07caf2bbf1ac7b52a9f504977913068a917270001dd960b6c11b157d1626f0768ec099af9385aea3f31c91111a8c5b899ffb99e6b0192acd61b1853311b0bf166057ca433e231c93ab5988844a09a91c113ebc58e18019fbfd76ad6d98cafa0174391546e7022afe62e870e20e16d57c4c419a5c2bb69"
|
||||||
|
)
|
||||||
|
case 425865 ..< 518000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 425865,
|
||||||
|
hash: "0011c4de26004e564347b8af218ca16cd07b08c4159b1cc9c43afa6cb8807bed",
|
||||||
|
time: 1551215770,
|
||||||
|
tree: "01881e4da7e4767ee8a144a32ab8a5719a513bb05854477773bb55e6cd7f15055201f8a99a3a5ae3528ec2fc0bda9652b6728aecb08bf364e06ac511fd6654d782720f019ef0b9bdd075c38519fa4ab8210fe7e94c609f52672796e33e3cab58b1602831000001f803bf338ff1526b2ca527288974cb9be3fe240a2eadb7507e46ba59eaddb9320129fc0148ac088a6aa509f8f64ef79fda92232020369b58a12b32c05b6f428f22015e3dd0950c442940bd015c2176f7c817f22104f54c61159727483188c539dc13000000013589be9e2d9e9e38fd78b1e8eaec5b5f5167bf7fd2b1c95c316fa366a24cac4c01a86b141bdb55fd5f5b2e880ea4e07caf2bbf1ac7b52a9f504977913068a917270001dd960b6c11b157d1626f0768ec099af9385aea3f31c91111a8c5b899ffb99e6b0192acd61b1853311b0bf166057ca433e231c93ab5988844a09a91c113ebc58e18019fbfd76ad6d98cafa0174391546e7022afe62e870e20e16d57c4c419a5c2bb69"
|
||||||
|
)
|
||||||
|
case 518000 ..< 523240:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 518000,
|
||||||
|
hash: "000ba586d734c295f0bc034be229b1c96cb040f9d4929efdb5d2b187eeb238fb",
|
||||||
|
time: 1560645743,
|
||||||
|
tree: "01a4f5240a88a6eb4ffbda7961a1430506aad1a50ba011593f02c243d968feb0550010000140f91773b4ab669846e5bcb96f60e68256c49a27872a98e9d5ce50b30a0c434e0000018968663d6a7b444591de83f8a07223113f5de7e8203807adacc7677c3bcd4f420194c7ecac0ef6d702d475680ec32051fdf6368af0c459ab450009c001bcbf7a5300000001f0eead5192c3b3ab7208429877570676647e448210332c6da7e18660b142b80e01b98b14cab05247195b3b3be3dd8639bae99a0dd10bed1282ac25b62a134afd7200000000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 523240 ..< 620000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 523240,
|
||||||
|
hash: "00000c33da2196f0ed1bda71043f671fc69a0212e01f892653e212ab358f6b79",
|
||||||
|
time: 1561002603,
|
||||||
|
tree: "01d3e02bc1c2d66762f370b329a3063067701ad66c44b40285686bc8ff25f5616f00100154bff87bd0bda3b70a6d7754eca261de15fee3cd9bc53073a232e07fc3261e27000001a54dcaccb4c5e578aef89f2a3b4e3c3d8a487e6e904c5da5916118d721948d07000000000118fa9c6fef4963049dc7002a13bb0021d5e950591e48c9e5f2cbd1199429b80401f0eead5192c3b3ab7208429877570676647e448210332c6da7e18660b142b80e01b98b14cab05247195b3b3be3dd8639bae99a0dd10bed1282ac25b62a134afd7200000000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 620000 ..< 680000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 620000,
|
||||||
|
hash: "005f97953c8e1265d6b45f4435ffa32918e53e8f0025c286a4080c3eab167197",
|
||||||
|
time: 1569572035,
|
||||||
|
tree: "0170cf036ea1ea3c6e08432e18b6a372ca0b8b83671cc13ab0cf9e28c182f6c36f00100000013f3fc2c16ac4780f1c472ca65534ab08911f325a9edde5ea7f24364b47c9a95300017621b12e518cbbbdb7511ab423e0bddda412ed61ed3cff5be2140de65d6a0069010576153a5a2098812e7a028c37c3398e186f398c9b07bc199784ab97e5535c3e0000019a6ce2f0f7dbb2de493a315abf62d8ca96ccc701f116b6ddfae33870a2183d3c01c9d3564eff54ebc328eab2e4f1150c3637f4f47516f879a0cfebdf49fe7b1d5201c104705fac60a85596010e41260d07f3a64f38f37a112eaef41cd9d736edc5270145e3d4899fcd7f0f1236ae31eafb3f4b65ad6b11a17eae1729cec09bd3afa01a000000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 680000 ..< 720000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 680000,
|
||||||
|
hash: "00a4fbf54597d2f474f999576affad63f0ba2daa14c6fcd55c7eeec700107270",
|
||||||
|
time: 1573569367,
|
||||||
|
tree: "010a57f939a267f8b1e8b77288c783432e48fa95f7b22ead5e8ff46a788181453801d6457d98d3698a367aef4a2fe5675a575790d5d8081b731f979f0e64043fb7351001afaaf81d6d982b401444dbcf89e63c2583d234c1a60de17940a9b3a15f3494660001ba7acc730584a689413c44781d3b13cd497bfdca3fe27fb78cd9b50e9929906300000000000129e195df514840a20b95200b92d5b8d196b119cd6887508d8de077beffdbfe68016482af04b979e08e4e5760d55832292e55dbdd88143992f123840c8983db7b3f000001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 720000 ..< 740000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 720000,
|
||||||
|
hash: "018b71dde8c9b1ee3e79961c6e3536c79226f5d6e79bb35c9ed28dcb8cb78b48",
|
||||||
|
time: 1575943651,
|
||||||
|
tree: "012cfde48dff4f20ddc50a7aca3746f7d77920eebc8cf4ef53feac34cb8719c03a012c668d234aaa485862e1d06e46d6d7093c2581e2b9cda90aafd691d6e325410610014f3a875476cb8159d46fec1aba18c201c268cd61b01811b7e5bf83998fb8222500011f19160cc75325c090f3eb3fa0cff2d94e43e2713c89e7b02a34f6ed08fbcd26000001edc05305223f7f2839abc1dc7d900468349577d6d6f5c182ef3a81a848753b5b0000000129cbee0c11a827718f126d9e037155a9e173ee2d2ecf57dc68f7b66437d44f7301a113bcf163405e4286bc080ac55aa68555d2c9e63334e7b9a5eb756872f14c470001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
|
||||||
|
case 740000 ..< 760000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 740000,
|
||||||
|
hash: "00163c394a1e545b4c777fc91474d92becdd0fe9300d38fb3563997d026a54ea",
|
||||||
|
time: 1577389695,
|
||||||
|
tree: "0135ee37f83d0b924eed58bcceb249a4977dcb21495561b97bc747a272ebe5d6580010000001fe65cfbb8a76e0d29ac94e5ada80c80b607d1addfc287754f37ddef531eb122500013a1d604d978f716fcb2887cdaa3c582a608b795ed1b3c57998cbede2be479931000108ffb0fbc6b653305b37cd5568b85112b996cd514fe97ec73f7169dae0cef05101baf5541e853483315273c25c1956d233513c3dabd8741972136b2f8f8cd89035000129cbee0c11a827718f126d9e037155a9e173ee2d2ecf57dc68f7b66437d44f7301a113bcf163405e4286bc080ac55aa68555d2c9e63334e7b9a5eb756872f14c470001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
|
||||||
|
case 760000 ..< 780000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 760000,
|
||||||
|
hash: "005ee769f3adbd0b24a63e8e4047200e038c38df277544d40c23ac1a88c1f37b",
|
||||||
|
time: 1578766903,
|
||||||
|
tree: "01470a1a4d29374e074f07a646b95dd89892d9b84d235a89ecc9d5a52beadce901001001311898ce56df0ddb10dc573a54ea06d11415e72602daa80c01f888fbd4a9a734018610afa4925cdb8bd4dd75a53ab69a74080322cae53c630ac02ce00b09d3171601bdfbbde5011bd6c0620ed2db3e01d5daa2ff8bb5f3b58687d265dd33a5681d530197e268c82e56dfc62aeb54586a2000766da8078f09a2d15fb558ad05664b4c5301aa204407034ba59fce0eee6518688585e96b0f10befd595b8e68a8ae15328a51017389398c5634242b03ef811f6abf224df9e6fc6d4393139e526dca4cf44dcc2c0000017de4c2c210c617dc61a43e124cab93e4f6143e1e9e46c2e55a541a9781cde43c0129cbee0c11a827718f126d9e037155a9e173ee2d2ecf57dc68f7b66437d44f7301a113bcf163405e4286bc080ac55aa68555d2c9e63334e7b9a5eb756872f14c470001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
|
||||||
|
case 780000 ..< 798181:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 780000,
|
||||||
|
hash: "0104238cc440b6bf05b86a1b00d794c6d88fc61b8c416124a971fb5ce94b91e6",
|
||||||
|
time: 1580205978,
|
||||||
|
tree: "011ed883b7eddb4783eee5b73ceee4c78413e1f6f9db3d88d1007f5fa62292955c001001861feaeab59bc31cd97ffc89467877abf8b9fa157bc875907eb90d6e8c723325000000000001ccc21a1d581eb6d3f35729f202f0014a59b4f9d41d92d44316b381f57dc8356b01ec0f418f21af87c0e0846b318be838bd181f25b708ee2b2fa030468399fb7932017de4c2c210c617dc61a43e124cab93e4f6143e1e9e46c2e55a541a9781cde43c0129cbee0c11a827718f126d9e037155a9e173ee2d2ecf57dc68f7b66437d44f7301a113bcf163405e4286bc080ac55aa68555d2c9e63334e7b9a5eb756872f14c470001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
|
||||||
|
case 798181 ..< 800000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 798181,
|
||||||
|
hash: "02936aa4f8b6b2caad7cca19a866158656e37edfb0f32e2a473dc278fa634b71",
|
||||||
|
time: 1581521064,
|
||||||
|
tree: "01901ef0f4221f8a02d5896fda6f78cb5578fb8e9a5361d5689bfb3b6ab92072320010000101c5d791d8748f0ab0ecdb48764de29c470cc74f5d95b5a1f8cf0830bb059b66015af654e998c75460e9c1f5ba185589c53c383167e66951cfe7684321b7a77e5c013faf6b3f21f03982ada477bfddc95b18e63683c497b2f4630ab453623c28974c01aff3253410a6601ab4b5b3626f2121cb77399c634b1774a4c63f415598d16b0c01a6158d0a1a1bec9dadc601b140a9fdfc7bdab7e232739a3cc0e0e46bbe3ef44301ccc21a1d581eb6d3f35729f202f0014a59b4f9d41d92d44316b381f57dc8356b01ec0f418f21af87c0e0846b318be838bd181f25b708ee2b2fa030468399fb7932017de4c2c210c617dc61a43e124cab93e4f6143e1e9e46c2e55a541a9781cde43c0129cbee0c11a827718f126d9e037155a9e173ee2d2ecf57dc68f7b66437d44f7301a113bcf163405e4286bc080ac55aa68555d2c9e63334e7b9a5eb756872f14c470001e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 800000 ..< 850000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 800000,
|
||||||
|
hash: "00599614a7795bbef99a598cfee887782900fa5cd95cd59900b8d6582bdc17a5",
|
||||||
|
time: 1581643886,
|
||||||
|
tree: "011ba0f16f59489a9bf9cc46c3ed1108c1dc0ff6e40f3a38def472c3229a96925e01b0eb758757bde323a6417d98365ce8f6299b0fa3de615d6cda68689e6a81573d1001438b40ff7357432d987d6ef4826fba35d38b2db531ea842ccedd4916a6aff9580000017cd705c293895c8b4613a3de3ad3b8d43ae05fff808882db4c5e19917e2f346d00000000000000016f6df9b95ef63866bdf0e8b4b97701cd09232ec3e4e240808c0546d01bc7bb0501e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 850000 ..< 900000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 850000,
|
||||||
|
hash: "003b66bc3528dc295193108caab868e0f3b93d13db2ddcad5486225fb2b83d83",
|
||||||
|
time: 1585012771,
|
||||||
|
tree: "01e3bd906376b563d184bfbf6616e220f895001b7ef9d26bf38c6cb5c71e57a42b001001d848adf8c38d113140bb30d306b0761da6987e25ffc0d82faa63c2764aab120301de3e6a35d09192cde3430860c70a534d7b63e95a726fab052de2a9befa3cc3320189b958fa030131bb83385a3e3a8b187a166dc1b3a02050f2d2fc20788536c30e0001cb8770ef198e7de60093a339afbc561c16c16749f9f96751c2fc58a22d0ff36f01f86ff70dd512f7075d02c5ee6e28a8824832d08025a4cfaf4c1854f1fba5da10019bcac1b44a27de2c4528fa6f4b3432913511b219cb3b29d137cac0236a3d244800000000016f6df9b95ef63866bdf0e8b4b97701cd09232ec3e4e240808c0546d01bc7bb0501e3ec5d790cc9acc2586fc6e9ce5aae5f5aba32d33e386165c248c4a03ec8ed670000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 950000 ..< 1013250:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 950000,
|
||||||
|
hash: "0005050d2ce31b9b925c7ef4ab3d3166d5833bdcfee251294f29072a2bc0f75d",
|
||||||
|
time: 1591609525,
|
||||||
|
tree: "01f0637235c4a699d49ba996457a6c4eb7c67edd8270948065683deb19ef218363019f65a9692cefc7b90b42c1538ac1f38f7a7598549089c4561315b482f378523010000000000000018d30d0039277b05ab9e0c3990d53037c45892bf17af2d04fef40ed48c164ad2201ff5d86bbbe360e31378e783b740f8b05db2cf4246b95aa3851d22ed45554750300010cefb25743d5dd6062ef3afba438731cd5b35befc1038ecca3076fd205829e550001c19052386d8bbe3c07a1faf302281d67946cc9547e7e1890ff56b3a3ec69c0310001be53a6cd33da0442c7c6362c0172241f42e13c6dc893436a661a1cbf49775c1f00011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1013250 ..< 1028400:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1013250,
|
||||||
|
hash: "0017b3c49eea14e93f69adbc7a8f24eef3e9645f92e3b8d5e4091e1d5a4824b7",
|
||||||
|
time: 1595516064,
|
||||||
|
tree: "01d45e95007f8f97fe3c6a297a9d4bca917772e545fbcbb61b4f42d8a743eae31b0010013d7b7da2e6792dbfc6360f0c13a1ba879aa51a498c6dbab87aa57cef558cc35a00000001f945c15602617327026e3e0f231daf91570b32f7bb766f65e7e82131a911cc3c0000013173e9983fbd7a396e192e520d163be06cdd28abcfeba46c59dc62a400f589080001e7d5b00f0758cd3b7407c6d13e23d1a59e3f510c3dd3a4a8fc367a5305673b3f000001c787f900940720a3692e5694b085d5409dfa966017a6a48441c7e4b423b3144701be53a6cd33da0442c7c6362c0172241f42e13c6dc893436a661a1cbf49775c1f00011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1028400 ..< 1130000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1028400,
|
||||||
|
hash: "0006b94b304009f8a6287aa48021aed26582ce74d387c2c452aede86566179a6",
|
||||||
|
time: 1596480151,
|
||||||
|
tree: "01ac95378779cf56f0726655d248f95d63e07316ab67651ce357b346f9a7adba300107d7544edbe7d0522fe523df2ff804fc9f33f4844dd29e86a23fc7aa1818e237100001f8779a159482fd3a28c640e6d48ddfb37a44a26a102aae3822f32d2de22a1c70011f97534315f1800961bc78fcd1495e3b8047bb227e2776080fb31be6cae14e73000000000001fe15295e017fc2b8ba4ea1b7e53dd15f19860d10e7952905b7598373e143413e00019289038516ce3d6038cebe852ab5e32f7a1966fc79a1e41c7cb6e67e5a71c33d0001c787f900940720a3692e5694b085d5409dfa966017a6a48441c7e4b423b3144701be53a6cd33da0442c7c6362c0172241f42e13c6dc893436a661a1cbf49775c1f00011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1130000 ..< 1370446:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1130000,
|
||||||
|
hash: "001f6563cf2863d36501dee00e41795f2fdb482970ea5f648791bbf7da4e6860",
|
||||||
|
time: 1603070117,
|
||||||
|
tree: "01b00c3e6d98e706fdb2d40f082096505aaa70fb87c067baf1a8a6d25cccff7258015a5334276509c93b855db0c2a1252e2ca725821c9274add1c2e92631bbbfa12b100151ba8342564941385670cd7346dc753bb5cc61164f000f65044cc09baa175917019ed834b8b9c8ca58969b3f239d74c2dd4a7d0a462afb1e856cf76209b866eb660135de9af32480f38eeca478a33a95f495abe7470e93d5aa4813fab7ea4fd12c4c0000017ce3fc7ebc2f8cfc2e1ee9f8e92b6e45065679ee3b48b5b2f0ce053305f5a95c011f1e8fe8f4a1cb5a700614218b8bebf2113c8a660abd255f67448b684b82d76e00000000016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1370446 ..< 1414969:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1370446,
|
||||||
|
hash: "00357a40a8d0473663f5ac32ecd4365bea097e47070b38803cbfae2b7a402233",
|
||||||
|
time: 1618587354,
|
||||||
|
tree: "01d0d36f8845f9ffad4f0a8812fbc5c4c69b45733199d7183307cb1a7d00353c0900100000017a8a6f641c487a313bb949623cca3b22b925adfef8216866aa090546bcf520000001bf48febcd2a10e51d420782990e17b746d5ce0f3292007e60a2eeb830bc46d0201ab6e0123bf72f70255ec4cacd33935b19ff834d481d67e06801073d0b8f0ea2a0121f42f607885a0158022413591af8eca7eae38b10c46e3ac81a9bfe70046e51d018229160dbe1f1d9e02d738e9d5060497e786e7434c80c32db7b8c96878e9904601034e6b1c73f09aa81f16a13cdb2188a53d8761483470f0bea01bfb84eb2cea1100018469338dcbdf2f7e54bca5bc3e1c5fad4a656f206040436d3d0433a901218b5e016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1414969 ..< 1420000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1414969,
|
||||||
|
hash: "00212ba35169b77dba4eb4f5ce8c10da31a9df6dd61bb434f2f9e159d78913bd",
|
||||||
|
time: 1621459669,
|
||||||
|
tree: "01a9497fdb3add3bc2d0676f3163d94cda7c8cf8112d9dd8d2e7611b187c600a410010000143905c99f7bb45b164c636bb2443d9621db8147dba6a84a279fa8ed8f012083d00016847084e044e84059ea4b88b8af2de3f65c72adcee21522d5ee9d370d70f525b0000014d03c61befc68d02710784399567067db98f24eda340a1fd4a3ecc549d0fd0660001b4c1c846cae1423eaf52f1a8b1bfdde9ed9d43ced4d80dba9e72d862a0e03e4001ba0d7aa9e68417291c63b835fa64114f5899208238de59ee360f594c8b6c1b72018469338dcbdf2f7e54bca5bc3e1c5fad4a656f206040436d3d0433a901218b5e016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1420000 ..< 1430000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1420000,
|
||||||
|
hash: "0089952e8ca00ee452412c3eef20403f9bc84751fc6ceb630c8a2eb149f051ca",
|
||||||
|
time: 1621783347,
|
||||||
|
tree: "0107478e9125e3050506cbeea850266d94108997ec3ef101d9693d136611b4076c00100001dfcde451d111cd50bac54c4ed4e238ca3dd8dcfcb8b50eabccb11a12dbcad71b0001cffd776a8fd6e5df911d000876525aa1d792a4f764e252dac9af69dd8ef3046d0106d4ec443aa1194ea579a1aa179bd5a29eeb4a5a01ccbfcf7af9cadc58225a6900014d03c61befc68d02710784399567067db98f24eda340a1fd4a3ecc549d0fd0660001b4c1c846cae1423eaf52f1a8b1bfdde9ed9d43ced4d80dba9e72d862a0e03e4001ba0d7aa9e68417291c63b835fa64114f5899208238de59ee360f594c8b6c1b72018469338dcbdf2f7e54bca5bc3e1c5fad4a656f206040436d3d0433a901218b5e016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1430000 ..< 1440000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1430000,
|
||||||
|
hash: "01d9b2d83a7ec4ecede08df009e389b70535a5d41a1c6d1ce0906381d06006e0",
|
||||||
|
time: 1622484411,
|
||||||
|
tree: "010ea3d173a66acda751cb72a86bcc1eed2708b997ca8c7292febbd4c19b41665e001001f908af1ee7296100c06672f69834e5be2dc8b5325945270d562669bba91b825d01c4b42187eb99ab242226f6f2a48a00d4e5b3b4201c931afe9bccc86f3fbdd46501f39c0c0c1f725fa6b3ab8b58e60b280207a41199e2e218405f31ae18f0759f16000154daf736c7f68b0f22072be3e6b59434618b514c0c32d044c187048e2600c60b01f98b75b62bf721db663a442cbfa411242ec07ccb70aee42ea3618ca7b157270a014d03c61befc68d02710784399567067db98f24eda340a1fd4a3ecc549d0fd0660001b4c1c846cae1423eaf52f1a8b1bfdde9ed9d43ced4d80dba9e72d862a0e03e4001ba0d7aa9e68417291c63b835fa64114f5899208238de59ee360f594c8b6c1b72018469338dcbdf2f7e54bca5bc3e1c5fad4a656f206040436d3d0433a901218b5e016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1440000 ..< 1450000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1440000,
|
||||||
|
hash: "0026a36cf31a5442caa1ac6d7be2773e1e58a3ccb6ae1116e84e6c90ddc95ec9",
|
||||||
|
time: 1623136353,
|
||||||
|
tree: "018d8cc853fd33af2a13ea00f379fe882fc56ecea3e0b1ecb75ac3b9783b443d3b01922d8ec71070cbe88eef0576738169965839e841d2fbc09c85f1d64f3528d4341001ee3dbc8987d7be81ccd8a5b502e9385c447f3f8c9c34085a1d11f7b41ceb625b010c1d1b1687fd081e55598e9bdcc5c565781ec867a12dd056384890f36fef434c00011674571f7aca05cc96139d2e59b08fe7a5b7b779da40a9903755b61e73421e64000001ccb87d20316142450d34c59bc515935f9adfd053a178ae8d799ea1f9bf02664901cc23dbfe7d27d7ad768868d7a96b6b31260ca34e4fbf164f652eb8e651f2fd3801b4c1c846cae1423eaf52f1a8b1bfdde9ed9d43ced4d80dba9e72d862a0e03e4001ba0d7aa9e68417291c63b835fa64114f5899208238de59ee360f594c8b6c1b72018469338dcbdf2f7e54bca5bc3e1c5fad4a656f206040436d3d0433a901218b5e016d559de7a1a382349cf97fe01a2fba41a49bb5e3b306d9ff8c2bcc301c731c00000001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1450000 ..< 1460000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1450000,
|
||||||
|
hash: "000008a97bc133de13ca304e0c6a2a1b3f2facdceac2cde5b4141179f2a743cc",
|
||||||
|
time: 1623815069,
|
||||||
|
tree: "0175626cf9d8448de98f68fcc585dd7a276c946c11bbc3b192ee08db99c542b86b01acf5a110dc7ab911b534984c46bf56592f0c4cc8cf70dbd6a9cc4a5b47d2c81c1001c91f518ccb74093a217a640c537b69b095de058e0430046c8783f231caa1fa4201f7c982ce76b2c9343fb771e077357322f9a7dabfd7ab93b7adee32806c930d6600000170910ab6355ec614412fae56dad5fdc1747ce1b306a4b8ae03b77513b612b00800000000000000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1460000 ..< 1470000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1460000,
|
||||||
|
hash: "00987b79a3c78d33dcb4d65e81a48b62a40c15d379a3983c4dffdd99a0c21d35",
|
||||||
|
time: 1624454126,
|
||||||
|
tree: "01f971b9781e857ab4acd5506174daf7ced473ad5a4a98134816d0c48de197d4400010000001ce49c67660eff9e404a3e4569ffa3ba98cc4514c05fa408beecd5c63420ef30e0192152273e4cbeafd426fa7df421310d2ccefad5e78f8d3e26dc283064b4d0d480188b70932b9ad821d4c9ecd57ed729a724723d22bdee4e5d4f08c9a924e68cf1501b2533ff180b8fb171fc0450fb7d1f91b7528bc19d88fdb2385c207b149d55e53017b499fdb9fe0db4bc418689d8f45f38b127b67d0445c421bfa6892c870610e260000000000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1470000 ..< 1480000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1470000,
|
||||||
|
hash: "0027c8d818126cc8ab96efdcf877c1fb54fb373f41ca8f06e68b0b7b0e304ac7",
|
||||||
|
time: 1625121412,
|
||||||
|
tree: "012442af751714abfbb1f6b815b187eecbb60849e29dca1e3acccfbfd73f6bb8150010000109777ddd46c0a0e7eb91f31735f6078c54334f9a6d22d6421898bd44fd83ce140000013337975cc4704be21cbecce1c877936ce395128f6264fcb91ba8c028e7f25230015d7589dc1009350a87831e2fa9c4d9d3ca61754644f1a1d5d09499567fdcb11e0136e55cb009dd4f8bb8a3469b27ec325f06552a66bef2d898b6a72063107d03350001a7b951c79a184af5bda58c8be77db9b1e3813df0de344f26b27e3ad02c325b3b000000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1480000 ..< 1490000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1480000,
|
||||||
|
hash: "0019c7d1a7d9d962de329db0785f35f56c514826702714f8738d14da87f4f20d",
|
||||||
|
time: 1625795173,
|
||||||
|
tree: "01a61918852f89d4d68aa82e1d93a7ddc4285ab2cf6a2ce92e79c4b9b498662014016d8109b64819882e5d35ee6730f54dda3a4ddc8232edc22226a367542c977a23100000016891e1f6b99afb29292bd3157f89eb2b8c1f74eed9cef56f4a802939d7392a1a0001f6f393a6ab5b0bc04a6d751bdbcd64a2740ff93aef7e1527dcd5de0511c4fb3001b938c3d7a93793fa04d51cce0369e789316a72f227436e02fc0c45fdd88def3700000001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1490000 ..< 1500000:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1490000,
|
||||||
|
hash: "00263c9eab1b6b5e37143a442a8aad242fada58bb5fc8d6a5dc9f217c8c7425c",
|
||||||
|
time: 1626460494,
|
||||||
|
tree: "01448b047d9d4611f923ceb0c01a2fc743c7b4a54f7a00e92d666cbd0f39980f3100100000000001d917913fed08004cf1c74eeb918829cb80e576187e2f8e0c0e12a7e9849a9b400130282bcf71d57c40235baa4a3e045d89803c1fe069803da86ccebf25435dd270014aad72f0f5c3cd459d6d89a68657fbd299c84be0228c1a8a50d63ff2f2f74e0a000001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1500000 ..< 1507328:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1500000,
|
||||||
|
hash: "00047a34c61409682f44640af9352023ad92f69b827d0f2b288f152ebea50f46",
|
||||||
|
time: 1627076501,
|
||||||
|
tree: "01172b95f271c6af8f68388f08c8ef970db8ec8d8d61204ecb7b2bb2c38262b92d0010016284585a6c85dadfef27ff33f1403926b4bb391de92e8be797e4280cc4ca2971000001a1ff388639379c0120782b3929bd8871af797be4b651f694aa961bad65a9c12400000001d806c98bda9653d5ae22757eed750871e16e0fb657f52c3d771a4411668e84330001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1500000 ..< 1507328:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1500000,
|
||||||
|
hash: "00047a34c61409682f44640af9352023ad92f69b827d0f2b288f152ebea50f46",
|
||||||
|
time: 1627076501,
|
||||||
|
tree: "01172b95f271c6af8f68388f08c8ef970db8ec8d8d61204ecb7b2bb2c38262b92d0010016284585a6c85dadfef27ff33f1403926b4bb391de92e8be797e4280cc4ca2971000001a1ff388639379c0120782b3929bd8871af797be4b651f694aa961bad65a9c12400000001d806c98bda9653d5ae22757eed750871e16e0fb657f52c3d771a4411668e84330001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
case 1507328 ..< BlockHeight.max:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1507328,
|
||||||
|
hash: "0026c9b20540e1bde6aaa8674a4083587a6e2555bcf8bb42680a8870b8da0070",
|
||||||
|
time: 1627566512,
|
||||||
|
tree: "01beb58cd0d4ac4e0f61888c7d77c7d73d260453b526bc61a830c158319f01b22301070135db53749d6640bdfc3c3e25d71dd65dcdc2c5828fd992eaee63546194051000000105884e2f6fbe3d0754fca27e20881b74ea687d33a0ea817844330a187d20465a0192f904a39694089c3befc610fd8e1236d5e7cb3b19d2e1d5fc4019af31fbc80201870a7fec351119b307e79c83bb627b343a87668e1d68e60625212e40deb33c3d000001d806c98bda9653d5ae22757eed750871e16e0fb657f52c3d771a4411668e84330001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return WalletBirthday(
|
||||||
|
height: 1507328,
|
||||||
|
hash: "0026c9b20540e1bde6aaa8674a4083587a6e2555bcf8bb42680a8870b8da0070",
|
||||||
|
time: 1627566512,
|
||||||
|
tree: "01beb58cd0d4ac4e0f61888c7d77c7d73d260453b526bc61a830c158319f01b22301070135db53749d6640bdfc3c3e25d71dd65dcdc2c5828fd992eaee63546194051000000105884e2f6fbe3d0754fca27e20881b74ea687d33a0ea817844330a187d20465a0192f904a39694089c3befc610fd8e1236d5e7cb3b19d2e1d5fc4019af31fbc80201870a7fec351119b307e79c83bb627b343a87668e1d68e60625212e40deb33c3d000001d806c98bda9653d5ae22757eed750871e16e0fb657f52c3d771a4411668e84330001260f6e9fac0922f98d58afbcc3f391ac19d5d944081466929a33b99df19c0e6a0000013d2fd009bf8a22d68f720eac19c411c99014ed9c5f85d5942e15d1fc039e28680001f08f39275112dd8905b854170b7f247cf2df18454d4fa94e6e4f9320cca05f24011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,241 @@
|
||||||
|
//
|
||||||
|
// ZcashSDK.swift
|
||||||
|
// ZcashLightClientKit
|
||||||
|
//
|
||||||
|
// Created by Francisco Gindre on 7/22/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
public protocol ZcashNetwork {
|
||||||
|
var networkType: NetworkType { get }
|
||||||
|
var constants: NetworkConstants.Type { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum NetworkType {
|
||||||
|
case mainnet
|
||||||
|
case testnet
|
||||||
|
|
||||||
|
var networkId: UInt32 {
|
||||||
|
switch self {
|
||||||
|
case .mainnet:
|
||||||
|
return 1
|
||||||
|
case .testnet:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NetworkType {
|
||||||
|
static func forChainName(_ chainame: String) -> NetworkType? {
|
||||||
|
switch chainame {
|
||||||
|
case "test":
|
||||||
|
return .testnet
|
||||||
|
case "main":
|
||||||
|
return .mainnet
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ZcashNetworkBuilder {
|
||||||
|
public static func network(for networkType: NetworkType) -> ZcashNetwork {
|
||||||
|
switch networkType {
|
||||||
|
case .mainnet:
|
||||||
|
return ZcashMainnet()
|
||||||
|
case .testnet:
|
||||||
|
return ZcashTestnet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZcashTestnet: ZcashNetwork {
|
||||||
|
var networkType: NetworkType = .testnet
|
||||||
|
var constants: NetworkConstants.Type = ZcashSDKTestnetConstants.self
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZcashMainnet: ZcashNetwork {
|
||||||
|
var networkType: NetworkType = .mainnet
|
||||||
|
var constants: NetworkConstants.Type = ZcashSDKMainnetConstants.self
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constants of ZcashLightClientKit. this constants don't
|
||||||
|
*/
|
||||||
|
public class ZcashSDK {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The number of zatoshi that equal 1 ZEC.
|
||||||
|
*/
|
||||||
|
public static var ZATOSHI_PER_ZEC: BlockHeight = 100_000_000
|
||||||
|
|
||||||
|
/**
|
||||||
|
The theoretical maximum number of blocks in a reorg, due to other bottlenecks in the protocol design.
|
||||||
|
*/
|
||||||
|
public static var MAX_REORG_SIZE = 100
|
||||||
|
/**
|
||||||
|
The amount of blocks ahead of the current height where new transactions are set to expire. This value is controlled
|
||||||
|
by the rust backend but it is helpful to know what it is set to and should be kept in sync.
|
||||||
|
*/
|
||||||
|
public static var EXPIRY_OFFSET = 20
|
||||||
|
//
|
||||||
|
// Defaults
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
Default size of batches of blocks to request from the compact block service.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_BATCH_SIZE = 100
|
||||||
|
/**
|
||||||
|
Default amount of time, in in seconds, to poll for new blocks. Typically, this should be about half the average
|
||||||
|
block time.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_POLL_INTERVAL: TimeInterval = 20
|
||||||
|
/**
|
||||||
|
Default attempts at retrying.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_RETRIES: Int = 5
|
||||||
|
/**
|
||||||
|
The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than
|
||||||
|
this before retyring.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_MAX_BACKOFF_INTERVAL: TimeInterval = 600
|
||||||
|
/**
|
||||||
|
Default number of blocks to rewind when a chain reorg is detected. This should be large enough to recover from the
|
||||||
|
reorg but smaller than the theoretical max reorg size of 100.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_REWIND_DISTANCE: Int = 10
|
||||||
|
/**
|
||||||
|
The number of blocks to allow before considering our data to be stale. This usually helps with what to do when
|
||||||
|
returning from the background and is exposed via the Synchronizer's isStale function.
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_STALE_TOLERANCE: Int = 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default Name for LibRustZcash data.db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default Name for Compact Block caches db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||||
|
/**
|
||||||
|
Default name for pending transactions db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||||
|
|
||||||
|
/**
|
||||||
|
File name for the sapling spend params
|
||||||
|
*/
|
||||||
|
public static var SPEND_PARAM_FILE_NAME = "sapling-spend.params"
|
||||||
|
/**
|
||||||
|
File name for the sapling output params
|
||||||
|
*/
|
||||||
|
public static var OUTPUT_PARAM_FILE_NAME = "sapling-output.params"
|
||||||
|
/**
|
||||||
|
The Url that is used by default in zcashd.
|
||||||
|
We'll want to make this externally configurable, rather than baking it into the SDK but
|
||||||
|
this will do for now, since we're using a cloudfront URL that already redirects.
|
||||||
|
*/
|
||||||
|
public static var CLOUD_PARAM_DIR_URL = "https://z.cash/downloads/"
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol NetworkConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||||
|
prior to this height, at all.
|
||||||
|
*/
|
||||||
|
static var SAPLING_ACTIVATION_HEIGHT: BlockHeight { get }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default Name for LibRustZcash data.db
|
||||||
|
*/
|
||||||
|
static var DEFAULT_DATA_DB_NAME: String { get }
|
||||||
|
/**
|
||||||
|
Default Name for Compact Block caches db
|
||||||
|
*/
|
||||||
|
static var DEFAULT_CACHES_DB_NAME: String { get }
|
||||||
|
/**
|
||||||
|
Default name for pending transactions db
|
||||||
|
*/
|
||||||
|
static var DEFAULT_PENDING_DB_NAME: String { get }
|
||||||
|
static var DEFAULT_DB_NAME_PREFIX: String { get }
|
||||||
|
|
||||||
|
/**
|
||||||
|
fixed height where the SDK considers that the ZIP-321 was deployed. This is a workaround
|
||||||
|
for librustzcash not figuring out the tx fee from the tx itself.
|
||||||
|
*/
|
||||||
|
static var FEE_CHANGE_HEIGHT: BlockHeight { get }
|
||||||
|
|
||||||
|
static func defaultFee(for height: BlockHeight) -> Int64
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension NetworkConstants {
|
||||||
|
|
||||||
|
static func defaultFee(for height: BlockHeight = BlockHeight.max) -> Int64 {
|
||||||
|
guard height >= FEE_CHANGE_HEIGHT else { return 10_000 }
|
||||||
|
|
||||||
|
return 1_000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ZcashSDKMainnetConstants: NetworkConstants {
|
||||||
|
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||||
|
prior to this height, at all.
|
||||||
|
*/
|
||||||
|
public static var SAPLING_ACTIVATION_HEIGHT: BlockHeight = 419_200
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default Name for LibRustZcash data.db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||||
|
/**
|
||||||
|
Default Name for Compact Block caches db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||||
|
/**
|
||||||
|
Default name for pending transactions db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||||
|
|
||||||
|
public static var DEFAULT_DB_NAME_PREFIX = "ZcashSdk_mainnet_"
|
||||||
|
|
||||||
|
public static var FEE_CHANGE_HEIGHT: BlockHeight = 1_077_550
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ZcashSDKTestnetConstants: NetworkConstants {
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
The height of the first sapling block. When it comes to shielded transactions, we do not need to consider any blocks
|
||||||
|
prior to this height, at all.
|
||||||
|
*/
|
||||||
|
public static var SAPLING_ACTIVATION_HEIGHT: BlockHeight = 280_000
|
||||||
|
|
||||||
|
/**
|
||||||
|
Default Name for LibRustZcash data.db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_DATA_DB_NAME = "data.db"
|
||||||
|
/**
|
||||||
|
Default Name for Compact Block caches db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_CACHES_DB_NAME = "caches.db"
|
||||||
|
/**
|
||||||
|
Default name for pending transactions db
|
||||||
|
*/
|
||||||
|
public static var DEFAULT_PENDING_DB_NAME = "pending.db"
|
||||||
|
|
||||||
|
public static var DEFAULT_DB_NAME_PREFIX = "ZcashSdk_testnet_"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Estimated height where wallets are supposed to change the fee
|
||||||
|
*/
|
||||||
|
public static var FEE_CHANGE_HEIGHT: BlockHeight = 1_028_500
|
||||||
|
|
||||||
|
}
|
|
@ -57,13 +57,13 @@ public extension TransactionEntity {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var anchor: BlockHeight? {
|
func anchor(network: ZcashNetwork) -> BlockHeight? {
|
||||||
if let minedHeight = self.minedHeight, minedHeight != -1 {
|
if let minedHeight = self.minedHeight, minedHeight != -1 {
|
||||||
return max(minedHeight - ZcashSDK.DEFAULT_STALE_TOLERANCE, ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
return max(minedHeight - ZcashSDK.DEFAULT_STALE_TOLERANCE, network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let expiryHeight = self.expiryHeight, expiryHeight != -1 {
|
if let expiryHeight = self.expiryHeight, expiryHeight != -1 {
|
||||||
return max(expiryHeight - ZcashSDK.EXPIRY_OFFSET - ZcashSDK.DEFAULT_STALE_TOLERANCE, ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
return max(expiryHeight - ZcashSDK.EXPIRY_OFFSET - ZcashSDK.DEFAULT_STALE_TOLERANCE, network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,39 +7,6 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/**
|
|
||||||
Ideally this extension shouldn't exist. Fees should be calculated from inputs and outputs. "Perfect is the enemy of good"
|
|
||||||
*/
|
|
||||||
public extension ZcashSDK {
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the default fee at the time of that blockheight.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static func defaultFee(for height: BlockHeight = BlockHeight.max) -> Int64 {
|
|
||||||
guard height >= feeChangeHeight else { return 10_000 }
|
|
||||||
|
|
||||||
return 1_000
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
Estimated height where wallets are supposed to change the fee
|
|
||||||
*/
|
|
||||||
private static var feeChangeHeight: BlockHeight {
|
|
||||||
ZcashSDK.isMainnet ? 1_077_550 : 1_028_500
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
minimum balance needed to do a shielding transaction
|
|
||||||
*/
|
|
||||||
static let shieldingThreshold: Int64 = 10000
|
|
||||||
|
|
||||||
enum NetworkType {
|
|
||||||
case mainnet
|
|
||||||
case testnet
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public typealias ConsensusBranchID = Int32
|
public typealias ConsensusBranchID = Int32
|
||||||
|
|
||||||
public extension ConsensusBranchID {
|
public extension ConsensusBranchID {
|
||||||
|
@ -53,12 +20,7 @@ public extension ConsensusBranchID {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ZcashSDK {
|
extension NetworkType {
|
||||||
static var networkType: NetworkType {
|
|
||||||
self.isMainnet ? .mainnet : .testnet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extension ZcashSDK.NetworkType {
|
|
||||||
init?(_ string: String) {
|
init?(_ string: String) {
|
||||||
switch string {
|
switch string {
|
||||||
case "main":
|
case "main":
|
||||||
|
|
|
@ -75,6 +75,7 @@ public class Initializer {
|
||||||
private(set) var accountRepository: AccountRepository
|
private(set) var accountRepository: AccountRepository
|
||||||
private(set) var storage: CompactBlockStorage
|
private(set) var storage: CompactBlockStorage
|
||||||
private(set) var downloader: CompactBlockDownloader
|
private(set) var downloader: CompactBlockDownloader
|
||||||
|
private(set) var network: ZcashNetwork
|
||||||
private(set) public var viewingKeys: [UnifiedViewingKey]
|
private(set) public var viewingKeys: [UnifiedViewingKey]
|
||||||
private(set) public var walletBirthday: WalletBirthday
|
private(set) public var walletBirthday: WalletBirthday
|
||||||
/**
|
/**
|
||||||
|
@ -91,10 +92,11 @@ public class Initializer {
|
||||||
dataDbURL: URL,
|
dataDbURL: URL,
|
||||||
pendingDbURL: URL,
|
pendingDbURL: URL,
|
||||||
endpoint: LightWalletEndpoint,
|
endpoint: LightWalletEndpoint,
|
||||||
|
network: ZcashNetwork,
|
||||||
spendParamsURL: URL,
|
spendParamsURL: URL,
|
||||||
outputParamsURL: URL,
|
outputParamsURL: URL,
|
||||||
viewingKeys: [UnifiedViewingKey],
|
viewingKeys: [UnifiedViewingKey],
|
||||||
walletBirthday: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT,
|
walletBirthday: BlockHeight,
|
||||||
alias: String = "",
|
alias: String = "",
|
||||||
loggerProxy: Logger? = nil) {
|
loggerProxy: Logger? = nil) {
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ public class Initializer {
|
||||||
|
|
||||||
self.init(rustBackend: ZcashRustBackend.self,
|
self.init(rustBackend: ZcashRustBackend.self,
|
||||||
lowerBoundHeight: walletBirthday,
|
lowerBoundHeight: walletBirthday,
|
||||||
|
network: network,
|
||||||
cacheDbURL: cacheDbURL,
|
cacheDbURL: cacheDbURL,
|
||||||
dataDbURL: dataDbURL,
|
dataDbURL: dataDbURL,
|
||||||
pendingDbURL: pendingDbURL,
|
pendingDbURL: pendingDbURL,
|
||||||
|
@ -124,6 +127,7 @@ public class Initializer {
|
||||||
*/
|
*/
|
||||||
init(rustBackend: ZcashRustBackendWelding.Type,
|
init(rustBackend: ZcashRustBackendWelding.Type,
|
||||||
lowerBoundHeight: BlockHeight,
|
lowerBoundHeight: BlockHeight,
|
||||||
|
network: ZcashNetwork,
|
||||||
cacheDbURL: URL,
|
cacheDbURL: URL,
|
||||||
dataDbURL: URL,
|
dataDbURL: URL,
|
||||||
pendingDbURL: URL,
|
pendingDbURL: URL,
|
||||||
|
@ -156,7 +160,8 @@ public class Initializer {
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.downloader = CompactBlockDownloader(service: service, storage: storage)
|
self.downloader = CompactBlockDownloader(service: service, storage: storage)
|
||||||
self.viewingKeys = viewingKeys
|
self.viewingKeys = viewingKeys
|
||||||
self.walletBirthday = WalletBirthday.birthday(with: walletBirthday)
|
self.walletBirthday = WalletBirthday.birthday(with: walletBirthday, network: network)
|
||||||
|
self.network = network
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,7 +187,7 @@ public class Initializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try rustBackend.initDataDb(dbData: dataDbURL)
|
try rustBackend.initDataDb(dbData: dataDbURL, networkType: network.networkType)
|
||||||
} catch RustWeldingError.dataDbNotEmpty {
|
} catch RustWeldingError.dataDbNotEmpty {
|
||||||
// this is fine
|
// this is fine
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -190,7 +195,7 @@ public class Initializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try rustBackend.initBlocksTable(dbData: dataDbURL, height: Int32(walletBirthday.height), hash: walletBirthday.hash, time: walletBirthday.time, saplingTree: walletBirthday.tree)
|
try rustBackend.initBlocksTable(dbData: dataDbURL, height: Int32(walletBirthday.height), hash: walletBirthday.hash, time: walletBirthday.time, saplingTree: walletBirthday.tree, networkType: network.networkType)
|
||||||
} catch RustWeldingError.dataDbNotEmpty {
|
} catch RustWeldingError.dataDbNotEmpty {
|
||||||
// this is fine
|
// this is fine
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -202,7 +207,7 @@ public class Initializer {
|
||||||
lowerBoundHeight = max(walletBirthday.height, lastDownloaded)
|
lowerBoundHeight = max(walletBirthday.height, lastDownloaded)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
guard try rustBackend.initAccountsTable(dbData: dataDbURL, uvks: viewingKeys) else {
|
guard try rustBackend.initAccountsTable(dbData: dataDbURL, uvks: viewingKeys, networkType: network.networkType) else {
|
||||||
throw rustBackend.lastError() ?? InitializerError.accountInitFailed
|
throw rustBackend.lastError() ?? InitializerError.accountInitFailed
|
||||||
}
|
}
|
||||||
} catch RustWeldingError.dataDbNotEmpty {
|
} catch RustWeldingError.dataDbNotEmpty {
|
||||||
|
@ -212,7 +217,9 @@ public class Initializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let migrationManager = MigrationManager(cacheDbConnection: SimpleConnectionProvider(path: cacheDbURL.path),
|
let migrationManager = MigrationManager(cacheDbConnection: SimpleConnectionProvider(path: cacheDbURL.path),
|
||||||
dataDbConnection: SimpleConnectionProvider(path: dataDbURL.path), pendingDbConnection: SimpleConnectionProvider(path: pendingDbURL.path))
|
dataDbConnection: SimpleConnectionProvider(path: dataDbURL.path),
|
||||||
|
pendingDbConnection: SimpleConnectionProvider(path: pendingDbURL.path),
|
||||||
|
networkType: self.network.networkType)
|
||||||
|
|
||||||
try migrationManager.performMigration(uvks: viewingKeys)
|
try migrationManager.performMigration(uvks: viewingKeys)
|
||||||
}
|
}
|
||||||
|
@ -229,7 +236,7 @@ public class Initializer {
|
||||||
- Parameter account: the index of the account
|
- Parameter account: the index of the account
|
||||||
*/
|
*/
|
||||||
public func getBalance(account index: Int = 0) -> Int64 {
|
public func getBalance(account index: Int = 0) -> Int64 {
|
||||||
rustBackend.getBalance(dbData: dataDbURL, account: Int32(index))
|
rustBackend.getBalance(dbData: dataDbURL, account: Int32(index), networkType: network.networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,20 +244,20 @@ public class Initializer {
|
||||||
- Parameter account: the index of the account
|
- Parameter account: the index of the account
|
||||||
*/
|
*/
|
||||||
public func getVerifiedBalance(account index: Int = 0) -> Int64 {
|
public func getVerifiedBalance(account index: Int = 0) -> Int64 {
|
||||||
rustBackend.getVerifiedBalance(dbData: dataDbURL, account: Int32(index))
|
rustBackend.getVerifiedBalance(dbData: dataDbURL, account: Int32(index), networkType: network.networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
checks if the provided address is a valid shielded zAddress
|
checks if the provided address is a valid shielded zAddress
|
||||||
*/
|
*/
|
||||||
public func isValidShieldedAddress(_ address: String) -> Bool {
|
public func isValidShieldedAddress(_ address: String) -> Bool {
|
||||||
(try? rustBackend.isValidShieldedAddress(address)) ?? false
|
(try? rustBackend.isValidShieldedAddress(address, networkType: network.networkType)) ?? false
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
checks if the provided address is a transparent zAddress
|
checks if the provided address is a transparent zAddress
|
||||||
*/
|
*/
|
||||||
public func isValidTransparentAddress(_ address: String) -> Bool {
|
public func isValidTransparentAddress(_ address: String) -> Bool {
|
||||||
(try? rustBackend.isValidTransparentAddress(address)) ?? false
|
(try? rustBackend.isValidTransparentAddress(address,networkType: network.networkType)) ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSpendParameterPresent() -> Bool {
|
func isSpendParameterPresent() -> Bool {
|
||||||
|
|
|
@ -21,23 +21,28 @@ public protocol ResourceProvider {
|
||||||
Convenience provider for a data db and cache db resources.
|
Convenience provider for a data db and cache db resources.
|
||||||
*/
|
*/
|
||||||
public struct DefaultResourceProvider: ResourceProvider {
|
public struct DefaultResourceProvider: ResourceProvider {
|
||||||
|
init(network: ZcashNetwork) {
|
||||||
|
self.network = network
|
||||||
|
}
|
||||||
|
var network: ZcashNetwork
|
||||||
public var dataDbURL: URL {
|
public var dataDbURL: URL {
|
||||||
|
let constants = network.constants
|
||||||
do {
|
do {
|
||||||
let url = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
let url = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||||
return url.appendingPathComponent(ZcashSDK.DEFAULT_DATA_DB_NAME)
|
return url.appendingPathComponent(constants.DEFAULT_DATA_DB_NAME)
|
||||||
} catch {
|
} catch {
|
||||||
return URL(fileURLWithPath: "file://\(ZcashSDK.DEFAULT_DATA_DB_NAME)")
|
return URL(fileURLWithPath: "file://\(constants.DEFAULT_DATA_DB_NAME)")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var cacheDbURL: URL {
|
public var cacheDbURL: URL {
|
||||||
|
let constants = network.constants
|
||||||
do {
|
do {
|
||||||
let path = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
let path = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||||
return path.appendingPathComponent(ZcashSDK.DEFAULT_CACHES_DB_NAME)
|
return path.appendingPathComponent(constants.DEFAULT_CACHES_DB_NAME)
|
||||||
} catch {
|
} catch {
|
||||||
return URL(fileURLWithPath: "file://\(ZcashSDK.DEFAULT_CACHES_DB_NAME)")
|
return URL(fileURLWithPath: "file://\(constants.DEFAULT_CACHES_DB_NAME)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
/**
|
/**
|
||||||
* Sets up the internal structure of the data database.
|
* Sets up the internal structure of the data database.
|
||||||
*/
|
*/
|
||||||
static func initDataDb(dbData: URL) throws {
|
static func initDataDb(dbData: URL, networkType: NetworkType) throws {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
guard zcashlc_init_data_database(dbData.0, dbData.1) != 0 else {
|
guard zcashlc_init_data_database(dbData.0, dbData.1, networkType.networkId) != 0 else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw throwDataDbError(error)
|
throw throwDataDbError(error)
|
||||||
}
|
}
|
||||||
|
@ -46,12 +46,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidShieldedAddress(_ address: String) throws -> Bool {
|
static func isValidShieldedAddress(_ address: String, networkType: NetworkType) throws -> Bool {
|
||||||
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
guard zcashlc_is_valid_shielded_address([CChar](address.utf8CString)) else {
|
guard zcashlc_is_valid_shielded_address([CChar](address.utf8CString), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidTransparentAddress(_ address: String) throws -> Bool {
|
static func isValidTransparentAddress(_ address: String, networkType: NetworkType) throws -> Bool {
|
||||||
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
guard zcashlc_is_valid_transparent_address([CChar](address.utf8CString)) else {
|
guard zcashlc_is_valid_transparent_address([CChar](address.utf8CString), networkType.networkId ) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -74,12 +74,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidExtendedFullViewingKey(_ key: String) throws -> Bool {
|
static func isValidExtendedFullViewingKey(_ key: String, networkType: NetworkType) throws -> Bool {
|
||||||
guard !key.containsCStringNullBytesBeforeStringEnding() else {
|
guard !key.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
guard zcashlc_is_valid_viewing_key([CChar](key.utf8CString)) else {
|
guard zcashlc_is_valid_viewing_key([CChar](key.utf8CString), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,10 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32) -> [String]? {
|
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32, networkType: NetworkType) -> [String]? {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
var capacity = UInt(0);
|
var capacity = UInt(0);
|
||||||
let extsksCStr = zcashlc_init_accounts_table(dbData.0, dbData.1, seed, UInt(seed.count), accounts, &capacity)
|
let extsksCStr = zcashlc_init_accounts_table(dbData.0, dbData.1, seed, UInt(seed.count), accounts, &capacity, networkType.networkId)
|
||||||
if extsksCStr == nil {
|
if extsksCStr == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return extsks
|
return extsks
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey]) throws -> Bool {
|
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey], networkType: NetworkType) throws -> Bool {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
var ffiUvks = [FFIUnifiedViewingKey]()
|
var ffiUvks = [FFIUnifiedViewingKey]()
|
||||||
|
@ -115,6 +115,10 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
guard !uvk.extpub.containsCStringNullBytesBeforeStringEnding() else {
|
guard !uvk.extpub.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard try self.isValidExtendedFullViewingKey(uvk.extfvk, networkType: networkType) else {
|
||||||
|
throw RustWeldingError.malformedStringInput
|
||||||
|
}
|
||||||
|
|
||||||
let extfvkCStr = [CChar](String(uvk.extfvk).utf8CString)
|
let extfvkCStr = [CChar](String(uvk.extfvk).utf8CString)
|
||||||
|
|
||||||
|
@ -133,7 +137,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
let slice = UnsafeMutablePointer<FFIUVKBoxedSlice>.allocate(capacity: 1)
|
let slice = UnsafeMutablePointer<FFIUVKBoxedSlice>.allocate(capacity: 1)
|
||||||
slice.initialize(to: FFIUVKBoxedSlice(ptr: p.baseAddress, len: UInt(p.count)))
|
slice.initialize(to: FFIUVKBoxedSlice(ptr: p.baseAddress, len: UInt(p.count)))
|
||||||
|
|
||||||
result = zcashlc_init_accounts_table_with_keys(dbData.0, dbData.1, slice)
|
result = zcashlc_init_accounts_table_with_keys(dbData.0, dbData.1, slice, networkType.networkId)
|
||||||
slice.deinitialize(count: 1)
|
slice.deinitialize(count: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,29 +151,8 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return result
|
return result
|
||||||
|
|
||||||
}
|
}
|
||||||
// static func initAccountsTable(dbData: URL, exfvks: [String]) throws -> Bool {
|
|
||||||
// let dbData = dbData.osStr()
|
|
||||||
// let viewingKeys = exfvks.map { UnsafePointer(strdup($0)) }
|
|
||||||
//
|
|
||||||
// guard exfvks.count > 0 else {
|
|
||||||
// throw RustWeldingError.malformedStringInput
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let res = zcashlc_init_accounts_table_with_keys(dbData.0, dbData.1, viewingKeys, UInt(viewingKeys.count));
|
|
||||||
//
|
|
||||||
// viewingKeys.compactMap({ UnsafeMutablePointer(mutating: $0) }).forEach({ free($0) })
|
|
||||||
//
|
|
||||||
// guard res else {
|
|
||||||
// if let error = lastError() {
|
|
||||||
// throw error
|
|
||||||
// }
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
// return res
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String) throws {
|
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String, networkType: NetworkType) throws {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
guard !hash.containsCStringNullBytesBeforeStringEnding() else {
|
guard !hash.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
|
@ -180,7 +163,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard zcashlc_init_blocks_table(dbData.0, dbData.1, height, [CChar](hash.utf8CString), time, [CChar](saplingTree.utf8CString)) != 0 else {
|
guard zcashlc_init_blocks_table(dbData.0, dbData.1, height, [CChar](hash.utf8CString), time, [CChar](saplingTree.utf8CString), networkType.networkId) != 0 else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -188,52 +171,65 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getAddress(dbData: URL, account: Int32) -> String? {
|
static func getAddress(dbData: URL, account: Int32, networkType: NetworkType) -> String? {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
guard let addressCStr = zcashlc_get_address(dbData.0, dbData.1, account) else { return nil }
|
guard let addressCStr = zcashlc_get_address(dbData.0, dbData.1, account, networkType.networkId) else { return nil }
|
||||||
|
|
||||||
let address = String(validatingUTF8: addressCStr)
|
let address = String(validatingUTF8: addressCStr)
|
||||||
zcashlc_string_free(addressCStr)
|
zcashlc_string_free(addressCStr)
|
||||||
return address
|
return address
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getBalance(dbData: URL, account: Int32) -> Int64 {
|
static func getBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64 {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_get_balance(dbData.0, dbData.1, account)
|
return zcashlc_get_balance(dbData.0, dbData.1, account, networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getVerifiedBalance(dbData: URL, account: Int32) -> Int64 {
|
static func getVerifiedBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64 {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_get_verified_balance(dbData.0, dbData.1, account)
|
return zcashlc_get_verified_balance(dbData.0, dbData.1, account, networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getVerifiedTransparentBalance(dbData: URL, address: String) throws -> Int64 {
|
static func getVerifiedTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64 {
|
||||||
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard try isValidTransparentAddress(address, networkType: networkType) else {
|
||||||
|
throw RustWeldingError.unableToDeriveKeys
|
||||||
|
}
|
||||||
|
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
return zcashlc_get_verified_transparent_balance(dbData.0, dbData.1, [CChar](address.utf8CString))
|
return zcashlc_get_verified_transparent_balance(dbData.0, dbData.1, [CChar](address.utf8CString), networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getTransparentBalance(dbData: URL, address: String) throws -> Int64 {
|
static func getTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64 {
|
||||||
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard try self.isValidTransparentAddress(address, networkType: networkType) else {
|
||||||
|
throw RustWeldingError.unableToDeriveKeys
|
||||||
|
}
|
||||||
|
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_get_total_transparent_balance(dbData.0, dbData.1, [CChar](address.utf8CString))
|
return zcashlc_get_total_transparent_balance(dbData.0, dbData.1, [CChar](address.utf8CString), networkType.networkId)
|
||||||
}
|
}
|
||||||
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT) throws -> Int32 {
|
|
||||||
|
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight, networkType: NetworkType) throws -> Int32 {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
guard !address.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = zcashlc_clear_utxos(dbData.0, dbData.1, [CChar](address.utf8CString), Int32(sinceHeight))
|
guard try isValidTransparentAddress(address, networkType: networkType) else {
|
||||||
|
throw RustWeldingError.unableToDeriveKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = zcashlc_clear_utxos(dbData.0, dbData.1, [CChar](address.utf8CString), Int32(sinceHeight), networkType.networkId)
|
||||||
|
|
||||||
guard result > 0 else {
|
guard result > 0 else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
|
@ -244,7 +240,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight) throws -> Bool {
|
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight, networkType: NetworkType) throws -> Bool {
|
||||||
|
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
|
@ -261,7 +257,8 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
script,
|
script,
|
||||||
UInt(script.count),
|
UInt(script.count),
|
||||||
value,
|
value,
|
||||||
Int32(height)) else {
|
Int32(height),
|
||||||
|
networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -270,60 +267,61 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func downloadedUtxoBalance(dbData: URL, address: String) throws -> WalletBalance {
|
static func downloadedUtxoBalance(dbData: URL, address: String, networkType: NetworkType) throws -> WalletBalance {
|
||||||
let verified = try getVerifiedTransparentBalance(dbData: dbData, address: address)
|
let verified = try getVerifiedTransparentBalance(dbData: dbData, address: address, networkType: networkType)
|
||||||
let total = try getTransparentBalance(dbData: dbData, address: address)
|
let total = try getTransparentBalance(dbData: dbData, address: address, networkType: networkType)
|
||||||
return TransparentBalance(verified: verified, total: total, address: address)
|
return TransparentBalance(verified: verified, total: total, address: address)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
|
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String? {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
guard let memoCStr = zcashlc_get_received_memo_as_utf8(dbData.0, dbData.1, idNote) else { return nil }
|
guard let memoCStr = zcashlc_get_received_memo_as_utf8(dbData.0, dbData.1, idNote, networkType.networkId) else { return nil }
|
||||||
|
|
||||||
let memo = String(validatingUTF8: memoCStr)
|
let memo = String(validatingUTF8: memoCStr)
|
||||||
zcashlc_string_free(memoCStr)
|
zcashlc_string_free(memoCStr)
|
||||||
return memo
|
return memo
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
|
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String? {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
|
|
||||||
guard let memoCStr = zcashlc_get_sent_memo_as_utf8(dbData.0, dbData.1, idNote) else { return nil }
|
guard let memoCStr = zcashlc_get_sent_memo_as_utf8(dbData.0, dbData.1, idNote, networkType.networkId) else { return nil }
|
||||||
|
|
||||||
let memo = String(validatingUTF8: memoCStr)
|
let memo = String(validatingUTF8: memoCStr)
|
||||||
zcashlc_string_free(memoCStr)
|
zcashlc_string_free(memoCStr)
|
||||||
return memo
|
return memo
|
||||||
}
|
}
|
||||||
|
|
||||||
static func validateCombinedChain(dbCache: URL, dbData: URL) -> Int32 {
|
static func validateCombinedChain(dbCache: URL, dbData: URL, networkType: NetworkType) -> Int32 {
|
||||||
let dbCache = dbCache.osStr()
|
let dbCache = dbCache.osStr()
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_validate_combined_chain(dbCache.0, dbCache.1, dbData.0, dbData.1)
|
return zcashlc_validate_combined_chain(dbCache.0, dbCache.1, dbData.0, dbData.1, networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getNearestRewindHeight(dbData: URL, height: Int32) -> Int32 {
|
static func getNearestRewindHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Int32 {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_get_nearest_rewind_height(dbData.0, dbData.1, height)
|
return zcashlc_get_nearest_rewind_height(dbData.0, dbData.1, height, networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func rewindToHeight(dbData: URL, height: Int32) -> Bool {
|
static func rewindToHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Bool {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_rewind_to_height(dbData.0, dbData.1, height)
|
return zcashlc_rewind_to_height(dbData.0, dbData.1, height, networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32 = 0) -> Bool {
|
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32 = 0, networkType: NetworkType) -> Bool {
|
||||||
let dbCache = dbCache.osStr()
|
let dbCache = dbCache.osStr()
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_scan_blocks(dbCache.0, dbCache.1, dbData.0, dbData.1, limit) != 0
|
return zcashlc_scan_blocks(dbCache.0, dbCache.1, dbData.0, dbData.1, limit, networkType.networkId) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8]) -> Bool {
|
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8], networkType: NetworkType) -> Bool {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
return zcashlc_decrypt_and_store_transaction(dbData.0, dbData.1, tx, UInt(tx.count)) != 0
|
return zcashlc_decrypt_and_store_transaction(dbData.0, dbData.1, tx, UInt(tx.count), networkType.networkId) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
static func createToAddress(dbData: URL, account: Int32, extsk: String, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64 {
|
static func createToAddress(dbData: URL, account: Int32, extsk: String, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64 {
|
||||||
|
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
let memoBytes = memo ?? ""
|
let memoBytes = memo ?? ""
|
||||||
|
|
||||||
|
@ -337,10 +335,11 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
spendParamsPath,
|
spendParamsPath,
|
||||||
UInt(spendParamsPath.lengthOfBytes(using: .utf8)),
|
UInt(spendParamsPath.lengthOfBytes(using: .utf8)),
|
||||||
outputParamsPath,
|
outputParamsPath,
|
||||||
UInt(outputParamsPath.lengthOfBytes(using: .utf8)))
|
UInt(outputParamsPath.lengthOfBytes(using: .utf8)),
|
||||||
|
networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64 {
|
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64 {
|
||||||
let dbData = dbData.osStr()
|
let dbData = dbData.osStr()
|
||||||
let memoBytes = memo ?? ""
|
let memoBytes = memo ?? ""
|
||||||
|
|
||||||
|
@ -353,16 +352,18 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
spendParamsPath,
|
spendParamsPath,
|
||||||
UInt(spendParamsPath.lengthOfBytes(using: .utf8)),
|
UInt(spendParamsPath.lengthOfBytes(using: .utf8)),
|
||||||
outputParamsPath,
|
outputParamsPath,
|
||||||
UInt(outputParamsPath.lengthOfBytes(using: .utf8)))
|
UInt(outputParamsPath.lengthOfBytes(using: .utf8)),
|
||||||
|
networkType.networkId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedFullViewingKey(_ spendingKey: String) throws -> String? {
|
static func deriveExtendedFullViewingKey(_ spendingKey: String, networkType: NetworkType) throws -> String? {
|
||||||
|
|
||||||
guard !spendingKey.containsCStringNullBytesBeforeStringEnding() else {
|
guard !spendingKey.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let extsk = zcashlc_derive_extended_full_viewing_key([CChar](spendingKey.utf8CString)) else {
|
guard let extsk = zcashlc_derive_extended_full_viewing_key([CChar](spendingKey.utf8CString),
|
||||||
|
networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -375,9 +376,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return derived
|
return derived
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32) throws -> [String]? {
|
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
var capacity = UInt(0);
|
var capacity = UInt(0);
|
||||||
guard let extsksCStr = zcashlc_derive_extended_full_viewing_keys(seed, UInt(seed.count), accounts, &capacity) else {
|
guard let extsksCStr = zcashlc_derive_extended_full_viewing_keys(seed, UInt(seed.count), accounts, &capacity, networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -392,9 +393,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return extsks
|
return extsks
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32) throws -> [String]? {
|
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
var capacity = UInt(0);
|
var capacity = UInt(0);
|
||||||
guard let extsksCStr = zcashlc_derive_extended_spending_keys(seed, UInt(seed.count), accounts, &capacity) else {
|
guard let extsksCStr = zcashlc_derive_extended_spending_keys(seed, UInt(seed.count), accounts, &capacity, networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -409,9 +410,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return extsks
|
return extsks
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int) throws -> [UnifiedViewingKey] {
|
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int, networkType: NetworkType) throws -> [UnifiedViewingKey] {
|
||||||
|
|
||||||
guard let uvks_struct = zcashlc_derive_unified_viewing_keys_from_seed(seed, UInt(seed.count), Int32(numberOfAccounts)) else {
|
guard let uvks_struct = zcashlc_derive_unified_viewing_keys_from_seed(seed, UInt(seed.count), Int32(numberOfAccounts), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -443,8 +444,8 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return uvks
|
return uvks
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32) throws -> String? {
|
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32, networkType: NetworkType) throws -> String? {
|
||||||
guard let zaddrCStr = zcashlc_derive_shielded_address_from_seed(seed, UInt(seed.count), accountIndex) else {
|
guard let zaddrCStr = zcashlc_derive_shielded_address_from_seed(seed, UInt(seed.count), accountIndex, networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -457,12 +458,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return zAddr
|
return zAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveShieldedAddressFromViewingKey(_ extfvk: String) throws -> String? {
|
static func deriveShieldedAddressFromViewingKey(_ extfvk: String, networkType: NetworkType) throws -> String? {
|
||||||
guard !extfvk.containsCStringNullBytesBeforeStringEnding() else {
|
guard !extfvk.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let zaddrCStr = zcashlc_derive_shielded_address_from_viewing_key([CChar](extfvk.utf8CString)) else {
|
guard let zaddrCStr = zcashlc_derive_shielded_address_from_viewing_key([CChar](extfvk.utf8CString), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -475,9 +476,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return zAddr
|
return zAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String? {
|
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String? {
|
||||||
|
|
||||||
guard let tAddrCStr = zcashlc_derive_transparent_address_from_seed(seed, UInt(seed.count), Int32(account), Int32(index)) else {
|
guard let tAddrCStr = zcashlc_derive_transparent_address_from_seed(seed, UInt(seed.count), Int32(account), Int32(index), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -489,8 +490,8 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return tAddr
|
return tAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String? {
|
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String? {
|
||||||
guard let skCStr = zcashlc_derive_transparent_private_key_from_seed(seed, UInt(seed.count), Int32(account), Int32(index)) else {
|
guard let skCStr = zcashlc_derive_transparent_private_key_from_seed(seed, UInt(seed.count), Int32(account), Int32(index), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -501,12 +502,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return sk
|
return sk
|
||||||
}
|
}
|
||||||
|
|
||||||
static func derivedTransparentAddressFromPublicKey(_ pubkey: String) throws -> String {
|
static func derivedTransparentAddressFromPublicKey(_ pubkey: String, networkType: NetworkType) throws -> String {
|
||||||
guard !pubkey.containsCStringNullBytesBeforeStringEnding() else {
|
guard !pubkey.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let tAddrCStr = zcashlc_derive_transparent_address_from_public_key([CChar](pubkey.utf8CString)), let tAddr = String(validatingUTF8: tAddrCStr) else {
|
guard let tAddrCStr = zcashlc_derive_transparent_address_from_public_key([CChar](pubkey.utf8CString), networkType.networkId), let tAddr = String(validatingUTF8: tAddrCStr) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -515,12 +516,12 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return tAddr
|
return tAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSecretKey(_ tsk: String) throws -> String? {
|
static func deriveTransparentAddressFromSecretKey(_ tsk: String, networkType: NetworkType) throws -> String? {
|
||||||
|
|
||||||
guard !tsk.containsCStringNullBytesBeforeStringEnding() else {
|
guard !tsk.containsCStringNullBytesBeforeStringEnding() else {
|
||||||
throw RustWeldingError.malformedStringInput
|
throw RustWeldingError.malformedStringInput
|
||||||
}
|
}
|
||||||
guard let tAddrCStr = zcashlc_derive_transparent_address_from_secret_key([CChar](tsk.utf8CString)) else {
|
guard let tAddrCStr = zcashlc_derive_transparent_address_from_secret_key([CChar](tsk.utf8CString), networkType.networkId) else {
|
||||||
if let error = lastError() {
|
if let error = lastError() {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
@ -531,8 +532,8 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
||||||
return tAddr
|
return tAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
static func consensusBranchIdFor(height: Int32) throws -> Int32 {
|
static func consensusBranchIdFor(height: Int32, networkType: NetworkType) throws -> Int32 {
|
||||||
let branchId = zcashlc_branch_id_for_height(height)
|
let branchId = zcashlc_branch_id_for_height(height, networkType.networkId)
|
||||||
|
|
||||||
guard branchId != -1 else {
|
guard branchId != -1 else {
|
||||||
throw RustWeldingError.noConsensusBranchId(height: height)
|
throw RustWeldingError.noConsensusBranchId(height: height)
|
||||||
|
|
|
@ -35,25 +35,25 @@ public protocol ZcashRustBackendWelding {
|
||||||
initializes the data db
|
initializes the data db
|
||||||
- Parameter dbData: location of the data db sql file
|
- Parameter dbData: location of the data db sql file
|
||||||
*/
|
*/
|
||||||
static func initDataDb(dbData: URL) throws
|
static func initDataDb(dbData: URL, networkType: NetworkType) throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
- Returns: true when the address is valid and shielded. Returns false in any other case
|
- Returns: true when the address is valid and shielded. Returns false in any other case
|
||||||
- Throws: Error when the provided address belongs to another network
|
- Throws: Error when the provided address belongs to another network
|
||||||
*/
|
*/
|
||||||
static func isValidShieldedAddress(_ address: String) throws -> Bool
|
static func isValidShieldedAddress(_ address: String, networkType: NetworkType) throws -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
- Returns: true when the address is valid and transparent. false in any other case
|
- Returns: true when the address is valid and transparent. false in any other case
|
||||||
- Throws: Error when the provided address belongs to another network
|
- Throws: Error when the provided address belongs to another network
|
||||||
*/
|
*/
|
||||||
static func isValidTransparentAddress(_ address: String) throws -> Bool
|
static func isValidTransparentAddress(_ address: String, networkType: NetworkType) throws -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
- Returns: true when the address is valid and transparent. false in any other case
|
- Returns: true when the address is valid and transparent. false in any other case
|
||||||
- Throws: Error when there's another problem not related to validity of the string in question
|
- Throws: Error when there's another problem not related to validity of the string in question
|
||||||
*/
|
*/
|
||||||
static func isValidExtendedFullViewingKey(_ key: String) throws -> Bool
|
static func isValidExtendedFullViewingKey(_ key: String, networkType: NetworkType) throws -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
initialize the accounts table from a given seed and a number of accounts
|
initialize the accounts table from a given seed and a number of accounts
|
||||||
|
@ -62,7 +62,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- seed: byte array of the zip32 seed
|
- seed: byte array of the zip32 seed
|
||||||
- accounts: how many accounts you want to have
|
- accounts: how many accounts you want to have
|
||||||
*/
|
*/
|
||||||
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32) -> [String]?
|
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32, networkType: NetworkType) -> [String]?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
initialize the accounts table from a set of unified viewing keys
|
initialize the accounts table from a set of unified viewing keys
|
||||||
|
@ -70,7 +70,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- dbData: location of the data db
|
- dbData: location of the data db
|
||||||
- uvks: an array of UnifiedViewingKeys
|
- uvks: an array of UnifiedViewingKeys
|
||||||
*/
|
*/
|
||||||
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey]) throws -> Bool
|
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey], networkType: NetworkType) throws -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
initialize the blocks table from a given checkpoint (birthday)
|
initialize the blocks table from a given checkpoint (birthday)
|
||||||
|
@ -81,7 +81,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- time: in milliseconds from reference
|
- time: in milliseconds from reference
|
||||||
- saplingTree: hash of the sapling tree
|
- saplingTree: hash of the sapling tree
|
||||||
*/
|
*/
|
||||||
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String) throws
|
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String, networkType: NetworkType) throws
|
||||||
|
|
||||||
/**
|
/**
|
||||||
gets the address from data db from the given account
|
gets the address from data db from the given account
|
||||||
|
@ -90,38 +90,38 @@ public protocol ZcashRustBackendWelding {
|
||||||
- account: index of the given account
|
- account: index of the given account
|
||||||
- Returns: an optional string with the address if found
|
- Returns: an optional string with the address if found
|
||||||
*/
|
*/
|
||||||
static func getAddress(dbData: URL, account: Int32) -> String?
|
static func getAddress(dbData: URL, account: Int32, networkType: NetworkType) -> String?
|
||||||
/**
|
/**
|
||||||
get the (unverified) balance from the given account
|
get the (unverified) balance from the given account
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- dbData: location of the data db
|
- dbData: location of the data db
|
||||||
- account: index of the given account
|
- account: index of the given account
|
||||||
*/
|
*/
|
||||||
static func getBalance(dbData: URL, account: Int32) -> Int64
|
static func getBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64
|
||||||
/**
|
/**
|
||||||
get the verified balance from the given account
|
get the verified balance from the given account
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- dbData: location of the data db
|
- dbData: location of the data db
|
||||||
- account: index of the given account
|
- account: index of the given account
|
||||||
*/
|
*/
|
||||||
static func getVerifiedBalance(dbData: URL, account: Int32) -> Int64
|
static func getVerifiedBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the verified cached transparent balance for the given address
|
Get the verified cached transparent balance for the given address
|
||||||
*/
|
*/
|
||||||
static func getVerifiedTransparentBalance(dbData: URL, address: String) throws -> Int64
|
static func getVerifiedTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the verified cached transparent balance for the given address
|
Get the verified cached transparent balance for the given address
|
||||||
*/
|
*/
|
||||||
static func getTransparentBalance(dbData: URL, address: String) throws -> Int64
|
static func getTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64
|
||||||
/**
|
/**
|
||||||
get received memo from note
|
get received memo from note
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- dbData: location of the data db file
|
- dbData: location of the data db file
|
||||||
- idNote: note_id of note where the memo is located
|
- idNote: note_id of note where the memo is located
|
||||||
*/
|
*/
|
||||||
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64) -> String?
|
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
get sent memo from note
|
get sent memo from note
|
||||||
|
@ -129,7 +129,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- dbData: location of the data db file
|
- dbData: location of the data db file
|
||||||
- idNote: note_id of note where the memo is located
|
- idNote: note_id of note where the memo is located
|
||||||
*/
|
*/
|
||||||
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64) -> String?
|
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Checks that the scanned blocks in the data database, when combined with the recent
|
Checks that the scanned blocks in the data database, when combined with the recent
|
||||||
|
@ -145,7 +145,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
* `0` if there was an error during validation unrelated to chain validity.
|
* `0` if there was an error during validation unrelated to chain validity.
|
||||||
- Important: This function does not mutate either of the databases.
|
- Important: This function does not mutate either of the databases.
|
||||||
*/
|
*/
|
||||||
static func validateCombinedChain(dbCache: URL, dbData: URL) -> Int32
|
static func validateCombinedChain(dbCache: URL, dbData: URL, networkType: NetworkType) -> Int32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the nearest height where a rewind is possible. Currently prunning gets rid of sapling witnesses older
|
Returns the nearest height where a rewind is possible. Currently prunning gets rid of sapling witnesses older
|
||||||
|
@ -155,14 +155,14 @@ public protocol ZcashRustBackendWelding {
|
||||||
- dbData: location of the data db file
|
- dbData: location of the data db file
|
||||||
- height: height you would like to rewind to.
|
- height: height you would like to rewind to.
|
||||||
*/
|
*/
|
||||||
static func getNearestRewindHeight(dbData: URL, height: Int32) -> Int32
|
static func getNearestRewindHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Int32
|
||||||
/**
|
/**
|
||||||
rewinds the compact block storage to the given height. clears up all derived data as well
|
rewinds the compact block storage to the given height. clears up all derived data as well
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- dbData: location of the data db file
|
- dbData: location of the data db file
|
||||||
- height: height to rewind to. DON'T PASS ARBITRARY HEIGHT. Use getNearestRewindHeight when unsure
|
- height: height to rewind to. DON'T PASS ARBITRARY HEIGHT. Use getNearestRewindHeight when unsure
|
||||||
*/
|
*/
|
||||||
static func rewindToHeight(dbData: URL, height: Int32) -> Bool
|
static func rewindToHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Scans new blocks added to the cache for any transactions received by the tracked
|
Scans new blocks added to the cache for any transactions received by the tracked
|
||||||
|
@ -183,7 +183,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- limit: scan up to limit blocks. pass 0 to set no limit.
|
- limit: scan up to limit blocks. pass 0 to set no limit.
|
||||||
returns false if fails to scan.
|
returns false if fails to scan.
|
||||||
*/
|
*/
|
||||||
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32) -> Bool
|
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32, networkType: NetworkType) -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
puts a UTXO into the data db database
|
puts a UTXO into the data db database
|
||||||
|
@ -196,7 +196,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- height: the mined height for the UTXO
|
- height: the mined height for the UTXO
|
||||||
- Returns: true if the operation succeded or false otherwise
|
- Returns: true if the operation succeded or false otherwise
|
||||||
*/
|
*/
|
||||||
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight) throws -> Bool
|
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight, networkType: NetworkType) throws -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
clears the cached utxos for the given address from the specified height on
|
clears the cached utxos for the given address from the specified height on
|
||||||
|
@ -207,7 +207,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: the amount of UTXOs cleared or -1 on error
|
- Returns: the amount of UTXOs cleared or -1 on error
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight) throws -> Int32
|
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight, networkType: NetworkType) throws -> Int32
|
||||||
/**
|
/**
|
||||||
Gets the balance of the previously downloaded UTXOs
|
Gets the balance of the previously downloaded UTXOs
|
||||||
- Parameters:
|
- Parameters:
|
||||||
|
@ -216,7 +216,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: the wallet balance containing verified and total balance.
|
- Returns: the wallet balance containing verified and total balance.
|
||||||
- Throws: Rustwelding Error if something fails
|
- Throws: Rustwelding Error if something fails
|
||||||
*/
|
*/
|
||||||
static func downloadedUtxoBalance(dbData: URL, address: String) throws -> WalletBalance
|
static func downloadedUtxoBalance(dbData: URL, address: String, networkType: NetworkType) throws -> WalletBalance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Scans a transaction for any information that can be decrypted by the accounts in the
|
Scans a transaction for any information that can be decrypted by the accounts in the
|
||||||
|
@ -227,7 +227,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- tx: the transaction to decrypt
|
- tx: the transaction to decrypt
|
||||||
returns false if fails to decrypt.
|
returns false if fails to decrypt.
|
||||||
*/
|
*/
|
||||||
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8]) -> Bool
|
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8], networkType: NetworkType) -> Bool
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a transaction to the given address from the given account
|
Creates a transaction to the given address from the given account
|
||||||
|
@ -241,7 +241,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
|
- spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
|
||||||
- outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
|
- outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
|
||||||
*/
|
*/
|
||||||
static func createToAddress(dbData: URL, account: Int32, extsk: String, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64
|
static func createToAddress(dbData: URL, account: Int32, extsk: String, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a transaction to shield all found UTXOs in cache db.
|
Creates a transaction to shield all found UTXOs in cache db.
|
||||||
|
@ -255,7 +255,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
|
- spendParamsPath: path escaped String for the filesystem locations where the spend parameters are located
|
||||||
- outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
|
- outputParamsPath: path escaped String for the filesystem locations where the output parameters are located
|
||||||
*/
|
*/
|
||||||
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64
|
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a full viewing key from a seed
|
Derives a full viewing key from a seed
|
||||||
|
@ -263,7 +263,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: the derived key
|
- Returns: the derived key
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveExtendedFullViewingKey(_ spendingKey: String) throws -> String?
|
static func deriveExtendedFullViewingKey(_ spendingKey: String, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a set of full viewing keys from a seed
|
Derives a set of full viewing keys from a seed
|
||||||
|
@ -272,7 +272,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an array containing the derived keys
|
- Returns: an array containing the derived keys
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32) throws -> [String]?
|
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a set of full viewing keys from a seed
|
Derives a set of full viewing keys from a seed
|
||||||
|
@ -281,7 +281,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an array containing the spending keys
|
- Returns: an array containing the spending keys
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32) throws -> [String]?
|
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a shielded address from a seed
|
Derives a shielded address from a seed
|
||||||
|
@ -290,7 +290,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an optional String containing the Shielded address
|
- Returns: an optional String containing the Shielded address
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32) throws -> String?
|
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a shielded address from an Extended Full Viewing Key
|
Derives a shielded address from an Extended Full Viewing Key
|
||||||
|
@ -298,7 +298,7 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an optional String containing the Shielded address
|
- Returns: an optional String containing the Shielded address
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveShieldedAddressFromViewingKey(_ extfvk: String) throws -> String?
|
static func deriveShieldedAddressFromViewingKey(_ extfvk: String, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a shielded address from an Extended Full Viewing Key
|
Derives a shielded address from an Extended Full Viewing Key
|
||||||
|
@ -306,14 +306,14 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an optional String containing the transparent address
|
- Returns: an optional String containing the transparent address
|
||||||
- Throws: RustBackendError if fatal error occurs
|
- Throws: RustBackendError if fatal error occurs
|
||||||
*/
|
*/
|
||||||
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String?
|
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a transparent secret key from Seed
|
Derives a transparent secret key from Seed
|
||||||
- Parameter seed: an array of bytes containing the seed
|
- Parameter seed: an array of bytes containing the seed
|
||||||
- Returns: an optional String containing the transparent secret (private) key
|
- Returns: an optional String containing the transparent secret (private) key
|
||||||
*/
|
*/
|
||||||
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String?
|
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a transparent address from a secret key
|
Derives a transparent address from a secret key
|
||||||
|
@ -321,18 +321,18 @@ public protocol ZcashRustBackendWelding {
|
||||||
- Returns: an optional String containing the transparent address.
|
- Returns: an optional String containing the transparent address.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSecretKey(_ tsk: String) throws -> String?
|
static func deriveTransparentAddressFromSecretKey(_ tsk: String, networkType: NetworkType) throws -> String?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Derives a tranparent address from a public key
|
Derives a tranparent address from a public key
|
||||||
- Parameter pubkey: public key represented as a string
|
- Parameter pubkey: public key represented as a string
|
||||||
*/
|
*/
|
||||||
static func derivedTransparentAddressFromPublicKey(_ pubkey: String) throws -> String
|
static func derivedTransparentAddressFromPublicKey(_ pubkey: String, networkType: NetworkType) throws -> String
|
||||||
|
|
||||||
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int) throws -> [UnifiedViewingKey]
|
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int, networkType: NetworkType) throws -> [UnifiedViewingKey]
|
||||||
/**
|
/**
|
||||||
Gets the consensus branch id for the given height
|
Gets the consensus branch id for the given height
|
||||||
- Parameter height: the height you what to know the branch id for
|
- Parameter height: the height you what to know the branch id for
|
||||||
*/
|
*/
|
||||||
static func consensusBranchIdFor(height: Int32) throws -> Int32
|
static func consensusBranchIdFor(height: Int32, networkType: NetworkType) throws -> Int32
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,7 +336,7 @@ extension LightWalletGRPCService: LightWalletService {
|
||||||
return height
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchUTXOs(for tAddress: String, height: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT) throws -> [UnspentTransactionOutputEntity] {
|
public func fetchUTXOs(for tAddress: String, height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||||
let arg = GetAddressUtxosArg.with { (utxoArgs) in
|
let arg = GetAddressUtxosArg.with { (utxoArgs) in
|
||||||
utxoArgs.addresses = [tAddress]
|
utxoArgs.addresses = [tAddress]
|
||||||
utxoArgs.startHeight = UInt64(height)
|
utxoArgs.startHeight = UInt64(height)
|
||||||
|
@ -358,7 +358,7 @@ extension LightWalletGRPCService: LightWalletService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchUTXOs(for tAddress: String, height: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT, result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void) {
|
public func fetchUTXOs(for tAddress: String, height: BlockHeight, result: @escaping (Result<[UnspentTransactionOutputEntity], LightWalletServiceError>) -> Void) {
|
||||||
queue.async { [weak self] in
|
queue.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
let arg = GetAddressUtxosArg.with { (utxoArgs) in
|
let arg = GetAddressUtxosArg.with { (utxoArgs) in
|
||||||
|
@ -394,7 +394,7 @@ extension LightWalletGRPCService: LightWalletService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchUTXOs(for tAddresses: [String], height: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT) throws -> [UnspentTransactionOutputEntity] {
|
public func fetchUTXOs(for tAddresses: [String], height: BlockHeight) throws -> [UnspentTransactionOutputEntity] {
|
||||||
|
|
||||||
guard tAddresses.count > 0 else {
|
guard tAddresses.count > 0 else {
|
||||||
return [] // FIXME: throw a real error
|
return [] // FIXME: throw a real error
|
||||||
|
|
|
@ -16,17 +16,11 @@ extension CompactBlockRange {
|
||||||
|
|
||||||
extension BlockID {
|
extension BlockID {
|
||||||
|
|
||||||
static let saplingActivationHeight: UInt64 = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
|
||||||
|
|
||||||
init(height: UInt64) {
|
init(height: UInt64) {
|
||||||
self = BlockID()
|
self = BlockID()
|
||||||
self.height = height
|
self.height = height
|
||||||
}
|
}
|
||||||
|
|
||||||
static var saplingActivation: BlockID {
|
|
||||||
BlockID(height: saplingActivationHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
init(height: BlockHeight) {
|
init(height: BlockHeight) {
|
||||||
self.init(height: UInt64(height))
|
self.init(height: UInt64(height))
|
||||||
}
|
}
|
||||||
|
@ -46,16 +40,6 @@ extension BlockRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func sinceSaplingActivation(to height: UInt64? = nil) -> BlockRange {
|
|
||||||
var blockRange = BlockRange()
|
|
||||||
|
|
||||||
blockRange.start = BlockID.saplingActivation
|
|
||||||
if let height = height {
|
|
||||||
blockRange.end = BlockID.init(height: height)
|
|
||||||
}
|
|
||||||
return blockRange
|
|
||||||
}
|
|
||||||
|
|
||||||
var compactBlockRange: CompactBlockRange {
|
var compactBlockRange: CompactBlockRange {
|
||||||
return Int(self.start.height) ... Int(self.end.height)
|
return Int(self.start.height) ... Int(self.end.height)
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,7 +394,6 @@ extension SyncStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension SyncStatus {
|
extension SyncStatus {
|
||||||
init(_ blockProcessorProgress: CompactBlockProgress) {
|
init(_ blockProcessorProgress: CompactBlockProgress) {
|
||||||
switch blockProcessorProgress {
|
switch blockProcessorProgress {
|
||||||
|
|
|
@ -107,7 +107,11 @@ public class DerivationTool: KeyDeriving {
|
||||||
|
|
||||||
var rustwelding: ZcashRustBackendWelding.Type = ZcashRustBackend.self
|
var rustwelding: ZcashRustBackendWelding.Type = ZcashRustBackend.self
|
||||||
|
|
||||||
public static let `default` = DerivationTool()
|
var networkType: NetworkType
|
||||||
|
|
||||||
|
public init(networkType: NetworkType) {
|
||||||
|
self.networkType = networkType
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
Given a seed and a number of accounts, return the associated viewing keys.
|
Given a seed and a number of accounts, return the associated viewing keys.
|
||||||
|
|
||||||
|
@ -123,7 +127,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
guard let keys = try rustwelding.deriveExtendedFullViewingKeys(seed: seed, accounts: numberOfAccounts) else {
|
guard let keys = try rustwelding.deriveExtendedFullViewingKeys(seed: seed, accounts: numberOfAccounts, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return keys
|
return keys
|
||||||
|
@ -141,7 +145,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
*/
|
*/
|
||||||
public func deriveViewingKey(spendingKey: String) throws -> String {
|
public func deriveViewingKey(spendingKey: String) throws -> String {
|
||||||
do {
|
do {
|
||||||
guard let key = try rustwelding.deriveExtendedFullViewingKey(spendingKey) else {
|
guard let key = try rustwelding.deriveExtendedFullViewingKey(spendingKey, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return key
|
return key
|
||||||
|
@ -165,7 +169,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
throw KeyDerivationErrors.invalidInput
|
throw KeyDerivationErrors.invalidInput
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
guard let keys = try rustwelding.deriveExtendedSpendingKeys(seed: seed, accounts: numberOfAccounts) else {
|
guard let keys = try rustwelding.deriveExtendedSpendingKeys(seed: seed, accounts: numberOfAccounts, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return keys
|
return keys
|
||||||
|
@ -189,7 +193,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
guard let address = try rustwelding.deriveShieldedAddressFromSeed(seed: seed, accountIndex: accountIndex) else {
|
guard let address = try rustwelding.deriveShieldedAddressFromSeed(seed: seed, accountIndex: accountIndex, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return address
|
return address
|
||||||
|
@ -209,7 +213,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
*/
|
*/
|
||||||
public func deriveShieldedAddress(viewingKey: String) throws -> String {
|
public func deriveShieldedAddress(viewingKey: String) throws -> String {
|
||||||
do {
|
do {
|
||||||
guard let zaddr = try rustwelding.deriveShieldedAddressFromViewingKey(viewingKey) else {
|
guard let zaddr = try rustwelding.deriveShieldedAddressFromViewingKey(viewingKey, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return zaddr
|
return zaddr
|
||||||
|
@ -220,7 +224,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
|
|
||||||
public func deriveTransparentAddress(seed: [UInt8], account: Int = 0, index: Int = 0) throws -> String {
|
public func deriveTransparentAddress(seed: [UInt8], account: Int = 0, index: Int = 0) throws -> String {
|
||||||
do {
|
do {
|
||||||
guard let zaddr = try rustwelding.deriveTransparentAddressFromSeed(seed: seed, account: account, index: index) else {
|
guard let zaddr = try rustwelding.deriveTransparentAddressFromSeed(seed: seed, account: account, index: index, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return zaddr
|
return zaddr
|
||||||
|
@ -234,7 +238,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
throw KeyDerivationErrors.invalidInput
|
throw KeyDerivationErrors.invalidInput
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
return try rustwelding.deriveUnifiedViewingKeyFromSeed(seed, numberOfAccounts: numberOfAccounts)
|
return try rustwelding.deriveUnifiedViewingKeyFromSeed(seed, numberOfAccounts: numberOfAccounts, networkType: networkType)
|
||||||
} catch {
|
} catch {
|
||||||
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
||||||
}
|
}
|
||||||
|
@ -259,7 +263,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
return try rustwelding.derivedTransparentAddressFromPublicKey(pubkey)
|
return try rustwelding.derivedTransparentAddressFromPublicKey(pubkey, networkType: networkType)
|
||||||
} catch {
|
} catch {
|
||||||
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
||||||
}
|
}
|
||||||
|
@ -273,7 +277,7 @@ public class DerivationTool: KeyDeriving {
|
||||||
*/
|
*/
|
||||||
public func deriveTransparentPrivateKey(seed: [UInt8], account: Int = 0, index: Int = 0) throws -> String {
|
public func deriveTransparentPrivateKey(seed: [UInt8], account: Int = 0, index: Int = 0) throws -> String {
|
||||||
do {
|
do {
|
||||||
guard let sk = try rustwelding.deriveTransparentPrivateKeyFromSeed(seed: seed, account: account, index: index) else {
|
guard let sk = try rustwelding.deriveTransparentPrivateKeyFromSeed(seed: seed, account: account, index: index, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return sk
|
return sk
|
||||||
|
@ -288,7 +292,7 @@ extension DerivationTool: KeyValidation {
|
||||||
|
|
||||||
public func isValidExtendedViewingKey(_ extvk: String) throws -> Bool {
|
public func isValidExtendedViewingKey(_ extvk: String) throws -> Bool {
|
||||||
do {
|
do {
|
||||||
return try rustwelding.isValidExtendedFullViewingKey(extvk)
|
return try rustwelding.isValidExtendedFullViewingKey(extvk, networkType: networkType)
|
||||||
} catch {
|
} catch {
|
||||||
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
||||||
}
|
}
|
||||||
|
@ -296,7 +300,7 @@ extension DerivationTool: KeyValidation {
|
||||||
|
|
||||||
public func isValidTransparentAddress(_ tAddress: String) throws -> Bool {
|
public func isValidTransparentAddress(_ tAddress: String) throws -> Bool {
|
||||||
do {
|
do {
|
||||||
return try rustwelding.isValidTransparentAddress(tAddress)
|
return try rustwelding.isValidTransparentAddress(tAddress, networkType: networkType)
|
||||||
} catch {
|
} catch {
|
||||||
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
||||||
}
|
}
|
||||||
|
@ -304,7 +308,7 @@ extension DerivationTool: KeyValidation {
|
||||||
|
|
||||||
public func isValidShieldedAddress(_ zAddress: String) throws -> Bool {
|
public func isValidShieldedAddress(_ zAddress: String) throws -> Bool {
|
||||||
do {
|
do {
|
||||||
return try rustwelding.isValidShieldedAddress(zAddress)
|
return try rustwelding.isValidShieldedAddress(zAddress, networkType: networkType)
|
||||||
} catch {
|
} catch {
|
||||||
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
throw KeyDerivationErrors.derivationError(underlyingError: error)
|
||||||
}
|
}
|
||||||
|
@ -318,7 +322,7 @@ extension DerivationTool: KeyValidation {
|
||||||
*/
|
*/
|
||||||
public func deriveTransparentAddressFromPrivateKey(_ tsk: String) throws -> String {
|
public func deriveTransparentAddressFromPrivateKey(_ tsk: String) throws -> String {
|
||||||
do {
|
do {
|
||||||
guard let tAddr = try rustwelding.deriveTransparentAddressFromSecretKey(tsk) else {
|
guard let tAddr = try rustwelding.deriveTransparentAddressFromSecretKey(tsk, networkType: networkType) else {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
return tAddr
|
return tAddr
|
||||||
|
|
|
@ -24,10 +24,16 @@ class PersistentTransactionManager: OutboundTransactionManager {
|
||||||
var encoder: TransactionEncoder
|
var encoder: TransactionEncoder
|
||||||
var service: LightWalletService
|
var service: LightWalletService
|
||||||
var queue: DispatchQueue
|
var queue: DispatchQueue
|
||||||
init(encoder: TransactionEncoder, service: LightWalletService, repository: PendingTransactionRepository) {
|
var network: NetworkType
|
||||||
|
|
||||||
|
init(encoder: TransactionEncoder,
|
||||||
|
service: LightWalletService,
|
||||||
|
repository: PendingTransactionRepository,
|
||||||
|
networkType: NetworkType) {
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.encoder = encoder
|
self.encoder = encoder
|
||||||
self.service = service
|
self.service = service
|
||||||
|
self.network = networkType
|
||||||
self.queue = DispatchQueue.init(label: "PersistentTransactionManager.serial.queue", qos: .userInitiated)
|
self.queue = DispatchQueue.init(label: "PersistentTransactionManager.serial.queue", qos: .userInitiated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +50,7 @@ class PersistentTransactionManager: OutboundTransactionManager {
|
||||||
queue.async { [weak self] in
|
queue.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
let derivationTool = DerivationTool()
|
let derivationTool = DerivationTool(networkType: self.network)
|
||||||
guard let vk = try? derivationTool.deriveViewingKey(spendingKey: spendingKey),
|
guard let vk = try? derivationTool.deriveViewingKey(spendingKey: spendingKey),
|
||||||
let zAddr = try? derivationTool.deriveShieldedAddress(viewingKey: vk) else {
|
let zAddr = try? derivationTool.deriveShieldedAddress(viewingKey: vk) else {
|
||||||
result(.failure(TransactionManagerError.shieldingEncodingFailed(tx: pendingTransaction, reason: "There was an error Deriving your keys")))
|
result(.failure(TransactionManagerError.shieldingEncodingFailed(tx: pendingTransaction, reason: "There was an error Deriving your keys")))
|
||||||
|
@ -243,7 +249,7 @@ class PersistentTransactionManager: OutboundTransactionManager {
|
||||||
class OutboundTransactionManagerBuilder {
|
class OutboundTransactionManagerBuilder {
|
||||||
|
|
||||||
static func build(initializer: Initializer) throws -> OutboundTransactionManager {
|
static func build(initializer: Initializer) throws -> OutboundTransactionManager {
|
||||||
return PersistentTransactionManager(encoder: TransactionEncoderbuilder.build(initializer: initializer), service: initializer.lightWalletService, repository: try PendingTransactionRepositoryBuilder.build(initializer: initializer))
|
return PersistentTransactionManager(encoder: TransactionEncoderbuilder.build(initializer: initializer), service: initializer.lightWalletService, repository: try PendingTransactionRepositoryBuilder.build(initializer: initializer), networkType: initializer.network.networkType)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,15 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
private var spendParamsURL: URL
|
private var spendParamsURL: URL
|
||||||
private var dataDbURL: URL
|
private var dataDbURL: URL
|
||||||
private var cacheDbURL: URL
|
private var cacheDbURL: URL
|
||||||
|
private var networkType: NetworkType
|
||||||
|
|
||||||
init(rust: ZcashRustBackendWelding.Type,
|
init(rust: ZcashRustBackendWelding.Type,
|
||||||
dataDb: URL,
|
dataDb: URL,
|
||||||
cacheDb: URL,
|
cacheDb: URL,
|
||||||
repository: TransactionRepository,
|
repository: TransactionRepository,
|
||||||
outputParams: URL,
|
outputParams: URL,
|
||||||
spendParams: URL) {
|
spendParams: URL,
|
||||||
|
networkType: NetworkType) {
|
||||||
|
|
||||||
self.rustBackend = rust
|
self.rustBackend = rust
|
||||||
self.dataDbURL = dataDb
|
self.dataDbURL = dataDb
|
||||||
|
@ -30,6 +32,7 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.outputParamsURL = outputParams
|
self.outputParamsURL = outputParams
|
||||||
self.spendParamsURL = spendParams
|
self.spendParamsURL = spendParams
|
||||||
|
self.networkType = networkType
|
||||||
self.queue = DispatchQueue(label: "wallet.transaction.encoder.serial.queue")
|
self.queue = DispatchQueue(label: "wallet.transaction.encoder.serial.queue")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,7 +43,8 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
cacheDb: initializer.cacheDbURL,
|
cacheDb: initializer.cacheDbURL,
|
||||||
repository: initializer.transactionRepository,
|
repository: initializer.transactionRepository,
|
||||||
outputParams: initializer.outputParamsURL,
|
outputParams: initializer.outputParamsURL,
|
||||||
spendParams: initializer.spendParamsURL)
|
spendParams: initializer.spendParamsURL,
|
||||||
|
networkType: initializer.network.networkType)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +90,8 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
value: Int64(zatoshi),
|
value: Int64(zatoshi),
|
||||||
memo: memo,
|
memo: memo,
|
||||||
spendParamsPath: self.spendParamsURL.path,
|
spendParamsPath: self.spendParamsURL.path,
|
||||||
outputParamsPath: self.outputParamsURL.path)
|
outputParamsPath: self.outputParamsURL.path,
|
||||||
|
networkType: networkType)
|
||||||
|
|
||||||
guard txId > 0 else {
|
guard txId > 0 else {
|
||||||
throw rustBackend.lastError() ?? RustWeldingError.genericError(message: "create spend failed")
|
throw rustBackend.lastError() ?? RustWeldingError.genericError(message: "create spend failed")
|
||||||
|
@ -130,7 +135,8 @@ class WalletTransactionEncoder: TransactionEncoder {
|
||||||
extsk: spendingKey,
|
extsk: spendingKey,
|
||||||
memo: memo,
|
memo: memo,
|
||||||
spendParamsPath: self.spendParamsURL.path,
|
spendParamsPath: self.spendParamsURL.path,
|
||||||
outputParamsPath: self.outputParamsURL.path)
|
outputParamsPath: self.outputParamsURL.path,
|
||||||
|
networkType: networkType)
|
||||||
|
|
||||||
guard txId > 0 else {
|
guard txId > 0 else {
|
||||||
throw rustBackend.lastError() ?? RustWeldingError.genericError(message: "create spend failed")
|
throw rustBackend.lastError() ?? RustWeldingError.genericError(message: "create spend failed")
|
||||||
|
|
|
@ -124,9 +124,9 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
public private(set) var progress: Float = 0.0
|
public private(set) var progress: Float = 0.0
|
||||||
public private(set) var blockProcessor: CompactBlockProcessor
|
public private(set) var blockProcessor: CompactBlockProcessor
|
||||||
public private(set) var initializer: Initializer
|
public private(set) var initializer: Initializer
|
||||||
public private(set)var latestScannedHeight: BlockHeight
|
public private(set) var latestScannedHeight: BlockHeight
|
||||||
public private(set) var connectionState: ConnectionState
|
public private(set) var connectionState: ConnectionState
|
||||||
|
public private(set) var network: ZcashNetwork
|
||||||
private var transactionManager: OutboundTransactionManager
|
private var transactionManager: OutboundTransactionManager
|
||||||
private var transactionRepository: TransactionRepository
|
private var transactionRepository: TransactionRepository
|
||||||
private var utxoRepository: UnspentTransactionOutputRepository
|
private var utxoRepository: UnspentTransactionOutputRepository
|
||||||
|
@ -159,7 +159,8 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
self.utxoRepository = utxoRepository
|
self.utxoRepository = utxoRepository
|
||||||
self.blockProcessor = blockProcessor
|
self.blockProcessor = blockProcessor
|
||||||
self.latestScannedHeight = (try? transactionRepository.lastScannedHeight()) ?? initializer.walletBirthday.height
|
self.latestScannedHeight = (try? transactionRepository.lastScannedHeight()) ?? initializer.walletBirthday.height
|
||||||
self.subscribeToProcessorNotifications(self.blockProcessor)
|
self.network = initializer.network
|
||||||
|
self.subscribeToProcessorNotifications(blockProcessor)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
@ -443,13 +444,14 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
public func shieldFunds(spendingKey: String, transparentSecretKey: String, memo: String?, from accountIndex: Int, resultBlock: @escaping (Result<PendingTransactionEntity, Error>) -> Void) {
|
public func shieldFunds(spendingKey: String, transparentSecretKey: String, memo: String?, from accountIndex: Int, resultBlock: @escaping (Result<PendingTransactionEntity, Error>) -> Void) {
|
||||||
|
|
||||||
// let's see if there are funds to shield
|
// let's see if there are funds to shield
|
||||||
let derivationTool = DerivationTool.default
|
let derivationTool = DerivationTool(networkType: self.network.networkType)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let tAddr = try derivationTool.deriveTransparentAddressFromPrivateKey(transparentSecretKey)
|
let tAddr = try derivationTool.deriveTransparentAddressFromPrivateKey(transparentSecretKey)
|
||||||
let tBalance = try utxoRepository.balance(address: tAddr, latestHeight: self.latestDownloadedHeight())
|
let tBalance = try utxoRepository.balance(address: tAddr, latestHeight: self.latestDownloadedHeight())
|
||||||
|
|
||||||
guard tBalance.verified >= ZcashSDK.shieldingThreshold else {
|
// Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
|
||||||
|
guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else {
|
||||||
resultBlock(.failure(ShieldFundsError.insuficientTransparentFunds))
|
resultBlock(.failure(ShieldFundsError.insuficientTransparentFunds))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -562,7 +564,7 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
initializer.lightWalletService.fetchUTXOs(for: address, height: ZcashSDK.SAPLING_ACTIVATION_HEIGHT, result: { [weak self] r in
|
initializer.lightWalletService.fetchUTXOs(for: address, height: network.constants.SAPLING_ACTIVATION_HEIGHT, result: { [weak self] r in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
switch r {
|
switch r {
|
||||||
case .success(let utxos):
|
case .success(let utxos):
|
||||||
|
@ -579,7 +581,7 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func refreshUTXOs(address: String, from height: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT, result: @escaping (Result<RefreshedUTXOs, Error>) -> Void) {
|
public func refreshUTXOs(address: String, from height: BlockHeight, result: @escaping (Result<RefreshedUTXOs, Error>) -> Void) {
|
||||||
|
|
||||||
self.blockProcessor.refreshUTXOs(tAddress: address, startHeight: height, result: result)
|
self.blockProcessor.refreshUTXOs(tAddress: address, startHeight: height, result: result)
|
||||||
}
|
}
|
||||||
|
@ -635,7 +637,7 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
height = rewindHeight
|
height = rewindHeight
|
||||||
|
|
||||||
case .transaction(let tx):
|
case .transaction(let tx):
|
||||||
guard let txHeight = tx.anchor else {
|
guard let txHeight = tx.anchor(network: self.network) else {
|
||||||
throw SynchronizerError.rewindErrorUnknownArchorHeight
|
throw SynchronizerError.rewindErrorUnknownArchorHeight
|
||||||
}
|
}
|
||||||
height = txHeight
|
height = txHeight
|
||||||
|
@ -846,4 +848,3 @@ fileprivate struct NullProgress: BlockProgressReporting {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ typedef struct {
|
||||||
uintptr_t len;
|
uintptr_t len;
|
||||||
} FFIUVKBoxedSlice;
|
} FFIUVKBoxedSlice;
|
||||||
|
|
||||||
int32_t zcashlc_branch_id_for_height(int32_t height);
|
int32_t zcashlc_branch_id_for_height(int32_t height, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the record of the last error message.
|
* Clears the record of the last error message.
|
||||||
|
@ -23,7 +23,8 @@ void zcashlc_clear_last_error(void);
|
||||||
int32_t zcashlc_clear_utxos(const uint8_t *db_data,
|
int32_t zcashlc_clear_utxos(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
const char *taddress,
|
const char *taddress,
|
||||||
int32_t above_height);
|
int32_t above_height,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a transaction paying the specified address from the given account.
|
* Creates a transaction paying the specified address from the given account.
|
||||||
|
@ -45,18 +46,20 @@ int64_t zcashlc_create_to_address(const uint8_t *db_data,
|
||||||
const uint8_t *spend_params,
|
const uint8_t *spend_params,
|
||||||
uintptr_t spend_params_len,
|
uintptr_t spend_params_len,
|
||||||
const uint8_t *output_params,
|
const uint8_t *output_params,
|
||||||
uintptr_t output_params_len);
|
uintptr_t output_params_len,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
int32_t zcashlc_decrypt_and_store_transaction(const uint8_t *db_data,
|
int32_t zcashlc_decrypt_and_store_transaction(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
const uint8_t *tx,
|
const uint8_t *tx,
|
||||||
uintptr_t tx_len);
|
uintptr_t tx_len,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derives a shielded address from the given extended full viewing key.
|
* derives a shielded address from the given extended full viewing key.
|
||||||
* call zcashlc_string_free with the returned pointer when done using it
|
* call zcashlc_string_free with the returned pointer when done using it
|
||||||
*/
|
*/
|
||||||
char *zcashlc_derive_extended_full_viewing_key(const char *extsk);
|
char *zcashlc_derive_extended_full_viewing_key(const char *extsk, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives Extended Full Viewing Keys from the given seed into 'accounts' number of accounts.
|
* Derives Extended Full Viewing Keys from the given seed into 'accounts' number of accounts.
|
||||||
|
@ -68,7 +71,8 @@ char *zcashlc_derive_extended_full_viewing_key(const char *extsk);
|
||||||
char **zcashlc_derive_extended_full_viewing_keys(const uint8_t *seed,
|
char **zcashlc_derive_extended_full_viewing_keys(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t accounts,
|
int32_t accounts,
|
||||||
uintptr_t *capacity_ret);
|
uintptr_t *capacity_ret,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives Extended Spending Keys from the given seed into 'accounts' number of accounts.
|
* Derives Extended Spending Keys from the given seed into 'accounts' number of accounts.
|
||||||
|
@ -80,7 +84,8 @@ char **zcashlc_derive_extended_full_viewing_keys(const uint8_t *seed,
|
||||||
char **zcashlc_derive_extended_spending_keys(const uint8_t *seed,
|
char **zcashlc_derive_extended_spending_keys(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t accounts,
|
int32_t accounts,
|
||||||
uintptr_t *capacity_ret);
|
uintptr_t *capacity_ret,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derives a shielded address from the given seed.
|
* derives a shielded address from the given seed.
|
||||||
|
@ -88,24 +93,25 @@ char **zcashlc_derive_extended_spending_keys(const uint8_t *seed,
|
||||||
*/
|
*/
|
||||||
char *zcashlc_derive_shielded_address_from_seed(const uint8_t *seed,
|
char *zcashlc_derive_shielded_address_from_seed(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t account_index);
|
int32_t account_index,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derives a shielded address from the given viewing key.
|
* derives a shielded address from the given viewing key.
|
||||||
* call zcashlc_string_free with the returned pointer when done using it
|
* call zcashlc_string_free with the returned pointer when done using it
|
||||||
*/
|
*/
|
||||||
char *zcashlc_derive_shielded_address_from_viewing_key(const char *extfvk);
|
char *zcashlc_derive_shielded_address_from_viewing_key(const char *extfvk, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* derives a shielded address from the given viewing key.
|
* derives a shielded address from the given viewing key.
|
||||||
* call zcashlc_string_free with the returned pointer when done using it
|
* call zcashlc_string_free with the returned pointer when done using it
|
||||||
*/
|
*/
|
||||||
char *zcashlc_derive_transparent_address_from_public_key(const char *pubkey);
|
char *zcashlc_derive_transparent_address_from_public_key(const char *pubkey, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives a transparent address from the given secret key enconded as a WIF string
|
* Derives a transparent address from the given secret key enconded as a WIF string
|
||||||
*/
|
*/
|
||||||
char *zcashlc_derive_transparent_address_from_secret_key(const char *tsk);
|
char *zcashlc_derive_transparent_address_from_secret_key(const char *tsk, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derives a transparent address from the given seed
|
* Derives a transparent address from the given seed
|
||||||
|
@ -113,7 +119,8 @@ char *zcashlc_derive_transparent_address_from_secret_key(const char *tsk);
|
||||||
char *zcashlc_derive_transparent_address_from_seed(const uint8_t *seed,
|
char *zcashlc_derive_transparent_address_from_seed(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t account,
|
int32_t account,
|
||||||
int32_t index);
|
int32_t index,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TEST TEST 123 TEST
|
* TEST TEST 123 TEST
|
||||||
|
@ -124,11 +131,13 @@ char *zcashlc_derive_transparent_address_from_seed(const uint8_t *seed,
|
||||||
char *zcashlc_derive_transparent_private_key_from_seed(const uint8_t *seed,
|
char *zcashlc_derive_transparent_private_key_from_seed(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t account,
|
int32_t account,
|
||||||
int32_t index);
|
int32_t index,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
FFIUVKBoxedSlice *zcashlc_derive_unified_viewing_keys_from_seed(const uint8_t *seed,
|
FFIUVKBoxedSlice *zcashlc_derive_unified_viewing_keys_from_seed(const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t accounts);
|
int32_t accounts,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the last error message into the provided allocated buffer.
|
* Copies the last error message into the provided allocated buffer.
|
||||||
|
@ -142,16 +151,23 @@ void zcashlc_free_uvk_array(FFIUVKBoxedSlice *uvks);
|
||||||
*
|
*
|
||||||
* Call `zcashlc_string_free` on the returned pointer when you are finished with it.
|
* Call `zcashlc_string_free` on the returned pointer when you are finished with it.
|
||||||
*/
|
*/
|
||||||
char *zcashlc_get_address(const uint8_t *db_data, uintptr_t db_data_len, int32_t account);
|
char *zcashlc_get_address(const uint8_t *db_data,
|
||||||
|
uintptr_t db_data_len,
|
||||||
|
int32_t account,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the balance for the account, including all unspent notes that we know about.
|
* Returns the balance for the account, including all unspent notes that we know about.
|
||||||
*/
|
*/
|
||||||
int64_t zcashlc_get_balance(const uint8_t *db_data, uintptr_t db_data_len, int32_t account);
|
int64_t zcashlc_get_balance(const uint8_t *db_data,
|
||||||
|
uintptr_t db_data_len,
|
||||||
|
int32_t account,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
int32_t zcashlc_get_nearest_rewind_height(const uint8_t *db_data,
|
int32_t zcashlc_get_nearest_rewind_height(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
int32_t height);
|
int32_t height,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the memo for a received note, if it is known and a valid UTF-8 string.
|
* Returns the memo for a received note, if it is known and a valid UTF-8 string.
|
||||||
|
@ -163,7 +179,8 @@ int32_t zcashlc_get_nearest_rewind_height(const uint8_t *db_data,
|
||||||
*/
|
*/
|
||||||
char *zcashlc_get_received_memo_as_utf8(const uint8_t *db_data,
|
char *zcashlc_get_received_memo_as_utf8(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
int64_t id_note);
|
int64_t id_note,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the memo for a sent note, if it is known and a valid UTF-8 string.
|
* Returns the memo for a sent note, if it is known and a valid UTF-8 string.
|
||||||
|
@ -173,7 +190,10 @@ char *zcashlc_get_received_memo_as_utf8(const uint8_t *db_data,
|
||||||
*
|
*
|
||||||
* Call `zcashlc_string_free` on the returned pointer when you are finished with it.
|
* Call `zcashlc_string_free` on the returned pointer when you are finished with it.
|
||||||
*/
|
*/
|
||||||
char *zcashlc_get_sent_memo_as_utf8(const uint8_t *db_data, uintptr_t db_data_len, int64_t id_note);
|
char *zcashlc_get_sent_memo_as_utf8(const uint8_t *db_data,
|
||||||
|
uintptr_t db_data_len,
|
||||||
|
int64_t id_note,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the verified transparent balance for the address, which ignores utxos that have been
|
* Returns the verified transparent balance for the address, which ignores utxos that have been
|
||||||
|
@ -181,7 +201,8 @@ char *zcashlc_get_sent_memo_as_utf8(const uint8_t *db_data, uintptr_t db_data_le
|
||||||
*/
|
*/
|
||||||
int64_t zcashlc_get_total_transparent_balance(const uint8_t *db_data,
|
int64_t zcashlc_get_total_transparent_balance(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
const char *address);
|
const char *address,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the verified balance for the account, which ignores notes that have been
|
* Returns the verified balance for the account, which ignores notes that have been
|
||||||
|
@ -189,7 +210,8 @@ int64_t zcashlc_get_total_transparent_balance(const uint8_t *db_data,
|
||||||
*/
|
*/
|
||||||
int64_t zcashlc_get_verified_balance(const uint8_t *db_data,
|
int64_t zcashlc_get_verified_balance(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
int32_t account);
|
int32_t account,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the verified transparent balance for the address, which ignores utxos that have been
|
* Returns the verified transparent balance for the address, which ignores utxos that have been
|
||||||
|
@ -197,7 +219,8 @@ int64_t zcashlc_get_verified_balance(const uint8_t *db_data,
|
||||||
*/
|
*/
|
||||||
int64_t zcashlc_get_verified_transparent_balance(const uint8_t *db_data,
|
int64_t zcashlc_get_verified_transparent_balance(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
const char *address);
|
const char *address,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the data database with the given number of accounts using the given seed.
|
* Initialises the data database with the given number of accounts using the given seed.
|
||||||
|
@ -212,7 +235,8 @@ char **zcashlc_init_accounts_table(const uint8_t *db_data,
|
||||||
const uint8_t *seed,
|
const uint8_t *seed,
|
||||||
uintptr_t seed_len,
|
uintptr_t seed_len,
|
||||||
int32_t accounts,
|
int32_t accounts,
|
||||||
uintptr_t *capacity_ret);
|
uintptr_t *capacity_ret,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the data database with the given extended full viewing keys
|
* Initialises the data database with the given extended full viewing keys
|
||||||
|
@ -220,7 +244,8 @@ char **zcashlc_init_accounts_table(const uint8_t *db_data,
|
||||||
*/
|
*/
|
||||||
bool zcashlc_init_accounts_table_with_keys(const uint8_t *db_data,
|
bool zcashlc_init_accounts_table_with_keys(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
FFIUVKBoxedSlice *uvks);
|
FFIUVKBoxedSlice *uvks,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the data database with the given block.
|
* Initialises the data database with the given block.
|
||||||
|
@ -233,30 +258,33 @@ int32_t zcashlc_init_blocks_table(const uint8_t *db_data,
|
||||||
int32_t height,
|
int32_t height,
|
||||||
const char *hash_hex,
|
const char *hash_hex,
|
||||||
uint32_t time,
|
uint32_t time,
|
||||||
const char *sapling_tree_hex);
|
const char *sapling_tree_hex,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the internal structure of the data database.
|
* Sets up the internal structure of the data database.
|
||||||
*/
|
*/
|
||||||
int32_t zcashlc_init_data_database(const uint8_t *db_data, uintptr_t db_data_len);
|
int32_t zcashlc_init_data_database(const uint8_t *db_data,
|
||||||
|
uintptr_t db_data_len,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when the address is valid and shielded.
|
* Returns true when the address is valid and shielded.
|
||||||
* Returns false in any other case
|
* Returns false in any other case
|
||||||
* Errors when the provided address belongs to another network
|
* Errors when the provided address belongs to another network
|
||||||
*/
|
*/
|
||||||
bool zcashlc_is_valid_shielded_address(const char *address);
|
bool zcashlc_is_valid_shielded_address(const char *address, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when the address is valid and transparent.
|
* Returns true when the address is valid and transparent.
|
||||||
* Returns false in any other case
|
* Returns false in any other case
|
||||||
*/
|
*/
|
||||||
bool zcashlc_is_valid_transparent_address(const char *address);
|
bool zcashlc_is_valid_transparent_address(const char *address, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns whether the given viewing key is valid or not
|
* returns whether the given viewing key is valid or not
|
||||||
*/
|
*/
|
||||||
bool zcashlc_is_valid_viewing_key(const char *key);
|
bool zcashlc_is_valid_viewing_key(const char *key, uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the length of the last error message to be logged.
|
* Returns the length of the last error message to be logged.
|
||||||
|
@ -272,7 +300,8 @@ bool zcashlc_put_utxo(const uint8_t *db_data,
|
||||||
const uint8_t *script_bytes,
|
const uint8_t *script_bytes,
|
||||||
uintptr_t script_bytes_len,
|
uintptr_t script_bytes_len,
|
||||||
int64_t value,
|
int64_t value,
|
||||||
int32_t height);
|
int32_t height,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rewinds the data database to the given height.
|
* Rewinds the data database to the given height.
|
||||||
|
@ -280,7 +309,10 @@ bool zcashlc_put_utxo(const uint8_t *db_data,
|
||||||
* If the requested height is greater than or equal to the height of the last scanned
|
* If the requested height is greater than or equal to the height of the last scanned
|
||||||
* block, this function does nothing.
|
* block, this function does nothing.
|
||||||
*/
|
*/
|
||||||
bool zcashlc_rewind_to_height(const uint8_t *db_data, uintptr_t db_data_len, int32_t height);
|
bool zcashlc_rewind_to_height(const uint8_t *db_data,
|
||||||
|
uintptr_t db_data_len,
|
||||||
|
int32_t height,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans new blocks added to the cache for any transactions received by the tracked
|
* Scans new blocks added to the cache for any transactions received by the tracked
|
||||||
|
@ -302,7 +334,8 @@ int32_t zcashlc_scan_blocks(const uint8_t *db_cache,
|
||||||
uintptr_t db_cache_len,
|
uintptr_t db_cache_len,
|
||||||
const uint8_t *db_data,
|
const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
uint32_t scan_limit);
|
uint32_t scan_limit,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
int64_t zcashlc_shield_funds(const uint8_t *db_data,
|
int64_t zcashlc_shield_funds(const uint8_t *db_data,
|
||||||
uintptr_t db_data_len,
|
uintptr_t db_data_len,
|
||||||
|
@ -313,7 +346,8 @@ int64_t zcashlc_shield_funds(const uint8_t *db_data,
|
||||||
const uint8_t *spend_params,
|
const uint8_t *spend_params,
|
||||||
uintptr_t spend_params_len,
|
uintptr_t spend_params_len,
|
||||||
const uint8_t *output_params,
|
const uint8_t *output_params,
|
||||||
uintptr_t output_params_len);
|
uintptr_t output_params_len,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees strings returned by other zcashlc functions.
|
* Frees strings returned by other zcashlc functions.
|
||||||
|
@ -341,7 +375,8 @@ void zcashlc_string_free(char *s);
|
||||||
int32_t zcashlc_validate_combined_chain(const uint8_t *db_cache,
|
int32_t zcashlc_validate_combined_chain(const uint8_t *db_cache,
|
||||||
uintptr_t db_cache_len,
|
uintptr_t db_cache_len,
|
||||||
const uint8_t *db_data,
|
const uint8_t *db_data,
|
||||||
uintptr_t db_data_len);
|
uintptr_t db_data_len,
|
||||||
|
uint32_t network_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees vectors of strings returned by other zcashlc functions.
|
* Frees vectors of strings returned by other zcashlc functions.
|
||||||
|
|
|
@ -24,12 +24,15 @@ class AdvancedReOrgTests: XCTestCase {
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
|
let network = DarksideWalletDNetwork()
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,14 @@ class BalanceTests: XCTestCase {
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
var syncedExpectation = XCTestExpectation(description: "synced")
|
var syncedExpectation = XCTestExpectation(description: "synced")
|
||||||
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
||||||
|
let network: ZcashNetwork = DarksideWalletDNetwork()
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
|
|
||||||
|
@ -58,10 +60,10 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
let maxBalance = verifiedBalance - Int64(ZcashSDK.defaultFee())
|
let maxBalance = verifiedBalance - Int64(network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
|
|
||||||
// 3 create a transaction for the max amount possible
|
// 3 create a transaction for the max amount possible
|
||||||
// 4 send the transaction
|
// 4 send the transaction
|
||||||
|
@ -196,10 +198,10 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
let maxBalanceMinusOne = verifiedBalance - Int64(ZcashSDK.defaultFee()) - 1
|
let maxBalanceMinusOne = verifiedBalance - Int64(network.constants.defaultFee(for: defaultLatestHeight)) - 1
|
||||||
|
|
||||||
// 3 create a transaction for the max amount possible
|
// 3 create a transaction for the max amount possible
|
||||||
// 4 send the transaction
|
// 4 send the transaction
|
||||||
|
@ -333,10 +335,10 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
let maxBalanceMinusOne = 100000 - ZcashSDK.defaultFee()
|
let maxBalanceMinusOne = 100000 - network.constants.defaultFee(for: defaultLatestHeight)
|
||||||
|
|
||||||
// 3 create a transaction for the max amount possible
|
// 3 create a transaction for the max amount possible
|
||||||
// 4 send the transaction
|
// 4 send the transaction
|
||||||
|
@ -483,7 +485,7 @@ class BalanceTests: XCTestCase {
|
||||||
/*
|
/*
|
||||||
there's more zatoshi to send than network fee
|
there's more zatoshi to send than network fee
|
||||||
*/
|
*/
|
||||||
XCTAssertTrue(presendVerifiedBalance >= (Int64(ZcashSDK.MINERS_FEE_ZATOSHI) + sendAmount))
|
XCTAssertTrue(presendVerifiedBalance >= (Int64(network.constants.defaultFee(for: defaultLatestHeight)) + sendAmount))
|
||||||
|
|
||||||
var pendingTx: PendingTransactionEntity?
|
var pendingTx: PendingTransactionEntity?
|
||||||
coordinator.synchronizer.sendToAddress(spendingKey: spendingKey,
|
coordinator.synchronizer.sendToAddress(spendingKey: spendingKey,
|
||||||
|
@ -540,8 +542,8 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
wait(for: [mineExpectation], timeout: 5)
|
wait(for: [mineExpectation], timeout: 5)
|
||||||
|
|
||||||
XCTAssertEqual(presendVerifiedBalance - self.sendAmount - ZcashSDK.defaultFee(),coordinator.synchronizer.initializer.getBalance())
|
XCTAssertEqual(presendVerifiedBalance - self.sendAmount - network.constants.defaultFee(for: defaultLatestHeight),coordinator.synchronizer.initializer.getBalance())
|
||||||
XCTAssertEqual(presendVerifiedBalance - self.sendAmount - ZcashSDK.defaultFee(),coordinator.synchronizer.initializer.getVerifiedBalance())
|
XCTAssertEqual(presendVerifiedBalance - self.sendAmount - network.constants.defaultFee(for: defaultLatestHeight),coordinator.synchronizer.initializer.getVerifiedBalance())
|
||||||
|
|
||||||
guard let transaction = pendingTx else {
|
guard let transaction = pendingTx else {
|
||||||
XCTFail("pending transaction nil")
|
XCTFail("pending transaction nil")
|
||||||
|
@ -629,7 +631,7 @@ class BalanceTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
let presendBalance = coordinator.synchronizer.initializer.getBalance()
|
let presendBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
XCTAssertTrue(presendBalance >= (Int64(ZcashSDK.defaultFee()) + sendAmount)) // there's more zatoshi to send than network fee
|
XCTAssertTrue(presendBalance >= (Int64(network.constants.defaultFee(for: defaultLatestHeight)) + sendAmount)) // there's more zatoshi to send than network fee
|
||||||
|
|
||||||
var pendingTx: PendingTransactionEntity?
|
var pendingTx: PendingTransactionEntity?
|
||||||
|
|
||||||
|
@ -667,7 +669,7 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
XCTAssertEqual(Int64(transaction.value), self.sendAmount)
|
XCTAssertEqual(Int64(transaction.value), self.sendAmount)
|
||||||
|
|
||||||
XCTAssertEqual(self.coordinator.synchronizer.initializer.getBalance(), presendBalance - Int64(self.sendAmount) - ZcashSDK.defaultFee())
|
XCTAssertEqual(self.coordinator.synchronizer.initializer.getBalance(), presendBalance - Int64(self.sendAmount) - network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
|
|
||||||
XCTAssertNil(transaction.errorCode)
|
XCTAssertNil(transaction.errorCode)
|
||||||
|
|
||||||
|
@ -697,7 +699,7 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
wait(for: [mineExpectation], timeout: 5)
|
wait(for: [mineExpectation], timeout: 5)
|
||||||
|
|
||||||
XCTAssertEqual(presendBalance - self.sendAmount - Int64(ZcashSDK.defaultFee()),coordinator.synchronizer.initializer.getBalance())
|
XCTAssertEqual(presendBalance - self.sendAmount - Int64(network.constants.defaultFee(for: defaultLatestHeight)),coordinator.synchronizer.initializer.getBalance())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -869,7 +871,7 @@ class BalanceTests: XCTestCase {
|
||||||
/*
|
/*
|
||||||
There’s a change note of value (previous note value - sent amount)
|
There’s a change note of value (previous note value - sent amount)
|
||||||
*/
|
*/
|
||||||
XCTAssertEqual(previousVerifiedBalance - self.sendAmount - ZcashSDK.defaultFee(), Int64(receivedNote.value))
|
XCTAssertEqual(previousVerifiedBalance - self.sendAmount - self.network.constants.defaultFee(for: self.defaultLatestHeight), Int64(receivedNote.value))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1024,7 +1026,7 @@ class BalanceTests: XCTestCase {
|
||||||
func totalBalanceValidation(totalBalance: Int64,
|
func totalBalanceValidation(totalBalance: Int64,
|
||||||
previousTotalbalance: Int64,
|
previousTotalbalance: Int64,
|
||||||
sentAmount: Int64) {
|
sentAmount: Int64) {
|
||||||
XCTAssertEqual(totalBalance, previousTotalbalance - sentAmount - Int64(ZcashSDK.MINERS_FEE_ZATOSHI))
|
XCTAssertEqual(totalBalance, previousTotalbalance - sentAmount - Int64(network.constants.defaultFee(for: defaultLatestHeight)))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,18 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBranchIdFailure() throws {
|
func testBranchIdFailure() throws {
|
||||||
let service = MockLightWalletService(latestBlockHeight: 1210000)
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: 1210000, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = 130000
|
info.blockHeight = 130000
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "main"
|
info.chainName = "main"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db33f"
|
info.consensusBranchID = "d34db33f"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
@ -63,17 +64,18 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBranchNetworkMismatchFailure() throws {
|
func testBranchNetworkMismatchFailure() throws {
|
||||||
let service = MockLightWalletService(latestBlockHeight: 1210000)
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: 1210000, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = 130000
|
info.blockHeight = 130000
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "test"
|
info.chainName = "test"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db4d"
|
info.consensusBranchID = "d34db4d"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
@ -103,17 +105,18 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
|
|
||||||
|
|
||||||
func testBranchNetworkTypeWrongFailure() throws {
|
func testBranchNetworkTypeWrongFailure() throws {
|
||||||
let service = MockLightWalletService(latestBlockHeight: 1210000)
|
let network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: 1210000, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = 130000
|
info.blockHeight = 130000
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "another"
|
info.chainName = "another"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db4d"
|
info.consensusBranchID = "d34db4d"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
@ -142,10 +145,11 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSaplingActivationHeightMismatch() throws {
|
func testSaplingActivationHeightMismatch() throws {
|
||||||
let service = MockLightWalletService(latestBlockHeight: 1210000)
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: 1210000, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = 130000
|
info.blockHeight = 130000
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
|
@ -167,7 +171,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
operation.errorHandler = { error in
|
operation.errorHandler = { error in
|
||||||
expectation.fulfill()
|
expectation.fulfill()
|
||||||
switch error {
|
switch error {
|
||||||
case CompactBlockProcessorError.saplingActivationMismatch(expected: ZcashSDK.SAPLING_ACTIVATION_HEIGHT, found: BlockHeight(info.saplingActivationHeight)):
|
case CompactBlockProcessorError.saplingActivationMismatch(expected: network.constants.SAPLING_ACTIVATION_HEIGHT, found: BlockHeight(info.saplingActivationHeight)):
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
XCTFail("Expected CompactBlockProcessorError.saplingActivationMismatch but found \(error)")
|
XCTFail("Expected CompactBlockProcessorError.saplingActivationMismatch but found \(error)")
|
||||||
|
@ -181,20 +185,22 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResultIsWait() throws {
|
func testResultIsWait() throws {
|
||||||
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
|
|
||||||
let expectedLatestHeight = BlockHeight(1210000)
|
let expectedLatestHeight = BlockHeight(1210000)
|
||||||
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight)
|
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let expectedStoreLatestHeight = BlockHeight(1220000)
|
let expectedStoreLatestHeight = BlockHeight(1220000)
|
||||||
let expectedResult = FigureNextBatchOperation.NextState.wait(latestHeight: expectedLatestHeight, latestDownloadHeight: expectedLatestHeight)
|
let expectedResult = FigureNextBatchOperation.NextState.wait(latestHeight: expectedLatestHeight, latestDownloadHeight: expectedLatestHeight)
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: 1210000, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = UInt64(expectedLatestHeight)
|
info.blockHeight = UInt64(expectedLatestHeight)
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "main"
|
info.chainName = "main"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db4d"
|
info.consensusBranchID = "d34db4d"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
@ -207,7 +213,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
startedExpectation.fulfill()
|
startedExpectation.fulfill()
|
||||||
}
|
}
|
||||||
operation.errorHandler = { error in
|
operation.errorHandler = { error in
|
||||||
XCTFail("this shouldn't happen")
|
XCTFail("this shouldn't happen: \(error)")
|
||||||
}
|
}
|
||||||
operation.completionHandler = { (finished, cancelled) in
|
operation.completionHandler = { (finished, cancelled) in
|
||||||
completedExpectation.fulfill()
|
completedExpectation.fulfill()
|
||||||
|
@ -236,21 +242,22 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResultProcessNew() throws {
|
func testResultProcessNew() throws {
|
||||||
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
let expectedLatestHeight = BlockHeight(1230000)
|
let expectedLatestHeight = BlockHeight(1230000)
|
||||||
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight)
|
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let expectedStoreLatestHeight = BlockHeight(1220000)
|
let expectedStoreLatestHeight = BlockHeight(1220000)
|
||||||
let walletBirthday = BlockHeight(1210000)
|
let walletBirthday = BlockHeight(1210000)
|
||||||
let expectedResult = FigureNextBatchOperation.NextState.processNewBlocks(range: CompactBlockProcessor.nextBatchBlockRange(latestHeight: expectedLatestHeight, latestDownloadedHeight: expectedStoreLatestHeight, walletBirthday: walletBirthday))
|
let expectedResult = FigureNextBatchOperation.NextState.processNewBlocks(range: CompactBlockProcessor.nextBatchBlockRange(latestHeight: expectedLatestHeight, latestDownloadedHeight: expectedStoreLatestHeight, walletBirthday: walletBirthday))
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: walletBirthday, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: walletBirthday, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = UInt64(expectedLatestHeight)
|
info.blockHeight = UInt64(expectedLatestHeight)
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "main"
|
info.chainName = "main"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db4d"
|
info.consensusBranchID = "d34db4d"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
@ -292,21 +299,22 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResultProcessorFinished() throws {
|
func testResultProcessorFinished() throws {
|
||||||
|
let network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
let expectedLatestHeight = BlockHeight(1230000)
|
let expectedLatestHeight = BlockHeight(1230000)
|
||||||
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight)
|
let service = MockLightWalletService(latestBlockHeight: expectedLatestHeight, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default))
|
||||||
let expectedStoreLatestHeight = BlockHeight(1230000)
|
let expectedStoreLatestHeight = BlockHeight(1230000)
|
||||||
let walletBirthday = BlockHeight(1210000)
|
let walletBirthday = BlockHeight(1210000)
|
||||||
let expectedResult = FigureNextBatchOperation.NextState.finishProcessing(height: expectedStoreLatestHeight)
|
let expectedResult = FigureNextBatchOperation.NextState.finishProcessing(height: expectedStoreLatestHeight)
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
let downloader = CompactBlockDownloader(service: service, storage: repository)
|
||||||
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: walletBirthday, saplingActivation: ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
let config = CompactBlockProcessor.Configuration(cacheDb: try! __cacheDbURL(), dataDb: try! __dataDbURL(), downloadBatchSize: 100, retries: 5, maxBackoffInterval: 10, rewindDistance: 100, walletBirthday: walletBirthday, saplingActivation: network.constants.SAPLING_ACTIVATION_HEIGHT, network: network)
|
||||||
var info = LightdInfo()
|
var info = LightdInfo()
|
||||||
info.blockHeight = UInt64(expectedLatestHeight)
|
info.blockHeight = UInt64(expectedLatestHeight)
|
||||||
info.branch = "d34db33f"
|
info.branch = "d34db33f"
|
||||||
info.chainName = "main"
|
info.chainName = "main"
|
||||||
info.buildUser = "test user"
|
info.buildUser = "test user"
|
||||||
info.consensusBranchID = "d34db4d"
|
info.consensusBranchID = "d34db4d"
|
||||||
info.saplingActivationHeight = UInt64(ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockRust = MockRustBackend.self
|
let mockRust = MockRustBackend.self
|
||||||
|
|
|
@ -14,10 +14,18 @@ class BlockDownloaderTests: XCTestCase {
|
||||||
var service: LightWalletService!
|
var service: LightWalletService!
|
||||||
var storage: CompactBlockRepository!
|
var storage: CompactBlockRepository!
|
||||||
var cacheDB = try! __cacheDbURL()
|
var cacheDB = try! __cacheDbURL()
|
||||||
override func setUp() {
|
var network = DarksideWalletDNetwork()
|
||||||
|
var darksideWalletService: DarksideWalletService!
|
||||||
|
let branchID = "2bb40e60"
|
||||||
|
let chainName = "main"
|
||||||
|
override func setUpWithError() throws {
|
||||||
service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
||||||
storage = try! TestDbBuilder.diskCompactBlockStorage(at: cacheDB)
|
storage = try! TestDbBuilder.diskCompactBlockStorage(at: cacheDB)
|
||||||
downloader = CompactBlockDownloader(service: service, storage: storage)
|
downloader = CompactBlockDownloader(service: service, storage: storage)
|
||||||
|
darksideWalletService = DarksideWalletService(service: service as! LightWalletGRPCService)
|
||||||
|
|
||||||
|
try FakeChainBuilder.buildChain(darksideWallet: darksideWalletService, branchID: branchID, chainName: chainName)
|
||||||
|
try darksideWalletService.applyStaged(nextLatestHeight: 663250)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
|
@ -32,8 +40,8 @@ class BlockDownloaderTests: XCTestCase {
|
||||||
|
|
||||||
let expect = XCTestExpectation(description: self.description)
|
let expect = XCTestExpectation(description: self.description)
|
||||||
expect.expectedFulfillmentCount = 3
|
expect.expectedFulfillmentCount = 3
|
||||||
let lowerRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let lowerRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let upperRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 99
|
let upperRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT + 99
|
||||||
|
|
||||||
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
||||||
downloader.downloadBlockRange(range) { (error) in
|
downloader.downloadBlockRange(range) { (error) in
|
||||||
|
@ -58,8 +66,8 @@ class BlockDownloaderTests: XCTestCase {
|
||||||
|
|
||||||
func testSmallDownload() {
|
func testSmallDownload() {
|
||||||
|
|
||||||
let lowerRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let lowerRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let upperRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 99
|
let upperRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT + 99
|
||||||
|
|
||||||
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
||||||
var latest: BlockHeight = 0
|
var latest: BlockHeight = 0
|
||||||
|
@ -86,12 +94,12 @@ class BlockDownloaderTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFailure() {
|
func testFailure() {
|
||||||
let awfulDownloader = CompactBlockDownloader(service: AwfulLightWalletService(latestBlockHeight: ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 1000), storage: ZcashConsoleFakeStorage())
|
let awfulDownloader = CompactBlockDownloader(service: AwfulLightWalletService(latestBlockHeight: self.network.constants.SAPLING_ACTIVATION_HEIGHT + 1000, service: darksideWalletService), storage: ZcashConsoleFakeStorage())
|
||||||
|
|
||||||
let expect = XCTestExpectation(description: self.description)
|
let expect = XCTestExpectation(description: self.description)
|
||||||
expect.expectedFulfillmentCount = 1
|
expect.expectedFulfillmentCount = 1
|
||||||
let lowerRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let lowerRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let upperRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 99
|
let upperRange: BlockHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT + 99
|
||||||
|
|
||||||
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ class BlockScanOperationTests: XCTestCase {
|
||||||
extpub: "02075a7f5f7507d64022dad5954849f216b0f1b09b2d588be663d8e7faeb5aaf61")
|
extpub: "02075a7f5f7507d64022dad5954849f216b0f1b09b2d588be663d8e7faeb5aaf61")
|
||||||
|
|
||||||
|
|
||||||
var walletBirthDay = WalletBirthday.birthday(with: 1386000)
|
var walletBirthDay = WalletBirthday.birthday(with: 1386000, network: ZcashNetworkBuilder.network(for: .testnet))
|
||||||
|
|
||||||
|
|
||||||
|
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
var blockRepository: BlockRepository!
|
var blockRepository: BlockRepository!
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
@ -47,17 +47,17 @@ class BlockScanOperationTests: XCTestCase {
|
||||||
|
|
||||||
func testSingleDownloadAndScanOperation() {
|
func testSingleDownloadAndScanOperation() {
|
||||||
logger = SampleLogger(logLevel: .debug)
|
logger = SampleLogger(logLevel: .debug)
|
||||||
XCTAssertNoThrow(try rustWelding.initDataDb(dbData: dataDbURL))
|
XCTAssertNoThrow(try rustWelding.initDataDb(dbData: dataDbURL, networkType: network.networkType))
|
||||||
let downloadStartedExpect = XCTestExpectation(description: self.description + "download started")
|
let downloadStartedExpect = XCTestExpectation(description: self.description + "download started")
|
||||||
let downloadExpect = XCTestExpectation(description: self.description + "download")
|
let downloadExpect = XCTestExpectation(description: self.description + "download")
|
||||||
let scanStartedExpect = XCTestExpectation(description: self.description + "scan started")
|
let scanStartedExpect = XCTestExpectation(description: self.description + "scan started")
|
||||||
let scanExpect = XCTestExpectation(description: self.description + "scan")
|
let scanExpect = XCTestExpectation(description: self.description + "scan")
|
||||||
let latestScannedBlockExpect = XCTestExpectation(description: self.description + "latestScannedHeight")
|
let latestScannedBlockExpect = XCTestExpectation(description: self.description + "latestScannedHeight")
|
||||||
let service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
let service = LightWalletGRPCService(endpoint: LightWalletEndpoint(address: "lightwalletd.testnet.electriccoin.co", port: 9067))
|
||||||
let blockCount = 100
|
let blockCount = 100
|
||||||
let range = ZcashSDK.SAPLING_ACTIVATION_HEIGHT ... ZcashSDK.SAPLING_ACTIVATION_HEIGHT + blockCount
|
let range = network.constants.SAPLING_ACTIVATION_HEIGHT ... network.constants.SAPLING_ACTIVATION_HEIGHT + blockCount
|
||||||
let downloadOperation = CompactBlockDownloadOperation(downloader: CompactBlockDownloader.sqlDownloader(service: service, at: cacheDbURL)!, range: range)
|
let downloadOperation = CompactBlockDownloadOperation(downloader: CompactBlockDownloader.sqlDownloader(service: service, at: cacheDbURL)!, range: range)
|
||||||
let scanOperation = CompactBlockScanningOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL)
|
let scanOperation = CompactBlockScanningOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL, networkType: network.networkType)
|
||||||
|
|
||||||
downloadOperation.startedHandler = {
|
downloadOperation.startedHandler = {
|
||||||
downloadStartedExpect.fulfill()
|
downloadStartedExpect.fulfill()
|
||||||
|
@ -119,15 +119,15 @@ class BlockScanOperationTests: XCTestCase {
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(observeBenchmark(_:)), name: SDKMetrics.notificationName, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(observeBenchmark(_:)), name: SDKMetrics.notificationName, object: nil)
|
||||||
|
|
||||||
try self.rustWelding.initDataDb(dbData: dataDbURL)
|
try self.rustWelding.initDataDb(dbData: dataDbURL, networkType: network.networkType)
|
||||||
guard try self.rustWelding.initAccountsTable(dbData: self.dataDbURL, uvks: [uvk]) else {
|
guard try self.rustWelding.initAccountsTable(dbData: self.dataDbURL, uvks: [uvk], networkType: network.networkType) else {
|
||||||
XCTFail("failed to init account table")
|
XCTFail("failed to init account table")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.rustWelding.initBlocksTable(dbData: dataDbURL, height: Int32(walletBirthDay.height), hash: walletBirthDay.hash, time: walletBirthDay.time, saplingTree: walletBirthDay.tree)
|
try self.rustWelding.initBlocksTable(dbData: dataDbURL, height: Int32(walletBirthDay.height), hash: walletBirthDay.hash, time: walletBirthDay.time, saplingTree: walletBirthDay.tree, networkType: network.networkType)
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: Constants.address, port: 9067, secure: true, singleCallTimeout: 100000, streamingCallTimeout: 1000000000)
|
let service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.eccTestnet)
|
||||||
let storage = CompactBlockStorage(url: cacheDbURL, readonly: false)
|
let storage = CompactBlockStorage(url: cacheDbURL, readonly: false)
|
||||||
try storage.createTable()
|
try storage.createTable()
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ class BlockScanOperationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let validationOperation = CompactBlockValidationOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL)
|
let validationOperation = CompactBlockValidationOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL, networkType: network.networkType)
|
||||||
validationOperation.errorHandler = { error in
|
validationOperation.errorHandler = { error in
|
||||||
self.operationQueue.cancelAllOperations()
|
self.operationQueue.cancelAllOperations()
|
||||||
XCTFail("failed with error \(error)")
|
XCTFail("failed with error \(error)")
|
||||||
|
@ -174,7 +174,7 @@ class BlockScanOperationTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
let transactionRepository = TransactionRepositoryBuilder.build(dataDbURL: dataDbURL)
|
let transactionRepository = TransactionRepositoryBuilder.build(dataDbURL: dataDbURL)
|
||||||
let scanningOperation = CompactBlockBatchScanningOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL, transactionRepository: transactionRepository, range: CompactBlockRange(uncheckedBounds: (walletBirthDay.height, walletBirthDay.height + 10000)), batchSize: 1000, progressDelegate: self)
|
let scanningOperation = CompactBlockBatchScanningOperation(rustWelding: rustWelding, cacheDb: cacheDbURL, dataDb: dataDbURL, transactionRepository: transactionRepository, range: CompactBlockRange(uncheckedBounds: (walletBirthDay.height, walletBirthDay.height + 10000)), batchSize: 1000, networkType: network.networkType, progressDelegate: self)
|
||||||
|
|
||||||
scanningOperation.completionHandler = { (finished,cancelled) in
|
scanningOperation.completionHandler = { (finished,cancelled) in
|
||||||
XCTAssert(finished)
|
XCTAssert(finished)
|
||||||
|
|
|
@ -23,14 +23,14 @@ class BlockStreamingTest: XCTestCase {
|
||||||
try? FileManager.default.removeItem(at: __dataDbURL())
|
try? FileManager.default.removeItem(at: __dataDbURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testExample() throws {
|
func testStreamOperation() throws {
|
||||||
let expectation = XCTestExpectation(description: "blockstream expectation")
|
let expectation = XCTestExpectation(description: "blockstream expectation")
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
let service = LightWalletGRPCService(host: LightWalletEndpointBuilder.eccTestnet.host,
|
||||||
port: 9067,
|
port: 9067,
|
||||||
secure: true,
|
secure: true,
|
||||||
singleCallTimeout: Int64.max,
|
singleCallTimeout: 1000,
|
||||||
streamingCallTimeout: 1000)
|
streamingCallTimeout: 100000)
|
||||||
|
|
||||||
|
|
||||||
let latestHeight = try service.latestBlockHeight()
|
let latestHeight = try service.latestBlockHeight()
|
||||||
|
@ -55,43 +55,10 @@ class BlockStreamingTest: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func testStreamOperation() throws {
|
|
||||||
let expectation = XCTestExpectation(description: "blockstream expectation")
|
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
|
||||||
port: 9067,
|
|
||||||
secure: true,
|
|
||||||
singleCallTimeout: 1000,
|
|
||||||
streamingCallTimeout: 1000)
|
|
||||||
let storage = try TestDbBuilder.inMemoryCompactBlockStorage()
|
|
||||||
|
|
||||||
let startHeight = try service.latestBlockHeight() - 100_000
|
|
||||||
let operation = CompactBlockStreamDownloadOperation(service: service,
|
|
||||||
storage: storage,
|
|
||||||
startHeight: startHeight,
|
|
||||||
progressDelegate: self)
|
|
||||||
|
|
||||||
operation.completionHandler = { (finished, cancelled) in
|
|
||||||
if cancelled {
|
|
||||||
XCTFail("operation cancelled")
|
|
||||||
}
|
|
||||||
expectation.fulfill()
|
|
||||||
}
|
|
||||||
|
|
||||||
operation.errorHandler = { error in
|
|
||||||
XCTFail("failed with error: \(error)")
|
|
||||||
expectation.fulfill()
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.addOperation(operation)
|
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testStreamOperationCancellation() throws {
|
func testStreamOperationCancellation() throws {
|
||||||
let expectation = XCTestExpectation(description: "blockstream expectation")
|
let expectation = XCTestExpectation(description: "blockstream expectation")
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
let service = LightWalletGRPCService(host: LightWalletEndpointBuilder.eccTestnet.host,
|
||||||
port: 9067,
|
port: 9067,
|
||||||
secure: true,
|
secure: true,
|
||||||
singleCallTimeout: 10000,
|
singleCallTimeout: 10000,
|
||||||
|
@ -124,7 +91,7 @@ class BlockStreamingTest: XCTestCase {
|
||||||
func testStreamOperationTimeout() throws {
|
func testStreamOperationTimeout() throws {
|
||||||
let expectation = XCTestExpectation(description: "blockstream expectation")
|
let expectation = XCTestExpectation(description: "blockstream expectation")
|
||||||
let errorExpectation = XCTestExpectation(description: "blockstream error expectation")
|
let errorExpectation = XCTestExpectation(description: "blockstream error expectation")
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
let service = LightWalletGRPCService(host: LightWalletEndpointBuilder.eccTestnet.host,
|
||||||
port: 9067,
|
port: 9067,
|
||||||
secure: true,
|
secure: true,
|
||||||
singleCallTimeout: 1000,
|
singleCallTimeout: 1000,
|
||||||
|
@ -165,25 +132,18 @@ class BlockStreamingTest: XCTestCase {
|
||||||
let elapsed = now.distance(to: date)
|
let elapsed = now.distance(to: date)
|
||||||
print("took \(elapsed) seconds")
|
print("took \(elapsed) seconds")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPerformanceExample() throws {
|
|
||||||
// This is an example of a performance test case.
|
|
||||||
self.measure {
|
|
||||||
// Put the code you want to measure the time of here.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBatchOperation() throws {
|
func testBatchOperation() throws {
|
||||||
let expectation = XCTestExpectation(description: "blockbatch expectation")
|
let expectation = XCTestExpectation(description: "blockbatch expectation")
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
let service = LightWalletGRPCService(host: LightWalletEndpointBuilder.eccTestnet.host,
|
||||||
port: 9067,
|
port: 9067,
|
||||||
secure: true,
|
secure: true,
|
||||||
singleCallTimeout: 300000,
|
singleCallTimeout: 300000,
|
||||||
streamingCallTimeout: 10000)
|
streamingCallTimeout: 10000)
|
||||||
let storage = try TestDbBuilder.diskCompactBlockStorage(at: __dataDbURL() )
|
let storage = try TestDbBuilder.diskCompactBlockStorage(at: __dataDbURL() )
|
||||||
let targetHeight = try service.latestBlockHeight()
|
let targetHeight = try service.latestBlockHeight()
|
||||||
let startHeight = targetHeight - 100_000
|
let startHeight = targetHeight - 10_000
|
||||||
let operation = CompactBlockBatchDownloadOperation(service: service,
|
let operation = CompactBlockBatchDownloadOperation(service: service,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
startHeight: startHeight, targetHeight: targetHeight,
|
startHeight: startHeight, targetHeight: targetHeight,
|
||||||
|
@ -203,13 +163,13 @@ class BlockStreamingTest: XCTestCase {
|
||||||
|
|
||||||
queue.addOperation(operation)
|
queue.addOperation(operation)
|
||||||
|
|
||||||
wait(for: [expectation], timeout: 300)
|
wait(for: [expectation], timeout: 120)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBatchOperationCancellation() throws {
|
func testBatchOperationCancellation() throws {
|
||||||
let expectation = XCTestExpectation(description: "blockbatch expectation")
|
let expectation = XCTestExpectation(description: "blockbatch expectation")
|
||||||
|
|
||||||
let service = LightWalletGRPCService(host: "lightwalletd.testnet.electriccoin.co",
|
let service = LightWalletGRPCService(host: LightWalletEndpointBuilder.eccTestnet.host,
|
||||||
port: 9067,
|
port: 9067,
|
||||||
secure: true,
|
secure: true,
|
||||||
singleCallTimeout: 300000,
|
singleCallTimeout: 300000,
|
||||||
|
@ -243,6 +203,6 @@ class BlockStreamingTest: XCTestCase {
|
||||||
extension BlockStreamingTest: CompactBlockProgressDelegate {
|
extension BlockStreamingTest: CompactBlockProgressDelegate {
|
||||||
|
|
||||||
func progressUpdated(_ progress: CompactBlockProgress) {
|
func progressUpdated(_ progress: CompactBlockProgress) {
|
||||||
// print("progressHeight: \(progress.progressHeight) startHeight: \(progress.startHeight), targetHeight: \(progress.targetHeight)")
|
print("progressHeight: \(String(describing: progress.progressHeight)) startHeight: \(progress.progress), targetHeight: \(String(describing: progress.targetHeight))")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
class CompactBlockProcessorTests: XCTestCase {
|
class CompactBlockProcessorTests: XCTestCase {
|
||||||
|
|
||||||
let processorConfig = CompactBlockProcessor.Configuration.standard
|
let processorConfig = CompactBlockProcessor.Configuration.standard(for: ZcashNetworkBuilder.network(for: .testnet), walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
var processor: CompactBlockProcessor!
|
var processor: CompactBlockProcessor!
|
||||||
var downloadStartedExpect: XCTestExpectation!
|
var downloadStartedExpect: XCTestExpectation!
|
||||||
var updatedNotificationExpectation: XCTestExpectation!
|
var updatedNotificationExpectation: XCTestExpectation!
|
||||||
|
@ -18,12 +18,26 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
var startedScanningNotificationExpectation: XCTestExpectation!
|
var startedScanningNotificationExpectation: XCTestExpectation!
|
||||||
var startedValidatingNotificationExpectation: XCTestExpectation!
|
var startedValidatingNotificationExpectation: XCTestExpectation!
|
||||||
var idleNotificationExpectation: XCTestExpectation!
|
var idleNotificationExpectation: XCTestExpectation!
|
||||||
let mockLatestHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 2000
|
let network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
|
let mockLatestHeight = ZcashNetworkBuilder.network(for: .testnet).constants.SAPLING_ACTIVATION_HEIGHT + 2000
|
||||||
|
|
||||||
override func setUp() {
|
override func setUpWithError() throws {
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
logger = SampleLogger(logLevel: .debug)
|
||||||
|
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: mockLatestHeight, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.eccTestnet))
|
||||||
|
let branchID = try ZcashRustBackend.consensusBranchIdFor(height: Int32(mockLatestHeight), networkType: network.networkType)
|
||||||
|
service.mockLightDInfo = LightdInfo.with({ info in
|
||||||
|
info.blockHeight = UInt64(mockLatestHeight)
|
||||||
|
info.branch = "asdf"
|
||||||
|
info.buildDate = "today"
|
||||||
|
info.buildUser = "testUser"
|
||||||
|
info.chainName = "test"
|
||||||
|
info.consensusBranchID = branchID.toString()
|
||||||
|
info.estimatedHeight = UInt64(mockLatestHeight)
|
||||||
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
|
})
|
||||||
|
|
||||||
let service = MockLightWalletService(latestBlockHeight: mockLatestHeight)
|
|
||||||
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
||||||
try! storage.createTable()
|
try! storage.createTable()
|
||||||
|
|
||||||
|
@ -32,7 +46,7 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
storage: storage,
|
storage: storage,
|
||||||
backend: ZcashRustBackend.self,
|
backend: ZcashRustBackend.self,
|
||||||
config: processorConfig)
|
config: processorConfig)
|
||||||
|
try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: .testnet)
|
||||||
downloadStartedExpect = XCTestExpectation(description: self.description + " downloadStartedExpect")
|
downloadStartedExpect = XCTestExpectation(description: self.description + " downloadStartedExpect")
|
||||||
stopNotificationExpectation = XCTestExpectation(description: self.description + " stopNotificationExpectation")
|
stopNotificationExpectation = XCTestExpectation(description: self.description + " stopNotificationExpectation")
|
||||||
updatedNotificationExpectation = XCTestExpectation(description: self.description + " updatedNotificationExpectation")
|
updatedNotificationExpectation = XCTestExpectation(description: self.description + " updatedNotificationExpectation")
|
||||||
|
@ -73,7 +87,7 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
updatedNotificationExpectation.subscribe(to: Notification.Name.blockProcessorUpdated, object: processor)
|
updatedNotificationExpectation.subscribe(to: Notification.Name.blockProcessorUpdated, object: processor)
|
||||||
startedValidatingNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedValidating, object: processor)
|
startedValidatingNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedValidating, object: processor)
|
||||||
startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor)
|
startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor)
|
||||||
idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorIdle, object: processor)
|
idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorFinished, object: processor)
|
||||||
|
|
||||||
XCTAssertNoThrow(try processor.start())
|
XCTAssertNoThrow(try processor.start())
|
||||||
}
|
}
|
||||||
|
@ -87,7 +101,7 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
startedValidatingNotificationExpectation,
|
startedValidatingNotificationExpectation,
|
||||||
startedScanningNotificationExpectation,
|
startedScanningNotificationExpectation,
|
||||||
idleNotificationExpectation,
|
idleNotificationExpectation,
|
||||||
], timeout: 260,enforceOrder: true)
|
], timeout: 30,enforceOrder: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testProgressNotifications() {
|
func testProgressNotifications() {
|
||||||
|
@ -109,15 +123,15 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
|
|
||||||
// test first range
|
// test first range
|
||||||
var latestDownloadedHeight = processorConfig.walletBirthday // this can be either this or Wallet Birthday.
|
var latestDownloadedHeight = processorConfig.walletBirthday // this can be either this or Wallet Birthday.
|
||||||
var latestBlockchainHeight = BlockHeight(ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 1000)
|
var latestBlockchainHeight = BlockHeight(network.constants.SAPLING_ACTIVATION_HEIGHT + 1000)
|
||||||
|
|
||||||
var expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight, upper:latestBlockchainHeight))
|
var expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight, upper:latestBlockchainHeight))
|
||||||
|
|
||||||
XCTAssertEqual(expectedBatchRange, CompactBlockProcessor.nextBatchBlockRange(latestHeight: latestBlockchainHeight, latestDownloadedHeight: latestDownloadedHeight, walletBirthday: processorConfig.walletBirthday))
|
XCTAssertEqual(expectedBatchRange, CompactBlockProcessor.nextBatchBlockRange(latestHeight: latestBlockchainHeight, latestDownloadedHeight: latestDownloadedHeight, walletBirthday: processorConfig.walletBirthday))
|
||||||
|
|
||||||
// Test mid-range
|
// Test mid-range
|
||||||
latestDownloadedHeight = BlockHeight(ZcashSDK.SAPLING_ACTIVATION_HEIGHT + ZcashSDK.DEFAULT_BATCH_SIZE)
|
latestDownloadedHeight = BlockHeight(network.constants.SAPLING_ACTIVATION_HEIGHT + ZcashSDK.DEFAULT_BATCH_SIZE)
|
||||||
latestBlockchainHeight = BlockHeight(ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 1000)
|
latestBlockchainHeight = BlockHeight(network.constants.SAPLING_ACTIVATION_HEIGHT + 1000)
|
||||||
|
|
||||||
expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight + 1, upper: latestBlockchainHeight))
|
expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight + 1, upper: latestBlockchainHeight))
|
||||||
|
|
||||||
|
@ -125,8 +139,8 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
|
|
||||||
// Test last batch range
|
// Test last batch range
|
||||||
|
|
||||||
latestDownloadedHeight = BlockHeight(ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 950)
|
latestDownloadedHeight = BlockHeight(network.constants.SAPLING_ACTIVATION_HEIGHT + 950)
|
||||||
latestBlockchainHeight = BlockHeight(ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 1000)
|
latestBlockchainHeight = BlockHeight(network.constants.SAPLING_ACTIVATION_HEIGHT + 1000)
|
||||||
|
|
||||||
expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight + 1, upper: latestBlockchainHeight))
|
expectedBatchRange = CompactBlockRange(uncheckedBounds: (lower: latestDownloadedHeight + 1, upper: latestBlockchainHeight))
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
class CompactBlockReorgTests: XCTestCase {
|
class CompactBlockReorgTests: XCTestCase {
|
||||||
|
|
||||||
let processorConfig = CompactBlockProcessor.Configuration.standard
|
let processorConfig = CompactBlockProcessor.Configuration.standard(for: ZcashNetworkBuilder.network(for: .testnet), walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
var processor: CompactBlockProcessor!
|
var processor: CompactBlockProcessor!
|
||||||
var downloadStartedExpect: XCTestExpectation!
|
var downloadStartedExpect: XCTestExpectation!
|
||||||
var updatedNotificationExpectation: XCTestExpectation!
|
var updatedNotificationExpectation: XCTestExpectation!
|
||||||
|
@ -20,19 +20,36 @@ class CompactBlockReorgTests: XCTestCase {
|
||||||
var startedValidatingNotificationExpectation: XCTestExpectation!
|
var startedValidatingNotificationExpectation: XCTestExpectation!
|
||||||
var idleNotificationExpectation: XCTestExpectation!
|
var idleNotificationExpectation: XCTestExpectation!
|
||||||
var reorgNotificationExpectation: XCTestExpectation!
|
var reorgNotificationExpectation: XCTestExpectation!
|
||||||
let mockLatestHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 2000
|
let network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
|
let mockLatestHeight = ZcashNetworkBuilder.network(for: .testnet).constants.SAPLING_ACTIVATION_HEIGHT + 2000
|
||||||
|
|
||||||
override func setUp() {
|
override func setUpWithError() throws {
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
||||||
let service = MockLightWalletService(latestBlockHeight: mockLatestHeight)
|
logger = SampleLogger(logLevel: .debug)
|
||||||
|
|
||||||
|
let service = MockLightWalletService(latestBlockHeight: mockLatestHeight, service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.eccTestnet))
|
||||||
|
let branchID = try ZcashRustBackend.consensusBranchIdFor(height: Int32(mockLatestHeight), networkType: network.networkType)
|
||||||
|
service.mockLightDInfo = LightdInfo.with({ info in
|
||||||
|
info.blockHeight = UInt64(mockLatestHeight)
|
||||||
|
info.branch = "asdf"
|
||||||
|
info.buildDate = "today"
|
||||||
|
info.buildUser = "testUser"
|
||||||
|
info.chainName = "test"
|
||||||
|
info.consensusBranchID = branchID.toString()
|
||||||
|
info.estimatedHeight = UInt64(mockLatestHeight)
|
||||||
|
info.saplingActivationHeight = UInt64(network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
|
})
|
||||||
|
|
||||||
|
try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: .testnet)
|
||||||
|
|
||||||
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
||||||
try! storage.createTable()
|
try! storage.createTable()
|
||||||
|
|
||||||
let mockBackend = MockRustBackend.self
|
let mockBackend = MockRustBackend.self
|
||||||
mockBackend.mockValidateCombinedChainFailAfterAttempts = 3
|
mockBackend.mockValidateCombinedChainFailAfterAttempts = 3
|
||||||
mockBackend.mockValidateCombinedChainKeepFailing = false
|
mockBackend.mockValidateCombinedChainKeepFailing = false
|
||||||
mockBackend.mockValidateCombinedChainFailureHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 320
|
mockBackend.mockValidateCombinedChainFailureHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT + 320
|
||||||
|
|
||||||
processor = CompactBlockProcessor(service: service,
|
processor = CompactBlockProcessor(service: service,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
|
@ -69,8 +86,8 @@ class CompactBlockReorgTests: XCTestCase {
|
||||||
XCTAssertNotNil(notification.userInfo)
|
XCTAssertNotNil(notification.userInfo)
|
||||||
if let reorg = notification.userInfo?[CompactBlockProcessorNotificationKey.reorgHeight] as? BlockHeight,
|
if let reorg = notification.userInfo?[CompactBlockProcessorNotificationKey.reorgHeight] as? BlockHeight,
|
||||||
let rewind = notification.userInfo?[CompactBlockProcessorNotificationKey.rewindHeight] as? BlockHeight {
|
let rewind = notification.userInfo?[CompactBlockProcessorNotificationKey.rewindHeight] as? BlockHeight {
|
||||||
XCTAssertTrue( reorg == 0 || reorg > ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
XCTAssertTrue( reorg == 0 || reorg > self.network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
XCTAssertTrue( rewind == 0 || rewind > ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
XCTAssertTrue( rewind == 0 || rewind > self.network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
XCTAssertTrue( rewind <= reorg )
|
XCTAssertTrue( rewind <= reorg )
|
||||||
reorgNotificationExpectation.fulfill()
|
reorgNotificationExpectation.fulfill()
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,7 +115,7 @@ class CompactBlockReorgTests: XCTestCase {
|
||||||
updatedNotificationExpectation.subscribe(to: Notification.Name.blockProcessorUpdated, object: processor)
|
updatedNotificationExpectation.subscribe(to: Notification.Name.blockProcessorUpdated, object: processor)
|
||||||
startedValidatingNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedValidating, object: processor)
|
startedValidatingNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedValidating, object: processor)
|
||||||
startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor)
|
startedScanningNotificationExpectation.subscribe(to: Notification.Name.blockProcessorStartedScanning, object: processor)
|
||||||
idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorIdle, object: processor)
|
idleNotificationExpectation.subscribe(to: Notification.Name.blockProcessorFinished, object: processor)
|
||||||
reorgNotificationExpectation.subscribe(to: Notification.Name.blockProcessorHandledReOrg, object: processor)
|
reorgNotificationExpectation.subscribe(to: Notification.Name.blockProcessorHandledReOrg, object: processor)
|
||||||
|
|
||||||
XCTAssertNoThrow(try processor.start())
|
XCTAssertNoThrow(try processor.start())
|
||||||
|
|
|
@ -13,13 +13,14 @@ class CompactBlockStorageTests: XCTestCase {
|
||||||
|
|
||||||
var compactBlockDao: CompactBlockRepository = try! TestDbBuilder.inMemoryCompactBlockStorage()
|
var compactBlockDao: CompactBlockRepository = try! TestDbBuilder.inMemoryCompactBlockStorage()
|
||||||
|
|
||||||
|
let network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
func testEmptyStorage() {
|
func testEmptyStorage() {
|
||||||
XCTAssertEqual(try! compactBlockDao.latestHeight(), BlockHeight.empty())
|
XCTAssertEqual(try! compactBlockDao.latestHeight(), BlockHeight.empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testStoreThousandBlocks() {
|
func testStoreThousandBlocks() {
|
||||||
let initialHeight = try! compactBlockDao.latestHeight()
|
let initialHeight = try! compactBlockDao.latestHeight()
|
||||||
let startHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let startHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let blockCount = Int(1_000)
|
let blockCount = Int(1_000)
|
||||||
let finalHeight = startHeight + blockCount
|
let finalHeight = startHeight + blockCount
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ class CompactBlockStorageTests: XCTestCase {
|
||||||
|
|
||||||
func testRewindTo() {
|
func testRewindTo() {
|
||||||
|
|
||||||
let startHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let startHeight = self.network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let blockCount = Int(1_000)
|
let blockCount = Int(1_000)
|
||||||
let finalHeight = startHeight + blockCount
|
let finalHeight = startHeight + blockCount
|
||||||
|
|
||||||
|
|
|
@ -22,15 +22,20 @@ class DarksideSanityCheckTests: XCTestCase {
|
||||||
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
||||||
var expectedReorgHeight: BlockHeight = 665188
|
var expectedReorgHeight: BlockHeight = 665188
|
||||||
var expectedRewindHeight: BlockHeight = 665188
|
var expectedRewindHeight: BlockHeight = 665188
|
||||||
|
var network = DarksideWalletDNetwork()
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
|
let branchID = "2bb40e60"
|
||||||
|
let chainName = "main"
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: birthday, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
|
||||||
try coordinator.resetBlocks(dataset: .default)
|
try coordinator.resetBlocks(dataset: .default)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SQLite
|
||||||
class DownloadOperationTests: XCTestCase {
|
class DownloadOperationTests: XCTestCase {
|
||||||
|
|
||||||
var operationQueue = OperationQueue()
|
var operationQueue = OperationQueue()
|
||||||
|
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
operationQueue.cancelAllOperations()
|
operationQueue.cancelAllOperations()
|
||||||
|
@ -21,11 +21,12 @@ class DownloadOperationTests: XCTestCase {
|
||||||
func testSingleOperation() {
|
func testSingleOperation() {
|
||||||
let expect = XCTestExpectation(description: self.description)
|
let expect = XCTestExpectation(description: self.description)
|
||||||
|
|
||||||
let service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
let service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.eccTestnet)
|
||||||
let storage = try! TestDbBuilder.inMemoryCompactBlockStorage()
|
let storage = try! TestDbBuilder.inMemoryCompactBlockStorage()
|
||||||
let downloader = CompactBlockDownloader(service: service, storage: storage)
|
let downloader = CompactBlockDownloader(service: service, storage: storage)
|
||||||
let blockCount = 100
|
let blockCount = 100
|
||||||
let range = ZcashSDK.SAPLING_ACTIVATION_HEIGHT ... ZcashSDK.SAPLING_ACTIVATION_HEIGHT + blockCount
|
let activationHeight = network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
|
let range = activationHeight ... activationHeight + blockCount
|
||||||
let downloadOperation = CompactBlockDownloadOperation(downloader: downloader, range: range)
|
let downloadOperation = CompactBlockDownloadOperation(downloader: downloader, range: range)
|
||||||
|
|
||||||
downloadOperation.completionHandler = { (finished, cancelled) in
|
downloadOperation.completionHandler = { (finished, cancelled) in
|
||||||
|
|
|
@ -13,10 +13,11 @@ class LightWalletServiceTests: XCTestCase {
|
||||||
|
|
||||||
var service: LightWalletService!
|
var service: LightWalletService!
|
||||||
var channel: Channel!
|
var channel: Channel!
|
||||||
|
let network: ZcashNetwork = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
channel = ChannelProvider().channel()
|
channel = ChannelProvider().channel()
|
||||||
service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.eccTestnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
|
@ -39,8 +40,8 @@ class LightWalletServiceTests: XCTestCase {
|
||||||
func testHundredBlocks() {
|
func testHundredBlocks() {
|
||||||
let expect = XCTestExpectation(description: self.description)
|
let expect = XCTestExpectation(description: self.description)
|
||||||
let count = 99
|
let count = 99
|
||||||
let lowerRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let lowerRange: BlockHeight = network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let upperRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + count
|
let upperRange: BlockHeight = network.constants.SAPLING_ACTIVATION_HEIGHT + count
|
||||||
let blockRange = lowerRange ... upperRange
|
let blockRange = lowerRange ... upperRange
|
||||||
|
|
||||||
service.blockRange(blockRange) { (result) in
|
service.blockRange(blockRange) { (result) in
|
||||||
|
@ -60,8 +61,8 @@ class LightWalletServiceTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSyncBlockRange() {
|
func testSyncBlockRange() {
|
||||||
let lowerRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT
|
let lowerRange: BlockHeight = network.constants.SAPLING_ACTIVATION_HEIGHT
|
||||||
let upperRange: BlockHeight = ZcashSDK.SAPLING_ACTIVATION_HEIGHT + 99
|
let upperRange: BlockHeight = network.constants.SAPLING_ACTIVATION_HEIGHT + 99
|
||||||
let blockRange = lowerRange ... upperRange
|
let blockRange = lowerRange ... upperRange
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -80,7 +81,7 @@ class LightWalletServiceTests: XCTestCase {
|
||||||
case .failure(let e):
|
case .failure(let e):
|
||||||
XCTFail("error: \(e)")
|
XCTFail("error: \(e)")
|
||||||
case .success(let height):
|
case .success(let height):
|
||||||
XCTAssertTrue(height > ZcashSDK.SAPLING_ACTIVATION_HEIGHT)
|
XCTAssertTrue(height > self.network.constants.SAPLING_ACTIVATION_HEIGHT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
var coordinator: TestCoordinator!
|
var coordinator: TestCoordinator!
|
||||||
|
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
// coordinator = try TestCoordinator(
|
// coordinator = try TestCoordinator(
|
||||||
|
@ -28,7 +29,7 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
// walletBirthday: birthday,
|
// walletBirthday: birthday,
|
||||||
// channelProvider: ChannelProvider()
|
// channelProvider: ChannelProvider()
|
||||||
// )
|
// )
|
||||||
try coordinator.reset(saplingActivation: birthday, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDownWithError() throws {
|
override func tearDownWithError() throws {
|
||||||
|
@ -59,7 +60,7 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
|
|
||||||
wait(for: [firstSyncExpectation], timeout: 120)
|
wait(for: [firstSyncExpectation], timeout: 120)
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
guard verifiedBalance > ZcashSDK.MINERS_FEE_ZATOSHI else {
|
guard verifiedBalance > network.constants.defaultFee(for: activationHeight) else {
|
||||||
XCTFail("not enough balance to continue test")
|
XCTFail("not enough balance to continue test")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -206,7 +207,7 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
|
|
||||||
wait(for: [firstSyncExpectation], timeout: 120)
|
wait(for: [firstSyncExpectation], timeout: 120)
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.MINERS_FEE_ZATOSHI)
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: activationHeight))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,7 +297,7 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
|
|
||||||
wait(for: [firstSyncExpectation], timeout: 120)
|
wait(for: [firstSyncExpectation], timeout: 120)
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
guard verifiedBalance > ZcashSDK.MINERS_FEE_ZATOSHI else {
|
guard verifiedBalance > network.constants.defaultFee(for: activationHeight) else {
|
||||||
XCTFail("balance is not enough to continue with this test")
|
XCTFail("balance is not enough to continue with this test")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -403,7 +404,7 @@ class NetworkUpgradeTests: XCTestCase {
|
||||||
var p: PendingTransactionEntity? = nil
|
var p: PendingTransactionEntity? = nil
|
||||||
|
|
||||||
// spend all the funds
|
// spend all the funds
|
||||||
let spendAmount: Int64 = postActivationBalance - Int64(ZcashSDK.MINERS_FEE_ZATOSHI)
|
let spendAmount: Int64 = postActivationBalance - Int64(network.constants.defaultFee(for: activationHeight))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
send transaction to recipient address
|
send transaction to recipient address
|
||||||
|
|
|
@ -8,18 +8,18 @@
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
class NullBytesTests: XCTestCase {
|
class NullBytesTests: XCTestCase {
|
||||||
|
let networkType = NetworkType.mainnet
|
||||||
func testZaddrNullBytes() throws {
|
func testZaddrNullBytes() throws {
|
||||||
let validZaddr = "zs1gqtfu59z20s9t20mxlxj86zpw6p69l0ev98uxrmlykf2nchj2dw8ny5e0l22kwmld2afc37gkfp" // this is a valid zAddr. if you send ZEC to it, you will be contributing to Human Rights Foundation. see more ways to help at https://paywithz.cash/
|
let validZaddr = "zs1gqtfu59z20s9t20mxlxj86zpw6p69l0ev98uxrmlykf2nchj2dw8ny5e0l22kwmld2afc37gkfp" // this is a valid zAddr. if you send ZEC to it, you will be contributing to Human Rights Foundation. see more ways to help at https://paywithz.cash/
|
||||||
let ZaddrWithNullBytes = "\(validZaddr)\0something else that makes the address invalid"
|
let ZaddrWithNullBytes = "\(validZaddr)\0something else that makes the address invalid"
|
||||||
|
|
||||||
XCTAssertFalse(try ZcashRustBackend.isValidShieldedAddress(ZaddrWithNullBytes))
|
XCTAssertFalse(try ZcashRustBackend.isValidShieldedAddress(ZaddrWithNullBytes, networkType: networkType))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTaddrNullBytes() throws {
|
func testTaddrNullBytes() throws {
|
||||||
let validTAddr = "t1J5pTRzJi7j8Xw9VJTrPxPEkaigr69gKVT" // this is a valid tAddr. if you send ZEC to it, you will be contributing to Human Rights Foundation. see more ways to help at https://paywithz.cash/
|
let validTAddr = "t1J5pTRzJi7j8Xw9VJTrPxPEkaigr69gKVT" // this is a valid tAddr. if you send ZEC to it, you will be contributing to Human Rights Foundation. see more ways to help at https://paywithz.cash/
|
||||||
let TaddrWithNullBytes = "\(validTAddr)\0fasdfasdf"
|
let TaddrWithNullBytes = "\(validTAddr)\0fasdfasdf"
|
||||||
XCTAssertFalse(try ZcashRustBackend.isValidTransparentAddress(TaddrWithNullBytes))
|
XCTAssertFalse(try ZcashRustBackend.isValidTransparentAddress(TaddrWithNullBytes, networkType: networkType))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInitAccountTableNullBytes() throws {
|
func testInitAccountTableNullBytes() throws {
|
||||||
|
@ -30,7 +30,7 @@ class NullBytesTests: XCTestCase {
|
||||||
let wrongTree = "0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101daeffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe4100010bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024\0750065a4a0001a9e1bf4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
let wrongTree = "0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101daeffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe4100010bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024\0750065a4a0001a9e1bf4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
let goodTree = "0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101daeffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe4100010bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024750065a4a0001a9e1bf4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
let goodTree = "0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101daeffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe4100010bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024750065a4a0001a9e1bf4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260"
|
||||||
|
|
||||||
XCTAssertThrowsError(try ZcashRustBackend.initBlocksTable(dbData: __dataDbURL(), height: height , hash: wrongHash, time: time, saplingTree: goodTree), "InitBlocksTable with Null bytes on hash string should have failed") { (error) in
|
XCTAssertThrowsError(try ZcashRustBackend.initBlocksTable(dbData: __dataDbURL(), height: height , hash: wrongHash, time: time, saplingTree: goodTree, networkType: networkType), "InitBlocksTable with Null bytes on hash string should have failed") { (error) in
|
||||||
|
|
||||||
guard let rustError = error as? RustWeldingError else {
|
guard let rustError = error as? RustWeldingError else {
|
||||||
XCTFail("Expected RustWeldingError")
|
XCTFail("Expected RustWeldingError")
|
||||||
|
@ -45,7 +45,7 @@ class NullBytesTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertThrowsError(try ZcashRustBackend.initBlocksTable(dbData: __dataDbURL(), height: height , hash: goodHash, time: time, saplingTree: wrongTree), "InitBlocksTable with Null bytes on saplingTree string should have failed") { (error) in
|
XCTAssertThrowsError(try ZcashRustBackend.initBlocksTable(dbData: __dataDbURL(), height: height , hash: goodHash, time: time, saplingTree: wrongTree, networkType: networkType), "InitBlocksTable with Null bytes on saplingTree string should have failed") { (error) in
|
||||||
|
|
||||||
guard let rustError = error as? RustWeldingError else {
|
guard let rustError = error as? RustWeldingError else {
|
||||||
XCTFail("Expected RustWeldingError")
|
XCTFail("Expected RustWeldingError")
|
||||||
|
@ -66,7 +66,7 @@ class NullBytesTests: XCTestCase {
|
||||||
|
|
||||||
let goodSpendingKeys = "secret-extended-key-main1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkyuegyhh5d4rdr8025nl7e0hm8r2txx3fuea5mquy3wnsr9tlajsg4wwvw0xcfk8357k4h850rgj72kt4rx3fjdz99zs9f4neda35cq8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszc7nc9vv"
|
let goodSpendingKeys = "secret-extended-key-main1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkyuegyhh5d4rdr8025nl7e0hm8r2txx3fuea5mquy3wnsr9tlajsg4wwvw0xcfk8357k4h850rgj72kt4rx3fjdz99zs9f4neda35cq8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszc7nc9vv"
|
||||||
|
|
||||||
XCTAssertThrowsError(try ZcashRustBackend.deriveExtendedFullViewingKey(wrongSpendingKeys),"Should have thrown an error but didn't! this is dangerous!") { (error) in
|
XCTAssertThrowsError(try ZcashRustBackend.deriveExtendedFullViewingKey(wrongSpendingKeys, networkType: networkType),"Should have thrown an error but didn't! this is dangerous!") { (error) in
|
||||||
|
|
||||||
guard let rustError = error as? RustWeldingError else {
|
guard let rustError = error as? RustWeldingError else {
|
||||||
XCTFail("Expected RustWeldingError")
|
XCTFail("Expected RustWeldingError")
|
||||||
|
@ -81,7 +81,7 @@ class NullBytesTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertNoThrow(try ZcashRustBackend.deriveExtendedFullViewingKey(goodSpendingKeys))
|
XCTAssertNoThrow(try ZcashRustBackend.deriveExtendedFullViewingKey(goodSpendingKeys, networkType: networkType))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ class PagedTransactionRepositoryTests: XCTestCase {
|
||||||
var transactionRepository: TransactionRepository!
|
var transactionRepository: TransactionRepository!
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
transactionRepository = MockTransactionRepository(unminedCount: 5, receivedCount: 150, sentCount: 100)
|
transactionRepository = MockTransactionRepository(unminedCount: 5, receivedCount: 150, sentCount: 100, network: ZcashNetworkBuilder.network(for: .testnet))
|
||||||
pagedTransactionRepository = PagedTransactionDAO(repository: transactionRepository)
|
pagedTransactionRepository = PagedTransactionDAO(repository: transactionRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,14 @@ class PendingTransactionUpdatesTest: XCTestCase {
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
|
let network = DarksideWalletDNetwork()
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,25 +22,29 @@ import XCTest
|
||||||
class ReOrgTests: XCTestCase {
|
class ReOrgTests: XCTestCase {
|
||||||
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" //TODO: Parameterize this from environment?
|
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread" //TODO: Parameterize this from environment?
|
||||||
|
|
||||||
let testRecipientAddress = "zs17mg40levjezevuhdp5pqrd52zere7r7vrjgdwn5sj4xsqtm20euwahv9anxmwr3y3kmwuz8k55a" //TODO: Parameterize this from environment
|
let testRecipientAddress = "zs17mg40levjezevuhdp5pqrd52zere7r7vrjgdwn5sj4xsqtm20euwahv9anxmwr3y3kmwuz8k55a" //TODO: Parameterize this from environment
|
||||||
|
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
var coordinator: TestCoordinator!
|
var coordinator: TestCoordinator!
|
||||||
var syncedExpectation = XCTestExpectation(description: "synced")
|
var syncedExpectation = XCTestExpectation(description: "synced")
|
||||||
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
||||||
var expectedReorgHeight: BlockHeight = 665188
|
var expectedReorgHeight: BlockHeight = 665188
|
||||||
var expectedRewindHeight: BlockHeight = 665188
|
var expectedRewindHeight: BlockHeight = 665188
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
let network = DarksideWalletDNetwork()
|
||||||
override func setUpWithError() throws {
|
let branchID = "2bb40e60"
|
||||||
|
let chainName = "main"
|
||||||
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
|
override func setUpWithError() throws {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(handleReOrgNotification(_:)), name: Notification.Name.blockProcessorHandledReOrg, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(handleReOrgNotification(_:)), name: Notification.Name.blockProcessorHandledReOrg, object: nil)
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: birthday, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
|
||||||
try coordinator.resetBlocks(dataset: .default)
|
try coordinator.resetBlocks(dataset: .default)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,7 @@ class ReOrgTests: XCTestCase {
|
||||||
let mockLatestHeight = BlockHeight(663200)
|
let mockLatestHeight = BlockHeight(663200)
|
||||||
let targetLatestHeight = BlockHeight(663202)
|
let targetLatestHeight = BlockHeight(663202)
|
||||||
let reOrgHeight = BlockHeight(663195)
|
let reOrgHeight = BlockHeight(663195)
|
||||||
let walletBirthday = WalletBirthday.birthday(with: 663150).height
|
let walletBirthday = WalletBirthday.birthday(with: 663150, network: network).height
|
||||||
|
|
||||||
try basicReOrgTest(baseDataset: .beforeReOrg,
|
try basicReOrgTest(baseDataset: .beforeReOrg,
|
||||||
reorgDataset: .afterSmallReorg,
|
reorgDataset: .afterSmallReorg,
|
||||||
|
@ -89,7 +93,7 @@ class ReOrgTests: XCTestCase {
|
||||||
let mockLatestHeight = BlockHeight(663200)
|
let mockLatestHeight = BlockHeight(663200)
|
||||||
let targetLatestHeight = BlockHeight(663250)
|
let targetLatestHeight = BlockHeight(663250)
|
||||||
let reOrgHeight = BlockHeight(663180)
|
let reOrgHeight = BlockHeight(663180)
|
||||||
let walletBirthday = WalletBirthday.birthday(with: BlockHeight(663150)).height
|
let walletBirthday = WalletBirthday.birthday(with: BlockHeight(663150), network: network).height
|
||||||
|
|
||||||
try basicReOrgTest(baseDataset: .beforeReOrg,
|
try basicReOrgTest(baseDataset: .beforeReOrg,
|
||||||
reorgDataset: .afterLargeReorg,
|
reorgDataset: .afterLargeReorg,
|
||||||
|
@ -107,7 +111,7 @@ class ReOrgTests: XCTestCase {
|
||||||
targetHeight: BlockHeight) throws {
|
targetHeight: BlockHeight) throws {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try coordinator.reset(saplingActivation: birthday, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
|
||||||
try coordinator.resetBlocks(dataset: .predefined(dataset: .beforeReOrg))
|
try coordinator.resetBlocks(dataset: .predefined(dataset: .beforeReOrg))
|
||||||
try coordinator.applyStaged(blockheight: firstLatestHeight)
|
try coordinator.applyStaged(blockheight: firstLatestHeight)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -23,12 +23,14 @@ class RewindRescanTests: XCTestCase {
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
|
var network = ZcashNetworkBuilder.network(for: .mainnet)
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,7 @@ class RewindRescanTests: XCTestCase {
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
// 2 check that there are no unconfirmed funds
|
// 2 check that there are no unconfirmed funds
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
// rewind to birthday
|
// rewind to birthday
|
||||||
|
@ -114,12 +116,12 @@ class RewindRescanTests: XCTestCase {
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
// 2 check that there are no unconfirmed funds
|
// 2 check that there are no unconfirmed funds
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
// rewind to birthday
|
// rewind to birthday
|
||||||
let targetHeight: BlockHeight = newChaintTip - 8000
|
let targetHeight: BlockHeight = newChaintTip - 8000
|
||||||
let rewindHeight = ZcashRustBackend.getNearestRewindHeight(dbData: coordinator.databases.dataDB, height: Int32(targetHeight))
|
let rewindHeight = ZcashRustBackend.getNearestRewindHeight(dbData: coordinator.databases.dataDB, height: Int32(targetHeight), networkType: network.networkType)
|
||||||
try coordinator.synchronizer.rewind(.height(blockheight: targetHeight))
|
try coordinator.synchronizer.rewind(.height(blockheight: targetHeight))
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,7 +181,7 @@ class RewindRescanTests: XCTestCase {
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
// 2 check that there are no unconfirmed funds
|
// 2 check that there are no unconfirmed funds
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
// rewind to transaction
|
// rewind to transaction
|
||||||
|
@ -192,7 +194,7 @@ class RewindRescanTests: XCTestCase {
|
||||||
|
|
||||||
|
|
||||||
// assert that after the new height is
|
// assert that after the new height is
|
||||||
XCTAssertEqual(try coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight(),transaction.transactionEntity.anchor)
|
XCTAssertEqual(try coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight(),transaction.transactionEntity.anchor(network: network))
|
||||||
|
|
||||||
let secondScanExpectation = XCTestExpectation(description: "rescan")
|
let secondScanExpectation = XCTestExpectation(description: "rescan")
|
||||||
|
|
||||||
|
@ -232,10 +234,10 @@ class RewindRescanTests: XCTestCase {
|
||||||
|
|
||||||
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
let verifiedBalance = coordinator.synchronizer.initializer.getVerifiedBalance()
|
||||||
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
let totalBalance = coordinator.synchronizer.initializer.getBalance()
|
||||||
XCTAssertTrue(verifiedBalance > ZcashSDK.defaultFee())
|
XCTAssertTrue(verifiedBalance > network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
XCTAssertEqual(verifiedBalance, totalBalance)
|
XCTAssertEqual(verifiedBalance, totalBalance)
|
||||||
|
|
||||||
let maxBalance = verifiedBalance - Int64(ZcashSDK.defaultFee())
|
let maxBalance = verifiedBalance - Int64(network.constants.defaultFee(for: defaultLatestHeight))
|
||||||
|
|
||||||
// 3 create a transaction for the max amount possible
|
// 3 create a transaction for the max amount possible
|
||||||
// 4 send the transaction
|
// 4 send the transaction
|
||||||
|
|
|
@ -23,13 +23,15 @@ class SychronizerDarksideTests: XCTestCase {
|
||||||
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
let chainName = "main"
|
let chainName = "main"
|
||||||
|
let network = DarksideWalletDNetwork()
|
||||||
var foundTransactions = [ConfirmedTransactionEntity]()
|
var foundTransactions = [ConfirmedTransactionEntity]()
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
|
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
channelProvider: ChannelProvider()
|
channelProvider: ChannelProvider(),
|
||||||
|
network: network
|
||||||
)
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,32 +43,36 @@ class TestCoordinator {
|
||||||
var service: DarksideWalletService
|
var service: DarksideWalletService
|
||||||
var spendingKeys: [String]?
|
var spendingKeys: [String]?
|
||||||
var databases: TemporaryTestDatabases
|
var databases: TemporaryTestDatabases
|
||||||
|
let network: ZcashNetwork
|
||||||
convenience init(seed: String,
|
convenience init(seed: String,
|
||||||
walletBirthday: BlockHeight,
|
walletBirthday: BlockHeight,
|
||||||
channelProvider: ChannelProvider) throws {
|
channelProvider: ChannelProvider,
|
||||||
guard let spendingKey = try DerivationTool.default.deriveSpendingKeys(
|
network: ZcashNetwork) throws {
|
||||||
|
let derivationTool = DerivationTool(networkType: network.networkType)
|
||||||
|
guard let spendingKey = try derivationTool.deriveSpendingKeys(
|
||||||
seed: TestSeed().seed(),
|
seed: TestSeed().seed(),
|
||||||
numberOfAccounts: 1).first else {
|
numberOfAccounts: 1).first else {
|
||||||
throw CoordinatorError.builderError
|
throw CoordinatorError.builderError
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let uvk = try DerivationTool.default.deriveUnifiedViewingKeysFromSeed(TestSeed().seed(), numberOfAccounts: 1).first else {
|
guard let uvk = try derivationTool.deriveUnifiedViewingKeysFromSeed(TestSeed().seed(), numberOfAccounts: 1).first else {
|
||||||
throw CoordinatorError.builderError
|
throw CoordinatorError.builderError
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.init(spendingKey: spendingKey, unifiedViewingKey: uvk, walletBirthday: walletBirthday, channelProvider: channelProvider)
|
try self.init(spendingKey: spendingKey, unifiedViewingKey: uvk, walletBirthday: walletBirthday, channelProvider: channelProvider, network: network)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init(
|
required init(
|
||||||
spendingKey: String,
|
spendingKey: String,
|
||||||
unifiedViewingKey: UnifiedViewingKey,
|
unifiedViewingKey: UnifiedViewingKey,
|
||||||
walletBirthday: BlockHeight,
|
walletBirthday: BlockHeight,
|
||||||
channelProvider: ChannelProvider) throws {
|
channelProvider: ChannelProvider,
|
||||||
|
network: ZcashNetwork) throws {
|
||||||
self.spendingKey = spendingKey
|
self.spendingKey = spendingKey
|
||||||
self.birthday = walletBirthday
|
self.birthday = walletBirthday
|
||||||
self.channelProvider = channelProvider
|
self.channelProvider = channelProvider
|
||||||
self.databases = TemporaryDbBuilder.build()
|
self.databases = TemporaryDbBuilder.build()
|
||||||
|
self.network = network
|
||||||
self.service = DarksideWalletService(service: LightWalletGRPCService(host: Constants.address, port: 9067, secure: false, singleCallTimeout: 10000, streamingCallTimeout: 1000000))
|
self.service = DarksideWalletService(service: LightWalletGRPCService(host: Constants.address, port: 9067, secure: false, singleCallTimeout: 10000, streamingCallTimeout: 1000000))
|
||||||
let storage = CompactBlockStorage(url: databases.cacheDB, readonly: false)
|
let storage = CompactBlockStorage(url: databases.cacheDB, readonly: false)
|
||||||
try storage.createTable()
|
try storage.createTable()
|
||||||
|
@ -89,7 +93,8 @@ class TestCoordinator {
|
||||||
outputParamsURL: try __outputParamsURL(),
|
outputParamsURL: try __outputParamsURL(),
|
||||||
spendingKey: spendingKey,
|
spendingKey: spendingKey,
|
||||||
unifiedViewingKey: unifiedViewingKey,
|
unifiedViewingKey: unifiedViewingKey,
|
||||||
walletBirthday: WalletBirthday.birthday(with: birthday),
|
walletBirthday: WalletBirthday.birthday(with: birthday, network: network),
|
||||||
|
network: network,
|
||||||
loggerProxy: SampleLogger(logLevel: .debug))
|
loggerProxy: SampleLogger(logLevel: .debug))
|
||||||
|
|
||||||
self.synchronizer = buildResult.synchronizer
|
self.synchronizer = buildResult.synchronizer
|
||||||
|
@ -210,7 +215,8 @@ extension TestCoordinator {
|
||||||
maxBackoffInterval: config.maxBackoffInterval,
|
maxBackoffInterval: config.maxBackoffInterval,
|
||||||
rewindDistance: config.rewindDistance,
|
rewindDistance: config.rewindDistance,
|
||||||
walletBirthday: config.walletBirthday,
|
walletBirthday: config.walletBirthday,
|
||||||
saplingActivation: config.saplingActivation)
|
saplingActivation: config.saplingActivation,
|
||||||
|
network: config.network)
|
||||||
try service.reset(saplingActivation: saplingActivation, branchID: branchID, chainName: chainName)
|
try service.reset(saplingActivation: saplingActivation, branchID: branchID, chainName: chainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,11 +260,13 @@ class TestSynchronizerBuilder {
|
||||||
spendingKey: String,
|
spendingKey: String,
|
||||||
unifiedViewingKey: UnifiedViewingKey,
|
unifiedViewingKey: UnifiedViewingKey,
|
||||||
walletBirthday: WalletBirthday,
|
walletBirthday: WalletBirthday,
|
||||||
|
network: ZcashNetwork,
|
||||||
loggerProxy: Logger? = nil
|
loggerProxy: Logger? = nil
|
||||||
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
||||||
let initializer = Initializer(
|
let initializer = Initializer(
|
||||||
rustBackend: rustBackend,
|
rustBackend: rustBackend,
|
||||||
lowerBoundHeight: lowerBoundHeight,
|
lowerBoundHeight: lowerBoundHeight,
|
||||||
|
network: network,
|
||||||
cacheDbURL: cacheDbURL,
|
cacheDbURL: cacheDbURL,
|
||||||
dataDbURL: dataDbURL,
|
dataDbURL: dataDbURL,
|
||||||
pendingDbURL: pendingDbURL,
|
pendingDbURL: pendingDbURL,
|
||||||
|
@ -281,7 +289,8 @@ class TestSynchronizerBuilder {
|
||||||
maxBackoffInterval: ZcashSDK.DEFAULT_MAX_BACKOFF_INTERVAL,
|
maxBackoffInterval: ZcashSDK.DEFAULT_MAX_BACKOFF_INTERVAL,
|
||||||
rewindDistance: ZcashSDK.DEFAULT_REWIND_DISTANCE,
|
rewindDistance: ZcashSDK.DEFAULT_REWIND_DISTANCE,
|
||||||
walletBirthday: walletBirthday.height,
|
walletBirthday: walletBirthday.height,
|
||||||
saplingActivation: lowerBoundHeight)
|
saplingActivation: lowerBoundHeight,
|
||||||
|
network: network)
|
||||||
|
|
||||||
let processor = CompactBlockProcessor(service: service,
|
let processor = CompactBlockProcessor(service: service,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
|
@ -318,13 +327,14 @@ class TestSynchronizerBuilder {
|
||||||
outputParamsURL: URL,
|
outputParamsURL: URL,
|
||||||
seedBytes: [UInt8],
|
seedBytes: [UInt8],
|
||||||
walletBirthday: WalletBirthday,
|
walletBirthday: WalletBirthday,
|
||||||
|
network: ZcashNetwork,
|
||||||
loggerProxy: Logger? = nil
|
loggerProxy: Logger? = nil
|
||||||
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
||||||
guard let spendingKey = try DerivationTool().deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
guard let spendingKey = try DerivationTool(networkType: network.networkType).deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
||||||
throw TestCoordinator.CoordinatorError.builderError
|
throw TestCoordinator.CoordinatorError.builderError
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let uvk = try DerivationTool().deriveUnifiedViewingKeysFromSeed(seedBytes, numberOfAccounts: 1).first else {
|
guard let uvk = try DerivationTool(networkType: network.networkType).deriveUnifiedViewingKeysFromSeed(seedBytes, numberOfAccounts: 1).first else {
|
||||||
throw TestCoordinator.CoordinatorError.builderError
|
throw TestCoordinator.CoordinatorError.builderError
|
||||||
}
|
}
|
||||||
return try build(rustBackend: rustBackend,
|
return try build(rustBackend: rustBackend,
|
||||||
|
@ -341,7 +351,8 @@ class TestSynchronizerBuilder {
|
||||||
outputParamsURL: outputParamsURL,
|
outputParamsURL: outputParamsURL,
|
||||||
spendingKey: spendingKey,
|
spendingKey: spendingKey,
|
||||||
unifiedViewingKey: uvk,
|
unifiedViewingKey: uvk,
|
||||||
walletBirthday: walletBirthday)
|
walletBirthday: walletBirthday,
|
||||||
|
network: network)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,34 +26,12 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
let mockLatestHeight = BlockHeight(663250)
|
let mockLatestHeight = BlockHeight(663250)
|
||||||
let targetLatestHeight = BlockHeight(663251)
|
let targetLatestHeight = BlockHeight(663251)
|
||||||
let walletBirthday = BlockHeight(663150)
|
let walletBirthday = BlockHeight(663150)
|
||||||
|
let network = DarksideWalletDNetwork()
|
||||||
|
let branchID = "2bb40e60"
|
||||||
|
let chainName = "main"
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
logger = SampleLogger(logLevel: .debug)
|
logger = SampleLogger(logLevel: .debug)
|
||||||
|
|
||||||
|
|
||||||
var config = CompactBlockProcessor.Configuration.standard
|
|
||||||
let rustBackend = ZcashRustBackend.self
|
|
||||||
|
|
||||||
|
|
||||||
let birthday = WalletBirthday.birthday(with: walletBirthday)
|
|
||||||
config.walletBirthday = birthday.height
|
|
||||||
processorConfig = config
|
|
||||||
|
|
||||||
try? FileManager.default.removeItem(at: processorConfig.cacheDb)
|
|
||||||
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
|
||||||
|
|
||||||
_ = rustBackend.initAccountsTable(dbData: processorConfig.dataDb, seed: TestSeed().seed(), accounts: 1)
|
|
||||||
let service = DarksideWalletService()
|
|
||||||
darksideWalletService = service
|
|
||||||
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
|
||||||
try! storage.createTable()
|
|
||||||
|
|
||||||
downloader = CompactBlockDownloader(service: service, storage: storage)
|
|
||||||
processor = CompactBlockProcessor(service: service,
|
|
||||||
storage: storage,
|
|
||||||
backend: rustBackend,
|
|
||||||
config: processorConfig)
|
|
||||||
|
|
||||||
downloadStartedExpect = XCTestExpectation(description: self.description + " downloadStartedExpect")
|
downloadStartedExpect = XCTestExpectation(description: self.description + " downloadStartedExpect")
|
||||||
stopNotificationExpectation = XCTestExpectation(description: self.description + " stopNotificationExpectation")
|
stopNotificationExpectation = XCTestExpectation(description: self.description + " stopNotificationExpectation")
|
||||||
updatedNotificationExpectation = XCTestExpectation(description: self.description + " updatedNotificationExpectation")
|
updatedNotificationExpectation = XCTestExpectation(description: self.description + " updatedNotificationExpectation")
|
||||||
|
@ -66,11 +44,39 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
|
|
||||||
waitExpectation = XCTestExpectation(description: self.description + "waitExpectation")
|
waitExpectation = XCTestExpectation(description: self.description + "waitExpectation")
|
||||||
|
|
||||||
|
let birthday = WalletBirthday.birthday(with: walletBirthday, network: network)
|
||||||
|
|
||||||
|
let config = CompactBlockProcessor.Configuration.standard(for: self.network, walletBirthday: birthday.height)
|
||||||
|
let rustBackend = ZcashRustBackend.self
|
||||||
|
processorConfig = config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try? FileManager.default.removeItem(at: processorConfig.cacheDb)
|
||||||
|
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
||||||
|
|
||||||
|
_ = rustBackend.initAccountsTable(dbData: processorConfig.dataDb, seed: TestSeed().seed(), accounts: 1,networkType: network.networkType)
|
||||||
|
_ = try rustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: network.networkType)
|
||||||
|
_ = try rustBackend.initBlocksTable(dbData: processorConfig.dataDb, height: Int32(birthday.height), hash: birthday.hash, time: birthday.time, saplingTree: birthday.tree, networkType: network.networkType)
|
||||||
|
|
||||||
|
let service = DarksideWalletService()
|
||||||
|
darksideWalletService = service
|
||||||
|
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
||||||
|
try! storage.createTable()
|
||||||
|
|
||||||
|
downloader = CompactBlockDownloader(service: service, storage: storage)
|
||||||
|
processor = CompactBlockProcessor(service: service,
|
||||||
|
storage: storage,
|
||||||
|
backend: rustBackend,
|
||||||
|
config: processorConfig)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(processorFailed(_:)), name: Notification.Name.blockProcessorFailed, object: processor)
|
NotificationCenter.default.addObserver(self, selector: #selector(processorFailed(_:)), name: Notification.Name.blockProcessorFailed, object: processor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDownWithError() throws {
|
override func tearDownWithError() throws {
|
||||||
try! FileManager.default.removeItem(at: processorConfig.cacheDb)
|
try? FileManager.default.removeItem(at: processorConfig.cacheDb)
|
||||||
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
||||||
downloadStartedExpect.unsubscribeFromNotifications()
|
downloadStartedExpect.unsubscribeFromNotifications()
|
||||||
stopNotificationExpectation.unsubscribeFromNotifications()
|
stopNotificationExpectation.unsubscribeFromNotifications()
|
||||||
|
@ -100,7 +106,7 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
func testBasicEnhacement() throws {
|
func testBasicEnhacement() throws {
|
||||||
|
|
||||||
let targetLatestHeight = BlockHeight(663250)
|
let targetLatestHeight = BlockHeight(663250)
|
||||||
let walletBirthday = WalletBirthday.birthday(with: 663151).height
|
let walletBirthday = WalletBirthday.birthday(with: 663151, network: network).height
|
||||||
|
|
||||||
try basicEnhancementTest(latestHeight: targetLatestHeight, walletBirthday: walletBirthday)
|
try basicEnhancementTest(latestHeight: targetLatestHeight, walletBirthday: walletBirthday)
|
||||||
}
|
}
|
||||||
|
@ -108,12 +114,15 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
func basicEnhancementTest(latestHeight: BlockHeight, walletBirthday: BlockHeight) throws {
|
func basicEnhancementTest(latestHeight: BlockHeight, walletBirthday: BlockHeight) throws {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
try darksideWalletService.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName)
|
||||||
try darksideWalletService.useDataset(DarksideDataset.beforeReOrg.rawValue)
|
try darksideWalletService.useDataset(DarksideDataset.beforeReOrg.rawValue)
|
||||||
|
try darksideWalletService.applyStaged(nextLatestHeight: 663200)
|
||||||
} catch {
|
} catch {
|
||||||
XCTFail("Error: \(error)")
|
XCTFail("Error: \(error)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sleep(3)
|
||||||
/**
|
/**
|
||||||
connect to dLWD
|
connect to dLWD
|
||||||
request latest height -> receive firstLatestHeight
|
request latest height -> receive firstLatestHeight
|
||||||
|
@ -124,12 +133,13 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
XCTFail("Error: \(error)")
|
XCTFail("Error: \(error)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
download and sync blocks from walletBirthday to firstLatestHeight
|
download and sync blocks from walletBirthday to firstLatestHeight
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
|
|
||||||
try startProcessing()
|
try startProcessing()
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -155,3 +165,4 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ class WalletTests: XCTestCase {
|
||||||
var dbData: URL! = nil
|
var dbData: URL! = nil
|
||||||
var paramDestination: URL! = nil
|
var paramDestination: URL! = nil
|
||||||
var cacheData: URL! = nil
|
var cacheData: URL! = nil
|
||||||
|
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
|
var seedData: Data = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==")!
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
|
|
||||||
dbData = try! __dataDbURL()
|
dbData = try! __dataDbURL()
|
||||||
|
@ -29,23 +30,30 @@ class WalletTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func testWalletInitialization() {
|
func testWalletInitialization() throws {
|
||||||
//
|
|
||||||
// let wallet = Initializer(cacheDbURL: cacheData,
|
let derivationTool = DerivationTool(networkType: network.networkType)
|
||||||
// dataDbURL: dbData,
|
let uvk = try derivationTool.deriveUnifiedViewingKeysFromSeed(seedData.bytes, numberOfAccounts: 1)
|
||||||
// pendingDbURL: try! TestDbBuilder.pendingTransactionsDbURL(),
|
let wallet = Initializer(cacheDbURL: try __cacheDbURL(),
|
||||||
// endpoint: LightWalletEndpointBuilder.default,
|
dataDbURL: try __dataDbURL(),
|
||||||
// spendParamsURL: try! __spendParamsURL(),
|
pendingDbURL: try TestDbBuilder.pendingTransactionsDbURL(),
|
||||||
// outputParamsURL: try! __outputParamsURL()
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
// )
|
network: network,
|
||||||
//
|
spendParamsURL: try __spendParamsURL(),
|
||||||
// XCTAssertNoThrow(try wallet.initialize(viewingKeys: ["zxviewtestsapling1qwxyzvdmqqqqpqy3knx32fpja779wzg76kmglgguvr74g773f3aw3gy37rar6y9d37knvskz6thnea55s05cz3a7q38835hq4w58yevn763cn2wf7k2mpj247ynxpt9qm0nn39slkz5dk572hxr43pxqtg5kz3pqcj8z8uhz0l2vx8gxe90uf4pgw7ks23f0hz2hm47k9ym42cmns3tenhxzlyur2nvx68h4fmk9nrs44ymcqz434zsuxpvhklrjzn00gc43fdghn5szc5x2w"], walletBirthday: 663194))
|
outputParamsURL: try __outputParamsURL(),
|
||||||
//
|
viewingKeys: uvk,
|
||||||
// // fileExists actually sucks, so attempting to delete the file and checking what happens is far better :)
|
walletBirthday: 663194)
|
||||||
// XCTAssertNoThrow( try FileManager.default.removeItem(at: dbData!) )
|
|
||||||
// // TODO: Initialize cacheDB on start, will be done when Synchronizer is ready and integrated
|
|
||||||
//// XCTAssertNoThrow( try FileManager.default.removeItem(at: cacheData!) )
|
|
||||||
// }
|
let synchronizer = try SDKSynchronizer(initializer: wallet)
|
||||||
|
XCTAssertNoThrow(try synchronizer.prepare())
|
||||||
|
|
||||||
|
// fileExists actually sucks, so attempting to delete the file and checking what happens is far better :)
|
||||||
|
XCTAssertNoThrow( try FileManager.default.removeItem(at: dbData!) )
|
||||||
|
// TODO: Initialize cacheDB on start, will be done when Synchronizer is ready and integrated
|
||||||
|
// XCTAssertNoThrow( try FileManager.default.removeItem(at: cacheData!) )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WalletBirthdayProvider {
|
struct WalletBirthdayProvider {
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ZcashLightClientKitTests: XCTestCase {
|
||||||
var service: LightWalletGRPCService!
|
var service: LightWalletGRPCService!
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
service = LightWalletGRPCService(endpoint: LightWalletEndpoint(address: Constants.address, port: 9067))
|
||||||
|
|
||||||
latestBlockHeight = try! service.latestBlock().compactBlockHeight()!
|
latestBlockHeight = try! service.latestBlock().compactBlockHeight()!
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
let spendingKey = "secret-extended-key-test1qvpevftsqqqqpqy52ut2vv24a2qh7nsukew7qg9pq6djfwyc3xt5vaxuenshp2hhspp9qmqvdh0gs2ljpwxders5jkwgyhgln0drjqaguaenfhehz4esdl4kwlm5t9q0l6wmzcrvcf5ed6dqzvct3e2ge7f6qdvzhp02m7sp5a0qjssrwpdh7u6tq89hl3wchuq8ljq8r8rwd6xdwh3nry9at80z7amnj3s6ah4jevnvfr08gxpws523z95g6dmn4wm6l3658kd4xcq9rc0qn"
|
let spendingKey = "secret-extended-key-test1qvpevftsqqqqpqy52ut2vv24a2qh7nsukew7qg9pq6djfwyc3xt5vaxuenshp2hhspp9qmqvdh0gs2ljpwxders5jkwgyhgln0drjqaguaenfhehz4esdl4kwlm5t9q0l6wmzcrvcf5ed6dqzvct3e2ge7f6qdvzhp02m7sp5a0qjssrwpdh7u6tq89hl3wchuq8ljq8r8rwd6xdwh3nry9at80z7amnj3s6ah4jevnvfr08gxpws523z95g6dmn4wm6l3658kd4xcq9rc0qn"
|
||||||
let recipientAddress = "ztestsapling1ctuamfer5xjnnrdr3xdazenljx0mu0gutcf9u9e74tr2d3jwjnt0qllzxaplu54hgc2tyjdc2p6"
|
let recipientAddress = "ztestsapling1ctuamfer5xjnnrdr3xdazenljx0mu0gutcf9u9e74tr2d3jwjnt0qllzxaplu54hgc2tyjdc2p6"
|
||||||
let zpend: Int = 500_000
|
let zpend: Int = 500_000
|
||||||
|
|
||||||
|
let networkType = NetworkType.testnet
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
dbData = try! __dataDbURL()
|
dbData = try! __dataDbURL()
|
||||||
try? dataDbHandle.setUp()
|
try? dataDbHandle.setUp()
|
||||||
|
@ -30,9 +33,9 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
func testInitWithShortSeedAndFail() {
|
func testInitWithShortSeedAndFail() {
|
||||||
let seed = "testreferencealice"
|
let seed = "testreferencealice"
|
||||||
|
|
||||||
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!))
|
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!, networkType: networkType))
|
||||||
|
|
||||||
let _ = ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1)
|
let _ = ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1, networkType: networkType)
|
||||||
XCTAssertNotNil(ZcashRustBackend.getLastError())
|
XCTAssertNotNil(ZcashRustBackend.getLastError())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,7 +44,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
let seed = Array("testreferencealicetestreferencealice".utf8)
|
let seed = Array("testreferencealicetestreferencealice".utf8)
|
||||||
|
|
||||||
var spendingKeys: [String]? = nil
|
var spendingKeys: [String]? = nil
|
||||||
XCTAssertNoThrow(try { spendingKeys = try ZcashRustBackend.deriveExtendedSpendingKeys(seed: seed, accounts: 1) }())
|
XCTAssertNoThrow(try { spendingKeys = try ZcashRustBackend.deriveExtendedSpendingKeys(seed: seed, accounts: 1, networkType: networkType) }())
|
||||||
|
|
||||||
XCTAssertNotNil(spendingKeys)
|
XCTAssertNotNil(spendingKeys)
|
||||||
XCTAssertFalse(spendingKeys?.first?.isEmpty ?? true)
|
XCTAssertFalse(spendingKeys?.first?.isEmpty ?? true)
|
||||||
|
@ -52,7 +55,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
let seed = Array("testreferencealicetestreferencealice".utf8)
|
let seed = Array("testreferencealicetestreferencealice".utf8)
|
||||||
|
|
||||||
var fullViewingKeys: [String]? = nil
|
var fullViewingKeys: [String]? = nil
|
||||||
XCTAssertNoThrow(try { fullViewingKeys = try ZcashRustBackend.deriveExtendedFullViewingKeys(seed: seed, accounts: 1) }())
|
XCTAssertNoThrow(try { fullViewingKeys = try ZcashRustBackend.deriveExtendedFullViewingKeys(seed: seed, accounts: 1, networkType: networkType) }())
|
||||||
|
|
||||||
XCTAssertNotNil(fullViewingKeys)
|
XCTAssertNotNil(fullViewingKeys)
|
||||||
XCTAssertFalse(fullViewingKeys?.first?.isEmpty ?? true)
|
XCTAssertFalse(fullViewingKeys?.first?.isEmpty ?? true)
|
||||||
|
@ -64,7 +67,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
|
|
||||||
|
|
||||||
var spendingKeys: [String]? = nil
|
var spendingKeys: [String]? = nil
|
||||||
XCTAssertNoThrow(try { spendingKeys = try ZcashRustBackend.deriveExtendedSpendingKeys(seed: seed, accounts: 1) }())
|
XCTAssertNoThrow(try { spendingKeys = try ZcashRustBackend.deriveExtendedSpendingKeys(seed: seed, accounts: 1, networkType: networkType) }())
|
||||||
|
|
||||||
XCTAssertNotNil(spendingKeys)
|
XCTAssertNotNil(spendingKeys)
|
||||||
XCTAssertFalse(spendingKeys?.first?.isEmpty ?? true)
|
XCTAssertFalse(spendingKeys?.first?.isEmpty ?? true)
|
||||||
|
@ -74,7 +77,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertNoThrow(try { fullViewingKey = try ZcashRustBackend.deriveExtendedFullViewingKey(spendingKey) }())
|
XCTAssertNoThrow(try { fullViewingKey = try ZcashRustBackend.deriveExtendedFullViewingKey(spendingKey, networkType: networkType) }())
|
||||||
|
|
||||||
XCTAssertNotNil(fullViewingKey)
|
XCTAssertNotNil(fullViewingKey)
|
||||||
XCTAssertFalse(fullViewingKey?.isEmpty ?? true)
|
XCTAssertFalse(fullViewingKey?.isEmpty ?? true)
|
||||||
|
@ -86,24 +89,24 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let seed = "testreferencealicetestreferencealice"
|
let seed = "testreferencealicetestreferencealice"
|
||||||
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!))
|
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!, networkType: networkType))
|
||||||
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
||||||
|
|
||||||
XCTAssertNotNil(ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1))
|
XCTAssertNotNil(ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1, networkType: networkType))
|
||||||
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
||||||
|
|
||||||
let addr = ZcashRustBackend.getAddress(dbData: dbData!, account: 0)
|
let addr = ZcashRustBackend.getAddress(dbData: dbData!, account: 0, networkType: networkType)
|
||||||
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
||||||
XCTAssertEqual(addr, Optional("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc"))
|
XCTAssertEqual(addr, Optional("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc"))
|
||||||
|
|
||||||
XCTAssertTrue(ZcashRustBackend.scanBlocks(dbCache: cacheDb, dbData: dbData))
|
XCTAssertTrue(ZcashRustBackend.scanBlocks(dbCache: cacheDb, dbData: dbData, networkType: networkType))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIsValidTransparentAddressFalse() {
|
func testIsValidTransparentAddressFalse() {
|
||||||
var isValid: Bool? = nil
|
var isValid: Bool? = nil
|
||||||
|
|
||||||
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidTransparentAddress("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc") }())
|
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidTransparentAddress("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc", networkType: networkType) }())
|
||||||
|
|
||||||
if let valid = isValid {
|
if let valid = isValid {
|
||||||
XCTAssertFalse(valid)
|
XCTAssertFalse(valid)
|
||||||
|
@ -117,7 +120,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
func testIsValidTransparentAddressTrue() {
|
func testIsValidTransparentAddressTrue() {
|
||||||
var isValid: Bool? = nil
|
var isValid: Bool? = nil
|
||||||
|
|
||||||
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidTransparentAddress("tmSwpioc7reeoNrYB9SKpWkurJz3yEj3ee7") }())
|
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidTransparentAddress("tmSwpioc7reeoNrYB9SKpWkurJz3yEj3ee7", networkType: networkType) }())
|
||||||
|
|
||||||
if let valid = isValid {
|
if let valid = isValid {
|
||||||
XCTAssertTrue(valid)
|
XCTAssertTrue(valid)
|
||||||
|
@ -129,7 +132,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
func testIsValidShieldedAddressTrue() {
|
func testIsValidShieldedAddressTrue() {
|
||||||
var isValid: Bool? = nil
|
var isValid: Bool? = nil
|
||||||
|
|
||||||
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidShieldedAddress("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc") }())
|
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidShieldedAddress("ztestsapling12k9m98wmpjts2m56wc60qzhgsfvlpxcwah268xk5yz4h942sd58jy3jamqyxjwums6hw7kfa4cc", networkType: networkType) }())
|
||||||
|
|
||||||
if let valid = isValid {
|
if let valid = isValid {
|
||||||
XCTAssertTrue(valid)
|
XCTAssertTrue(valid)
|
||||||
|
@ -141,7 +144,7 @@ class ZcashRustBackendTests: XCTestCase {
|
||||||
func testIsValidShieldedAddressFalse() {
|
func testIsValidShieldedAddressFalse() {
|
||||||
var isValid: Bool? = nil
|
var isValid: Bool? = nil
|
||||||
|
|
||||||
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidShieldedAddress("tmSwpioc7reeoNrYB9SKpWkurJz3yEj3ee7") }())
|
XCTAssertNoThrow(try { isValid = try ZcashRustBackend.isValidShieldedAddress("tmSwpioc7reeoNrYB9SKpWkurJz3yEj3ee7", networkType: networkType) }())
|
||||||
|
|
||||||
if let valid = isValid {
|
if let valid = isValid {
|
||||||
XCTAssertFalse(valid)
|
XCTAssertFalse(valid)
|
||||||
|
|
|
@ -199,3 +199,38 @@ class DarksideWalletService: LightWalletService {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DarksideWalletDConstants: NetworkConstants {
|
||||||
|
static var SAPLING_ACTIVATION_HEIGHT: BlockHeight {
|
||||||
|
663150
|
||||||
|
}
|
||||||
|
|
||||||
|
static var DEFAULT_DATA_DB_NAME: String {
|
||||||
|
ZcashSDKMainnetConstants.DEFAULT_DATA_DB_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
static var DEFAULT_CACHES_DB_NAME: String {
|
||||||
|
ZcashSDKMainnetConstants.DEFAULT_CACHES_DB_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
static var DEFAULT_PENDING_DB_NAME: String {
|
||||||
|
ZcashSDKMainnetConstants.DEFAULT_PENDING_DB_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
static var DEFAULT_DB_NAME_PREFIX: String {
|
||||||
|
ZcashSDKMainnetConstants.DEFAULT_DB_NAME_PREFIX
|
||||||
|
}
|
||||||
|
|
||||||
|
static var FEE_CHANGE_HEIGHT: BlockHeight {
|
||||||
|
ZcashSDKMainnetConstants.FEE_CHANGE_HEIGHT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
class DarksideWalletDNetwork: ZcashNetwork {
|
||||||
|
var constants: NetworkConstants.Type = DarksideWalletDConstants.self
|
||||||
|
|
||||||
|
var networkType = NetworkType.mainnet
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -68,13 +68,15 @@ class MockLightWalletService: LightWalletService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var service = LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
|
private var service: LightWalletService
|
||||||
|
|
||||||
var latestHeight: BlockHeight
|
var latestHeight: BlockHeight
|
||||||
|
|
||||||
init(latestBlockHeight: BlockHeight) {
|
init(latestBlockHeight: BlockHeight, service: LightWalletService) {
|
||||||
self.latestHeight = latestBlockHeight
|
self.latestHeight = latestBlockHeight
|
||||||
|
self.service = service
|
||||||
}
|
}
|
||||||
|
|
||||||
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
|
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
|
||||||
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
|
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
|
||||||
result(.success(self.latestHeight))
|
result(.success(self.latestHeight))
|
||||||
|
|
|
@ -44,10 +44,15 @@ class MockTransactionRepository: TransactionRepository {
|
||||||
receivedCount + sentCount
|
receivedCount + sentCount
|
||||||
}
|
}
|
||||||
|
|
||||||
init(unminedCount: Int, receivedCount: Int, sentCount: Int) {
|
var network: ZcashNetwork
|
||||||
|
init(unminedCount: Int,
|
||||||
|
receivedCount: Int,
|
||||||
|
sentCount: Int,
|
||||||
|
network: ZcashNetwork) {
|
||||||
self.unminedCount = unminedCount
|
self.unminedCount = unminedCount
|
||||||
self.receivedCount = receivedCount
|
self.receivedCount = receivedCount
|
||||||
self.sentCount = sentCount
|
self.sentCount = sentCount
|
||||||
|
self.network = network
|
||||||
}
|
}
|
||||||
|
|
||||||
func generate() {
|
func generate() {
|
||||||
|
@ -148,7 +153,7 @@ class MockTransactionRepository: TransactionRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomBlockHeight() -> BlockHeight {
|
func randomBlockHeight() -> BlockHeight {
|
||||||
BlockHeight.random(in: ZcashSDK.SAPLING_ACTIVATION_HEIGHT ... 1_000_000)
|
BlockHeight.random(in: network.constants.SAPLING_ACTIVATION_HEIGHT ... 1_000_000)
|
||||||
}
|
}
|
||||||
func randomTimeInterval() -> TimeInterval {
|
func randomTimeInterval() -> TimeInterval {
|
||||||
Double.random(in: Date().timeIntervalSince1970 - 1000000.0 ... Date().timeIntervalSince1970)
|
Double.random(in: Date().timeIntervalSince1970 - 1000000.0 ... Date().timeIntervalSince1970)
|
||||||
|
|
|
@ -77,104 +77,108 @@ extension LightWalletServiceMockResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockRustBackend: ZcashRustBackendWelding {
|
class MockRustBackend: ZcashRustBackendWelding {
|
||||||
|
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight, networkType: NetworkType) throws -> Int32 {
|
||||||
static func getNearestRewindHeight(dbData: URL, height: Int32) -> Int32 {
|
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight) throws -> Int32 {
|
|
||||||
|
static func getNearestRewindHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Int32 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey]) throws -> Bool {
|
static func network(dbData: URL, address: String, sinceHeight: BlockHeight, networkType: NetworkType) throws -> Int32 {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
|
||||||
|
static func initAccountsTable(dbData: URL, uvks: [UnifiedViewingKey], networkType: NetworkType) throws -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getVerifiedTransparentBalance(dbData: URL, address: String) throws -> Int64 {
|
static func getVerifiedTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getTransparentBalance(dbData: URL, address: String) throws -> Int64 {
|
static func getTransparentBalance(dbData: URL, address: String, networkType: NetworkType) throws -> Int64 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight) throws -> Bool {
|
static func putUnspentTransparentOutput(dbData: URL, address: String, txid: [UInt8], index: Int, script: [UInt8], value: Int64, height: BlockHeight, networkType: NetworkType) throws -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
static func downloadedUtxoBalance(dbData: URL, address: String) throws -> WalletBalance {
|
static func downloadedUtxoBalance(dbData: URL, address: String, networkType: NetworkType) throws -> WalletBalance {
|
||||||
throw RustWeldingError.genericError(message: "unimplemented")
|
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 {
|
static func createToAddress(dbData: URL, account: Int32, extsk: String, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64 {
|
static func shieldFunds(dbCache: URL, dbData: URL, account: Int32, tsk: String, extsk: String, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String? {
|
static func deriveTransparentAddressFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String? {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int) throws -> String? {
|
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], account: Int, index: Int, networkType: NetworkType) throws -> String? {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSecretKey(_ tsk: String) throws -> String? {
|
static func deriveTransparentAddressFromSecretKey(_ tsk: String, networkType: NetworkType) throws -> String? {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
|
|
||||||
static func derivedTransparentAddressFromPublicKey(_ pubkey: String) throws -> String {
|
static func derivedTransparentAddressFromPublicKey(_ pubkey: String, networkType: NetworkType) throws -> String {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int) throws -> [UnifiedViewingKey] {
|
static func deriveUnifiedViewingKeyFromSeed(_ seed: [UInt8], numberOfAccounts: Int, networkType: NetworkType) throws -> [UnifiedViewingKey] {
|
||||||
throw KeyDerivationErrors.unableToDerive
|
throw KeyDerivationErrors.unableToDerive
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidExtendedFullViewingKey(_ key: String) throws -> Bool {
|
static func isValidExtendedFullViewingKey(_ key: String, networkType: NetworkType) throws -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8]) throws -> String? {
|
static func deriveTransparentPrivateKeyFromSeed(seed: [UInt8], networkType: NetworkType) throws -> String? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initAccountsTable(dbData: URL, exfvks: [String]) throws -> Bool {
|
static func initAccountsTable(dbData: URL, exfvks: [String], networkType: NetworkType) throws -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveTransparentAddressFromSeed(seed: [UInt8]) throws -> String? {
|
static func deriveTransparentAddressFromSeed(seed: [UInt8], networkType: NetworkType) throws -> String? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32) throws -> [String]? {
|
static func deriveExtendedFullViewingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32) throws -> [String]? {
|
static func deriveExtendedSpendingKeys(seed: [UInt8], accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32) throws -> String? {
|
static func deriveShieldedAddressFromSeed(seed: [UInt8], accountIndex: Int32, networkType: NetworkType) throws -> String? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveShieldedAddressFromViewingKey(_ extfvk: String) throws -> String? {
|
static func deriveShieldedAddressFromViewingKey(_ extfvk: String, networkType: NetworkType) throws -> String? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static func consensusBranchIdFor(height: Int32) throws -> Int32 {
|
static func consensusBranchIdFor(height: Int32, networkType: NetworkType) throws -> Int32 {
|
||||||
guard let c = consensusBranchID else {
|
guard let c = consensusBranchID else {
|
||||||
return try rustBackend.consensusBranchIdFor(height: height)
|
return try rustBackend.consensusBranchIdFor(height: height, networkType: networkType)
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var networkType = NetworkType.testnet
|
||||||
static var mockDataDb = false
|
static var mockDataDb = false
|
||||||
static var mockAcounts = false
|
static var mockAcounts = false
|
||||||
static var mockError: RustWeldingError?
|
static var mockError: RustWeldingError?
|
||||||
|
@ -202,61 +206,61 @@ class MockRustBackend: ZcashRustBackendWelding {
|
||||||
mockLastError ?? rustBackend.getLastError()
|
mockLastError ?? rustBackend.getLastError()
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidShieldedAddress(_ address: String) throws -> Bool {
|
static func isValidShieldedAddress(_ address: String, networkType: NetworkType) throws -> Bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func isValidTransparentAddress(_ address: String) throws -> Bool {
|
static func isValidTransparentAddress(_ address: String, networkType: NetworkType) throws -> Bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initDataDb(dbData: URL) throws {
|
static func initDataDb(dbData: URL, networkType: NetworkType) throws {
|
||||||
if !mockDataDb {
|
if !mockDataDb {
|
||||||
try rustBackend.initDataDb(dbData: dbData)
|
try rustBackend.initDataDb(dbData: dbData, networkType: networkType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32) -> [String]? {
|
static func initAccountsTable(dbData: URL, seed: [UInt8], accounts: Int32, networkType: NetworkType) -> [String]? {
|
||||||
mockAccounts ?? rustBackend.initAccountsTable(dbData: dbData, seed: seed, accounts: accounts)
|
mockAccounts ?? rustBackend.initAccountsTable(dbData: dbData, seed: seed, accounts: accounts, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String) throws {
|
static func initBlocksTable(dbData: URL, height: Int32, hash: String, time: UInt32, saplingTree: String, networkType: NetworkType) throws {
|
||||||
if !mockDataDb {
|
if !mockDataDb {
|
||||||
try rustBackend.initBlocksTable(dbData: dbData, height: height, hash: hash, time: time, saplingTree: saplingTree)
|
try rustBackend.initBlocksTable(dbData: dbData, height: height, hash: hash, time: time, saplingTree: saplingTree, networkType: networkType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getAddress(dbData: URL, account: Int32) -> String? {
|
static func getAddress(dbData: URL, account: Int32, networkType: NetworkType) -> String? {
|
||||||
mockAddresses?[Int(account)] ?? rustBackend.getAddress(dbData: dbData, account: account)
|
mockAddresses?[Int(account)] ?? rustBackend.getAddress(dbData: dbData, account: account, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getBalance(dbData: URL, account: Int32) -> Int64 {
|
static func getBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64 {
|
||||||
mockBalance ?? rustBackend.getBalance(dbData: dbData, account: account)
|
mockBalance ?? rustBackend.getBalance(dbData: dbData, account: account, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getVerifiedBalance(dbData: URL, account: Int32) -> Int64 {
|
static func getVerifiedBalance(dbData: URL, account: Int32, networkType: NetworkType) -> Int64 {
|
||||||
mockVerifiedBalance ?? rustBackend.getVerifiedBalance(dbData: dbData, account: account)
|
mockVerifiedBalance ?? rustBackend.getVerifiedBalance(dbData: dbData, account: account, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
|
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String? {
|
||||||
mockMemo ?? rustBackend.getReceivedMemoAsUTF8(dbData: dbData, idNote: idNote)
|
mockMemo ?? rustBackend.getReceivedMemoAsUTF8(dbData: dbData, idNote: idNote, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
|
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64, networkType: NetworkType) -> String? {
|
||||||
mockSentMemo ?? getSentMemoAsUTF8(dbData: dbData, idNote: idNote)
|
mockSentMemo ?? getSentMemoAsUTF8(dbData: dbData, idNote: idNote, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func validateCombinedChain(dbCache: URL, dbData: URL) -> Int32 {
|
static func validateCombinedChain(dbCache: URL, dbData: URL, networkType: NetworkType) -> Int32 {
|
||||||
if let rate = self.mockValidateCombinedChainSuccessRate {
|
if let rate = self.mockValidateCombinedChainSuccessRate {
|
||||||
if shouldSucceed(successRate: rate) {
|
if shouldSucceed(successRate: rate) {
|
||||||
return validationResult(dbCache: dbCache, dbData: dbData)
|
return validationResult(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
} else {
|
} else {
|
||||||
return Int32(mockValidateCombinedChainFailureHeight)
|
return Int32(mockValidateCombinedChainFailureHeight)
|
||||||
}
|
}
|
||||||
} else if let attempts = self.mockValidateCombinedChainFailAfterAttempts {
|
} else if let attempts = self.mockValidateCombinedChainFailAfterAttempts {
|
||||||
self.mockValidateCombinedChainFailAfterAttempts = attempts - 1
|
self.mockValidateCombinedChainFailAfterAttempts = attempts - 1
|
||||||
if attempts > 0 {
|
if attempts > 0 {
|
||||||
return validationResult(dbCache: dbCache, dbData: dbData)
|
return validationResult(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if attempts == 0 {
|
if attempts == 0 {
|
||||||
|
@ -264,38 +268,38 @@ class MockRustBackend: ZcashRustBackendWelding {
|
||||||
} else if attempts < 0 && mockValidateCombinedChainKeepFailing {
|
} else if attempts < 0 && mockValidateCombinedChainKeepFailing {
|
||||||
return Int32(mockValidateCombinedChainFailureHeight)
|
return Int32(mockValidateCombinedChainFailureHeight)
|
||||||
} else {
|
} else {
|
||||||
return validationResult(dbCache: dbCache, dbData: dbData)
|
return validationResult(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rustBackend.validateCombinedChain(dbCache: dbCache, dbData: dbData)
|
return rustBackend.validateCombinedChain(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func validationResult(dbCache: URL, dbData: URL) -> Int32{
|
private static func validationResult(dbCache: URL, dbData: URL, networkType: NetworkType) -> Int32{
|
||||||
if mockDataDb {
|
if mockDataDb {
|
||||||
return -1
|
return -1
|
||||||
} else {
|
} else {
|
||||||
return rustBackend.validateCombinedChain(dbCache: dbCache, dbData: dbData)
|
return rustBackend.validateCombinedChain(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func rewindToHeight(dbData: URL, height: Int32) -> Bool {
|
static func rewindToHeight(dbData: URL, height: Int32, networkType: NetworkType) -> Bool {
|
||||||
mockDataDb ? true : rustBackend.rewindToHeight(dbData: dbData, height: height)
|
mockDataDb ? true : rustBackend.rewindToHeight(dbData: dbData, height: height, networkType: networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32) -> Bool {
|
static func scanBlocks(dbCache: URL, dbData: URL, limit: UInt32, networkType: NetworkType) -> Bool {
|
||||||
if let rate = mockScanblocksSuccessRate {
|
if let rate = mockScanblocksSuccessRate {
|
||||||
|
|
||||||
if shouldSucceed(successRate: rate) {
|
if shouldSucceed(successRate: rate) {
|
||||||
return mockDataDb ? true : rustBackend.scanBlocks(dbCache: dbCache, dbData: dbData)
|
return mockDataDb ? true : rustBackend.scanBlocks(dbCache: dbCache, dbData: dbData, networkType: networkType)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rustBackend.scanBlocks(dbCache: dbCache, dbData: dbData)
|
return rustBackend.scanBlocks(dbCache: dbCache, dbData: dbData, networkType: Self.networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func createToAddress(dbData: URL, account: Int32, extsk: String, consensusBranchId: Int32, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String) -> Int64 {
|
static func createToAddress(dbData: URL, account: Int32, extsk: String, consensusBranchId: Int32, to: String, value: Int64, memo: String?, spendParamsPath: String, outputParamsPath: String, networkType: NetworkType) -> Int64 {
|
||||||
// mockCreateToAddress ?? rustBackend.createToAddress(dbData: dbData, account: account, extsk: extsk, consensusBranchId: consensusBranchId, to: to, value: value, memo: memo, spendParamsPath: spendParamsPath, outputParamsPath: outputParamsPath)
|
// mockCreateToAddress ?? rustBackend.createToAddress(dbData: dbData, account: account, extsk: extsk, consensusBranchId: consensusBranchId, to: to, value: value, memo: memo, spendParamsPath: spendParamsPath, outputParamsPath: outputParamsPath)
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
@ -305,19 +309,19 @@ class MockRustBackend: ZcashRustBackendWelding {
|
||||||
return random <= successRate
|
return random <= successRate
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedFullViewingKey(_ spendingKey: String) throws -> String? {
|
static func deriveExtendedFullViewingKey(_ spendingKey: String, networkType: NetworkType) throws -> String? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedFullViewingKeys(seed: String, accounts: Int32) throws -> [String]? {
|
static func deriveExtendedFullViewingKeys(seed: String, accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deriveExtendedSpendingKeys(seed: String, accounts: Int32) throws -> [String]? {
|
static func deriveExtendedSpendingKeys(seed: String, accounts: Int32, networkType: NetworkType) throws -> [String]? {
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8]) -> Bool {
|
static func decryptAndStoreTransaction(dbData: URL, tx: [UInt8], networkType: NetworkType) -> Bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,14 @@ class LightWalletEndpointBuilder {
|
||||||
static var `default`: LightWalletEndpoint {
|
static var `default`: LightWalletEndpoint {
|
||||||
LightWalletEndpoint(address: Constants.address, port: 9067, secure: false)
|
LightWalletEndpoint(address: Constants.address, port: 9067, secure: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static var publicTestnet: LightWalletEndpoint {
|
||||||
|
LightWalletEndpoint(address: "testnet.lightwalletd.com", port: 9067, secure: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
static var eccTestnet: LightWalletEndpoint {
|
||||||
|
LightWalletEndpoint(address: "lightwalletd.testnet.electriccoin.co", port: 9067, secure: true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChannelProvider {
|
class ChannelProvider {
|
||||||
|
|
47
changelog.md
47
changelog.md
|
@ -1,3 +1,50 @@
|
||||||
|
# 0.12.0-alpha.11
|
||||||
|
* [Enhancement] Network Agnostic build
|
||||||
|
|
||||||
|
# 0.12.0-alpha.10
|
||||||
|
* Fix: UNIQUE Constraint bug when coming from background. fixed and logged warning to keep investigating
|
||||||
|
* [New] latestScannedHeight added to SDKSynchronizer
|
||||||
|
|
||||||
|
# 0.12.0-alpha.9
|
||||||
|
* CompactBlockProcessor states don't propagate correctly
|
||||||
|
|
||||||
|
# 0.12.0-alpha.8
|
||||||
|
* target height reporting enhancements
|
||||||
|
|
||||||
|
# 0.12.0-alpha.7
|
||||||
|
* improve status publishing for SDKSynchronizer
|
||||||
|
* [FIX] missingStartHeight error when scanning from sapling activation
|
||||||
|
|
||||||
|
# 0.12.0-alpha.6
|
||||||
|
* Make sapling parameters default url public
|
||||||
|
|
||||||
|
# 0.12.0-alpha.5
|
||||||
|
* add output files to build phase to avoid CI failures
|
||||||
|
* fix lint warnings
|
||||||
|
|
||||||
|
# 0.12.0-alpha.4
|
||||||
|
* Tests
|
||||||
|
* [Fix] Issue #289 main thread lock when validating the server
|
||||||
|
* [Fix] info single call times out all the time
|
||||||
|
* make sure operations cancel in a timely manner
|
||||||
|
* FigureNextBatchOperation.swift tests
|
||||||
|
* make range function static
|
||||||
|
|
||||||
|
# tag: 0.12.0-alpha.3
|
||||||
|
* getInfo service times out too soon
|
||||||
|
# 0.12.0-alpha.2
|
||||||
|
* FIX: processor stalls on reconnection
|
||||||
|
* Fix warnings
|
||||||
|
# 0.12.0-alpha.1
|
||||||
|
* Replace Status for SyncStatus
|
||||||
|
* fix tests
|
||||||
|
* Fix Demo App
|
||||||
|
* fetch operation does not cancel when the previous operations do
|
||||||
|
* Fix: operations start when they have been canceled already
|
||||||
|
* fix progress being > 1
|
||||||
|
* Synchronizing by phases, preview
|
||||||
|
* Add fetch UTXO operation to compact block processor
|
||||||
|
* CompactBlock batch download and stream download operation tests pass.
|
||||||
# 0.11.1
|
# 0.11.1
|
||||||
* [Enhancement] Rewind API has a `.quick` option
|
* [Enhancement] Rewind API has a `.quick` option
|
||||||
# 0.11.0
|
# 0.11.0
|
||||||
|
|
403
rust/src/lib.rs
403
rust/src/lib.rs
|
@ -11,7 +11,7 @@ use zcash_client_backend::{
|
||||||
data_api::{
|
data_api::{
|
||||||
chain::{scan_cached_blocks, validate_chain},
|
chain::{scan_cached_blocks, validate_chain},
|
||||||
error::Error,
|
error::Error,
|
||||||
wallet::{create_spend_to_address, decrypt_and_store_transaction, shield_funds, ANCHOR_OFFSET},
|
wallet::{create_spend_to_address, decrypt_and_store_transaction, shield_funds},
|
||||||
WalletRead,
|
WalletRead,
|
||||||
},
|
},
|
||||||
encoding::{
|
encoding::{
|
||||||
|
@ -43,17 +43,13 @@ use zcash_client_sqlite::{
|
||||||
};
|
};
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
block::BlockHash,
|
block::BlockHash,
|
||||||
consensus::{BlockHeight, BranchId, Parameters},
|
consensus::{BlockHeight, BranchId, Network, Parameters},
|
||||||
memo::{Memo, MemoBytes},
|
memo::{Memo, MemoBytes},
|
||||||
transaction::{components::Amount, components::OutPoint, Transaction},
|
transaction::{components::Amount, components::OutPoint, Transaction},
|
||||||
zip32::ExtendedFullViewingKey,
|
zip32::ExtendedFullViewingKey,
|
||||||
legacy::TransparentAddress,
|
legacy::TransparentAddress,
|
||||||
};
|
};
|
||||||
|
use zcash_primitives::consensus::Network::{MainNetwork, TestNetwork};
|
||||||
#[cfg(feature = "mainnet")]
|
|
||||||
use zcash_primitives::consensus::{MainNetwork, MAIN_NETWORK};
|
|
||||||
#[cfg(not(feature = "mainnet"))]
|
|
||||||
use zcash_primitives::consensus::{TestNetwork, TEST_NETWORK};
|
|
||||||
|
|
||||||
use zcash_proofs::prover::LocalTxProver;
|
use zcash_proofs::prover::LocalTxProver;
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
@ -78,37 +74,21 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mainnet")]
|
|
||||||
pub const NETWORK: MainNetwork = MAIN_NETWORK;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mainnet"))]
|
|
||||||
pub const NETWORK: TestNetwork = TEST_NETWORK;
|
|
||||||
|
|
||||||
#[cfg(feature = "mainnet")]
|
|
||||||
fn wallet_db(
|
fn wallet_db(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
) -> Result<WalletDb<MainNetwork>, failure::Error> {
|
network: Network,
|
||||||
|
) -> Result<WalletDb<Network>, failure::Error> {
|
||||||
let db_data = Path::new(OsStr::from_bytes(unsafe {
|
let db_data = Path::new(OsStr::from_bytes(unsafe {
|
||||||
slice::from_raw_parts(db_data, db_data_len)
|
slice::from_raw_parts(db_data, db_data_len)
|
||||||
}));
|
}));
|
||||||
WalletDb::for_path(db_data, NETWORK)
|
WalletDb::for_path(db_data, network)
|
||||||
.map_err(|e| format_err!("Error opening wallet database connection: {}", e))
|
.map_err(|e| format_err!("Error opening wallet database connection: {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mainnet"))]
|
fn block_db(cache_db: *const u8,
|
||||||
fn wallet_db(
|
cache_db_len: usize) -> Result<BlockDb, failure::Error> {
|
||||||
db_data: *const u8,
|
|
||||||
db_data_len: usize,
|
|
||||||
) -> Result<WalletDb<TestNetwork>, failure::Error> {
|
|
||||||
let db_data = Path::new(OsStr::from_bytes(unsafe {
|
|
||||||
slice::from_raw_parts(db_data, db_data_len)
|
|
||||||
}));
|
|
||||||
WalletDb::for_path(db_data, NETWORK)
|
|
||||||
.map_err(|e| format_err!("Error opening wallet database connection: {}", e))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_db(cache_db: *const u8, cache_db_len: usize) -> Result<BlockDb, failure::Error> {
|
|
||||||
let cache_db = Path::new(OsStr::from_bytes(unsafe {
|
let cache_db = Path::new(OsStr::from_bytes(unsafe {
|
||||||
slice::from_raw_parts(cache_db, cache_db_len)
|
slice::from_raw_parts(cache_db, cache_db_len)
|
||||||
}));
|
}));
|
||||||
|
@ -136,13 +116,18 @@ pub extern "C" fn zcashlc_clear_last_error() {
|
||||||
|
|
||||||
/// Sets up the internal structure of the data database.
|
/// Sets up the internal structure of the data database.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn zcashlc_init_data_database(db_data: *const u8, db_data_len: usize) -> i32 {
|
pub extern "C" fn zcashlc_init_data_database(
|
||||||
|
db_data: *const u8,
|
||||||
|
db_data_len: usize,
|
||||||
|
network_id: u32,
|
||||||
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let db_data = Path::new(OsStr::from_bytes(unsafe {
|
let db_data = Path::new(OsStr::from_bytes(unsafe {
|
||||||
slice::from_raw_parts(db_data, db_data_len)
|
slice::from_raw_parts(db_data, db_data_len)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
WalletDb::for_path(db_data, NETWORK)
|
WalletDb::for_path(db_data, network)
|
||||||
.map(|db| init_wallet_db(&db))
|
.map(|db| init_wallet_db(&db))
|
||||||
.map(|_| 1)
|
.map(|_| 1)
|
||||||
.map_err(|e| format_err!("Error while initializing data DB: {}", e))
|
.map_err(|e| format_err!("Error while initializing data DB: {}", e))
|
||||||
|
@ -164,9 +149,11 @@ pub extern "C" fn zcashlc_init_accounts_table(
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
accounts: i32,
|
accounts: i32,
|
||||||
capacity_ret: *mut usize,
|
capacity_ret: *mut usize,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut *mut c_char {
|
) -> *mut *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let seed = unsafe { slice::from_raw_parts(seed, seed_len) };
|
let seed = unsafe { slice::from_raw_parts(seed, seed_len) };
|
||||||
let accounts = if accounts >= 0 {
|
let accounts = if accounts >= 0 {
|
||||||
accounts as u32
|
accounts as u32
|
||||||
|
@ -175,13 +162,13 @@ pub extern "C" fn zcashlc_init_accounts_table(
|
||||||
};
|
};
|
||||||
|
|
||||||
let extsks: Vec<_> = (0..accounts)
|
let extsks: Vec<_> = (0..accounts)
|
||||||
.map(|account| spending_key(&seed, NETWORK.coin_type(), AccountId(account)))
|
.map(|account| spending_key(&seed, network.coin_type(), AccountId(account)))
|
||||||
.collect();
|
.collect();
|
||||||
let extfvks: Vec<_> = extsks.iter().map(ExtendedFullViewingKey::from).collect();
|
let extfvks: Vec<_> = extsks.iter().map(ExtendedFullViewingKey::from).collect();
|
||||||
|
|
||||||
let t_addreses: Vec<_> = (0..accounts)
|
let t_addreses: Vec<_> = (0..accounts)
|
||||||
.map(|account| {
|
.map(|account| {
|
||||||
let tsk = derive_secret_key_from_seed(&NETWORK, &seed, AccountId(account), 0).unwrap();
|
let tsk = derive_secret_key_from_seed(&network, &seed, AccountId(account), 0).unwrap();
|
||||||
derive_transparent_address_from_secret_key(&tsk)
|
derive_transparent_address_from_secret_key(&tsk)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
@ -192,7 +179,7 @@ pub extern "C" fn zcashlc_init_accounts_table(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|extsk| {
|
.map(|extsk| {
|
||||||
let encoded = encode_extended_spending_key(
|
let encoded = encode_extended_spending_key(
|
||||||
NETWORK.hrp_sapling_extended_spending_key(),
|
network.hrp_sapling_extended_spending_key(),
|
||||||
extsk,
|
extsk,
|
||||||
);
|
);
|
||||||
CString::new(encoded).unwrap().into_raw()
|
CString::new(encoded).unwrap().into_raw()
|
||||||
|
@ -216,9 +203,11 @@ pub extern "C" fn zcashlc_init_accounts_table_with_keys(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
uvks: *mut FFIUVKBoxedSlice,
|
uvks: *mut FFIUVKBoxedSlice,
|
||||||
|
network_id: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
let s: Box<FFIUVKBoxedSlice> = unsafe { Box::from_raw(uvks) };
|
let s: Box<FFIUVKBoxedSlice> = unsafe { Box::from_raw(uvks) };
|
||||||
|
|
||||||
|
@ -230,7 +219,7 @@ pub extern "C" fn zcashlc_init_accounts_table_with_keys(
|
||||||
for u in slice.into_iter() {
|
for u in slice.into_iter() {
|
||||||
let vkstr = unsafe { CStr::from_ptr(u.extfvk).to_str().unwrap() };
|
let vkstr = unsafe { CStr::from_ptr(u.extfvk).to_str().unwrap() };
|
||||||
let extfvk = decode_extended_full_viewing_key(
|
let extfvk = decode_extended_full_viewing_key(
|
||||||
NETWORK.hrp_sapling_extended_full_viewing_key(),
|
network.hrp_sapling_extended_full_viewing_key(),
|
||||||
&vkstr,
|
&vkstr,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -263,8 +252,10 @@ pub unsafe extern "C" fn zcashlc_derive_extended_spending_keys(
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
accounts: i32,
|
accounts: i32,
|
||||||
capacity_ret: *mut usize,
|
capacity_ret: *mut usize,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut *mut c_char {
|
) -> *mut *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
let accounts = if accounts > 0 {
|
let accounts = if accounts > 0 {
|
||||||
accounts as u32
|
accounts as u32
|
||||||
|
@ -273,7 +264,7 @@ pub unsafe extern "C" fn zcashlc_derive_extended_spending_keys(
|
||||||
};
|
};
|
||||||
|
|
||||||
let extsks: Vec<_> = (0..accounts)
|
let extsks: Vec<_> = (0..accounts)
|
||||||
.map(|account| spending_key(&seed, NETWORK.coin_type(), AccountId(account)))
|
.map(|account| spending_key(&seed, network.coin_type(), AccountId(account)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Return the ExtendedSpendingKeys for the created accounts.
|
// Return the ExtendedSpendingKeys for the created accounts.
|
||||||
|
@ -281,7 +272,7 @@ pub unsafe extern "C" fn zcashlc_derive_extended_spending_keys(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|extsk| {
|
.map(|extsk| {
|
||||||
let encoded = encode_extended_spending_key(
|
let encoded = encode_extended_spending_key(
|
||||||
NETWORK.hrp_sapling_extended_spending_key(),
|
network.hrp_sapling_extended_spending_key(),
|
||||||
extsk,
|
extsk,
|
||||||
);
|
);
|
||||||
CString::new(encoded).unwrap().into_raw()
|
CString::new(encoded).unwrap().into_raw()
|
||||||
|
@ -311,10 +302,11 @@ pub struct FFIUVKBoxedSlice {
|
||||||
|
|
||||||
fn unified_viewing_key_new(
|
fn unified_viewing_key_new(
|
||||||
extfvk: &ExtendedFullViewingKey,
|
extfvk: &ExtendedFullViewingKey,
|
||||||
extpub: &PublicKey) -> FFIUnifiedViewingKey {
|
extpub: &PublicKey,
|
||||||
|
network: Network) -> FFIUnifiedViewingKey {
|
||||||
|
|
||||||
let encoded_extfvk = encode_extended_full_viewing_key(
|
let encoded_extfvk = encode_extended_full_viewing_key(
|
||||||
NETWORK.hrp_sapling_extended_full_viewing_key(),
|
network.hrp_sapling_extended_full_viewing_key(),
|
||||||
extfvk,
|
extfvk,
|
||||||
);
|
);
|
||||||
let encoded_pubkey = hex::encode(&extpub.serialize());
|
let encoded_pubkey = hex::encode(&extpub.serialize());
|
||||||
|
@ -323,7 +315,6 @@ fn unified_viewing_key_new(
|
||||||
extfvk: CString::new(encoded_extfvk).unwrap().into_raw(),
|
extfvk: CString::new(encoded_extfvk).unwrap().into_raw(),
|
||||||
extpub: CString::new(encoded_pubkey).unwrap().into_raw()
|
extpub: CString::new(encoded_pubkey).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uvk_vec_to_ffi (v: Vec<FFIUnifiedViewingKey>)
|
fn uvk_vec_to_ffi (v: Vec<FFIUnifiedViewingKey>)
|
||||||
|
@ -360,8 +351,10 @@ pub unsafe extern "C" fn zcashlc_derive_unified_viewing_keys_from_seed(
|
||||||
seed: *const u8,
|
seed: *const u8,
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
accounts: i32,
|
accounts: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut FFIUVKBoxedSlice {
|
) -> *mut FFIUVKBoxedSlice {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
let accounts = if accounts > 0 {
|
let accounts = if accounts > 0 {
|
||||||
accounts as u32
|
accounts as u32
|
||||||
|
@ -371,9 +364,9 @@ pub unsafe extern "C" fn zcashlc_derive_unified_viewing_keys_from_seed(
|
||||||
|
|
||||||
let uvks: Vec<_> = (0..accounts)
|
let uvks: Vec<_> = (0..accounts)
|
||||||
.map(|account| {
|
.map(|account| {
|
||||||
let extfvk = ExtendedFullViewingKey::from(&spending_key(&seed, NETWORK.coin_type(), AccountId(account)));
|
let extfvk = ExtendedFullViewingKey::from(&spending_key(&seed, network.coin_type(), AccountId(account)));
|
||||||
let extpub = derive_public_key_from_seed(&NETWORK, &seed, AccountId(account), 0).unwrap();
|
let extpub = derive_public_key_from_seed(&network, &seed, AccountId(account), 0).unwrap();
|
||||||
unified_viewing_key_new(&extfvk, &extpub)
|
unified_viewing_key_new(&extfvk, &extpub, network)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Ok(uvk_vec_to_ffi(uvks))
|
Ok(uvk_vec_to_ffi(uvks))
|
||||||
|
@ -393,8 +386,10 @@ pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_keys(
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
accounts: i32,
|
accounts: i32,
|
||||||
capacity_ret: *mut usize,
|
capacity_ret: *mut usize,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut *mut c_char {
|
) -> *mut *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
let accounts = if accounts > 0 {
|
let accounts = if accounts > 0 {
|
||||||
accounts as u32
|
accounts as u32
|
||||||
|
@ -404,7 +399,7 @@ pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_keys(
|
||||||
|
|
||||||
let extsks: Vec<_> = (0..accounts)
|
let extsks: Vec<_> = (0..accounts)
|
||||||
.map(|account| {
|
.map(|account| {
|
||||||
ExtendedFullViewingKey::from(&spending_key(&seed, NETWORK.coin_type(), AccountId(account)))
|
ExtendedFullViewingKey::from(&spending_key(&seed, network.coin_type(), AccountId(account)))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -413,7 +408,7 @@ pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_keys(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|extsk| {
|
.map(|extsk| {
|
||||||
let encoded = encode_extended_full_viewing_key(
|
let encoded = encode_extended_full_viewing_key(
|
||||||
NETWORK.hrp_sapling_extended_full_viewing_key(),
|
network.hrp_sapling_extended_full_viewing_key(),
|
||||||
extsk,
|
extsk,
|
||||||
);
|
);
|
||||||
CString::new(encoded).unwrap().into_raw()
|
CString::new(encoded).unwrap().into_raw()
|
||||||
|
@ -434,19 +429,21 @@ pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_seed(
|
||||||
seed: *const u8,
|
seed: *const u8,
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
account_index: i32,
|
account_index: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
let account_index = if account_index >= 0 {
|
let account_index = if account_index >= 0 {
|
||||||
account_index as u32
|
account_index as u32
|
||||||
} else {
|
} else {
|
||||||
return Err(format_err!("accounts argument must be greater than zero"));
|
return Err(format_err!("accounts argument must be greater than zero"));
|
||||||
};
|
};
|
||||||
let address = spending_key(&seed, NETWORK.coin_type(), AccountId(account_index))
|
let address = spending_key(&seed, network.coin_type(), AccountId(account_index))
|
||||||
.default_address()
|
.default_address()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1;
|
.1;
|
||||||
let address_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &address);
|
let address_str = encode_payment_address(network.hrp_sapling_payment_address(), &address);
|
||||||
Ok(CString::new(address_str).unwrap().into_raw())
|
Ok(CString::new(address_str).unwrap().into_raw())
|
||||||
});
|
});
|
||||||
unwrap_exc_or_null(res)
|
unwrap_exc_or_null(res)
|
||||||
|
@ -457,13 +454,15 @@ pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_seed(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_public_key(
|
pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_public_key(
|
||||||
pubkey: *const c_char,
|
pubkey: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let public_key_str = CStr::from_ptr(pubkey).to_str()?;
|
let public_key_str = CStr::from_ptr(pubkey).to_str()?;
|
||||||
let pk = PublicKey::from_str(&public_key_str)?;
|
let pk = PublicKey::from_str(&public_key_str)?;
|
||||||
let taddr =
|
let taddr =
|
||||||
derive_transparent_address_from_public_key(&pk)
|
derive_transparent_address_from_public_key(&pk)
|
||||||
.encode(&NETWORK);
|
.encode(&network);
|
||||||
|
|
||||||
Ok(CString::new(taddr).unwrap().into_raw())
|
Ok(CString::new(taddr).unwrap().into_raw())
|
||||||
});
|
});
|
||||||
|
@ -475,11 +474,13 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_public_key(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_viewing_key(
|
pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_viewing_key(
|
||||||
extfvk: *const c_char,
|
extfvk: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let extfvk_string = CStr::from_ptr(extfvk).to_str()?;
|
let extfvk_string = CStr::from_ptr(extfvk).to_str()?;
|
||||||
let extfvk = match decode_extended_full_viewing_key(
|
let extfvk = match decode_extended_full_viewing_key(
|
||||||
NETWORK.hrp_sapling_extended_full_viewing_key(),
|
network.hrp_sapling_extended_full_viewing_key(),
|
||||||
&extfvk_string,
|
&extfvk_string,
|
||||||
) {
|
) {
|
||||||
Ok(Some(extfvk)) => extfvk,
|
Ok(Some(extfvk)) => extfvk,
|
||||||
|
@ -494,7 +495,7 @@ pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_viewing_key(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let address = extfvk.default_address().unwrap().1;
|
let address = extfvk.default_address().unwrap().1;
|
||||||
let address_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &address);
|
let address_str = encode_payment_address(network.hrp_sapling_payment_address(), &address);
|
||||||
Ok(CString::new(address_str).unwrap().into_raw())
|
Ok(CString::new(address_str).unwrap().into_raw())
|
||||||
});
|
});
|
||||||
unwrap_exc_or_null(res)
|
unwrap_exc_or_null(res)
|
||||||
|
@ -505,11 +506,13 @@ pub unsafe extern "C" fn zcashlc_derive_shielded_address_from_viewing_key(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_key(
|
pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_key(
|
||||||
extsk: *const c_char,
|
extsk: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let extsk = CStr::from_ptr(extsk).to_str()?;
|
let extsk = CStr::from_ptr(extsk).to_str()?;
|
||||||
let extfvk = match decode_extended_spending_key(
|
let extfvk = match decode_extended_spending_key(
|
||||||
NETWORK.hrp_sapling_extended_spending_key(),
|
network.hrp_sapling_extended_spending_key(),
|
||||||
&extsk,
|
&extsk,
|
||||||
) {
|
) {
|
||||||
Ok(Some(extsk)) => ExtendedFullViewingKey::from(&extsk),
|
Ok(Some(extsk)) => ExtendedFullViewingKey::from(&extsk),
|
||||||
|
@ -525,7 +528,7 @@ pub unsafe extern "C" fn zcashlc_derive_extended_full_viewing_key(
|
||||||
};
|
};
|
||||||
|
|
||||||
let encoded = encode_extended_full_viewing_key(
|
let encoded = encode_extended_full_viewing_key(
|
||||||
NETWORK.hrp_sapling_extended_full_viewing_key(),
|
network.hrp_sapling_extended_full_viewing_key(),
|
||||||
&extfvk,
|
&extfvk,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -546,9 +549,11 @@ pub extern "C" fn zcashlc_init_blocks_table(
|
||||||
hash_hex: *const c_char,
|
hash_hex: *const c_char,
|
||||||
time: u32,
|
time: u32,
|
||||||
sapling_tree_hex: *const c_char,
|
sapling_tree_hex: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len,network)?;
|
||||||
let hash = {
|
let hash = {
|
||||||
let mut hash = hex::decode(unsafe { CStr::from_ptr(hash_hex) }.to_str()?).unwrap();
|
let mut hash = hex::decode(unsafe { CStr::from_ptr(hash_hex) }.to_str()?).unwrap();
|
||||||
hash.reverse();
|
hash.reverse();
|
||||||
|
@ -579,9 +584,11 @@ pub extern "C" fn zcashlc_get_address(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
account: i32,
|
account: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let account = if account >= 0 {
|
let account = if account >= 0 {
|
||||||
account as u32
|
account as u32
|
||||||
} else {
|
} else {
|
||||||
|
@ -592,7 +599,7 @@ pub extern "C" fn zcashlc_get_address(
|
||||||
|
|
||||||
match (&db_data).get_address(account) {
|
match (&db_data).get_address(account) {
|
||||||
Ok(Some(addr)) => {
|
Ok(Some(addr)) => {
|
||||||
let addr_str = encode_payment_address(NETWORK.hrp_sapling_payment_address(), &addr);
|
let addr_str = encode_payment_address(network.hrp_sapling_payment_address(), &addr);
|
||||||
let c_str_addr = CString::new(addr_str).unwrap();
|
let c_str_addr = CString::new(addr_str).unwrap();
|
||||||
Ok(c_str_addr.into_raw())
|
Ok(c_str_addr.into_raw())
|
||||||
}
|
}
|
||||||
|
@ -610,16 +617,19 @@ pub extern "C" fn zcashlc_get_address(
|
||||||
/// Returns false in any other case
|
/// Returns false in any other case
|
||||||
/// Errors when the provided address belongs to another network
|
/// Errors when the provided address belongs to another network
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_is_valid_shielded_address(address: *const c_char) -> bool {
|
pub unsafe extern "C" fn zcashlc_is_valid_shielded_address(address: *const c_char,
|
||||||
|
network_id: u32) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let addr = CStr::from_ptr(address).to_str()?;
|
let addr = CStr::from_ptr(address).to_str()?;
|
||||||
Ok(is_valid_shielded_address(&addr))
|
Ok(is_valid_shielded_address(&addr, &network))
|
||||||
});
|
});
|
||||||
unwrap_exc_or(res, false)
|
unwrap_exc_or(res, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_shielded_address(address: &str) -> bool {
|
fn is_valid_shielded_address(address: &str,
|
||||||
match RecipientAddress::decode(&NETWORK, &address) {
|
network: &Network) -> bool {
|
||||||
|
match RecipientAddress::decode(network, &address) {
|
||||||
Some(addr) => match addr {
|
Some(addr) => match addr {
|
||||||
RecipientAddress::Shielded(_) => true,
|
RecipientAddress::Shielded(_) => true,
|
||||||
RecipientAddress::Transparent(_) => false,
|
RecipientAddress::Transparent(_) => false,
|
||||||
|
@ -631,20 +641,24 @@ fn is_valid_shielded_address(address: &str) -> bool {
|
||||||
/// Returns true when the address is valid and transparent.
|
/// Returns true when the address is valid and transparent.
|
||||||
/// Returns false in any other case
|
/// Returns false in any other case
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_is_valid_transparent_address(address: *const c_char) -> bool {
|
pub unsafe extern "C" fn zcashlc_is_valid_transparent_address(address: *const c_char,
|
||||||
|
network_id: u32) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let addr = CStr::from_ptr(address).to_str()?;
|
let addr = CStr::from_ptr(address).to_str()?;
|
||||||
Ok(is_valid_transparent_address(&addr))
|
Ok(is_valid_transparent_address(&addr, &network))
|
||||||
});
|
});
|
||||||
unwrap_exc_or(res, false)
|
unwrap_exc_or(res, false)
|
||||||
}
|
}
|
||||||
/// returns whether the given viewing key is valid or not
|
/// returns whether the given viewing key is valid or not
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_is_valid_viewing_key(key: *const c_char) -> bool {
|
pub unsafe extern "C" fn zcashlc_is_valid_viewing_key(key: *const c_char,
|
||||||
|
network_id: u32) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let vkstr = CStr::from_ptr(key).to_str()?;
|
let vkstr = CStr::from_ptr(key).to_str()?;
|
||||||
|
|
||||||
match decode_extended_full_viewing_key(&NETWORK.hrp_sapling_extended_full_viewing_key(), &vkstr) {
|
match decode_extended_full_viewing_key(&network.hrp_sapling_extended_full_viewing_key(), &vkstr) {
|
||||||
Ok(s) => match s {
|
Ok(s) => match s {
|
||||||
None => Ok(false),
|
None => Ok(false),
|
||||||
_ => Ok(true),
|
_ => Ok(true),
|
||||||
|
@ -654,8 +668,10 @@ pub unsafe extern "C" fn zcashlc_is_valid_viewing_key(key: *const c_char) -> boo
|
||||||
});
|
});
|
||||||
unwrap_exc_or(res, false)
|
unwrap_exc_or(res, false)
|
||||||
}
|
}
|
||||||
fn is_valid_transparent_address(address: &str) -> bool {
|
|
||||||
match RecipientAddress::decode(&NETWORK, &address) {
|
fn is_valid_transparent_address(address: &str,
|
||||||
|
network: &Network) -> bool {
|
||||||
|
match RecipientAddress::decode(network, &address) {
|
||||||
Some(addr) => match addr {
|
Some(addr) => match addr {
|
||||||
RecipientAddress::Shielded(_) => false,
|
RecipientAddress::Shielded(_) => false,
|
||||||
RecipientAddress::Transparent(_) => true,
|
RecipientAddress::Transparent(_) => true,
|
||||||
|
@ -666,9 +682,15 @@ fn is_valid_transparent_address(address: &str) -> bool {
|
||||||
|
|
||||||
/// Returns the balance for the account, including all unspent notes that we know about.
|
/// Returns the balance for the account, including all unspent notes that we know about.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn zcashlc_get_balance(db_data: *const u8, db_data_len: usize, account: i32) -> i64 {
|
pub extern "C" fn zcashlc_get_balance(
|
||||||
|
db_data: *const u8,
|
||||||
|
db_data_len: usize,
|
||||||
|
account: i32,
|
||||||
|
network_id: u32,
|
||||||
|
) -> i64 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
if account >= 0 {
|
if account >= 0 {
|
||||||
let (_, max_height) = (&db_data)
|
let (_, max_height) = (&db_data)
|
||||||
|
@ -698,9 +720,11 @@ pub extern "C" fn zcashlc_get_verified_balance(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
account: i32,
|
account: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> i64 {
|
) -> i64 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
if account >= 0 {
|
if account >= 0 {
|
||||||
(&db_data)
|
(&db_data)
|
||||||
.get_target_and_anchor_heights()
|
.get_target_and_anchor_heights()
|
||||||
|
@ -730,11 +754,13 @@ pub extern "C" fn zcashlc_get_verified_transparent_balance(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
address: *const c_char,
|
address: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> i64 {
|
) -> i64 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let addr = unsafe { CStr::from_ptr(address).to_str()? };
|
let addr = unsafe { CStr::from_ptr(address).to_str()? };
|
||||||
let taddr = TransparentAddress::decode(&NETWORK, &addr).unwrap();
|
let taddr = TransparentAddress::decode(&network, &addr).unwrap();
|
||||||
let amount = (&db_data)
|
let amount = (&db_data)
|
||||||
.get_target_and_anchor_heights()
|
.get_target_and_anchor_heights()
|
||||||
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
||||||
|
@ -764,11 +790,13 @@ pub extern "C" fn zcashlc_get_total_transparent_balance(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
address: *const c_char,
|
address: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> i64 {
|
) -> i64 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let addr = unsafe { CStr::from_ptr(address).to_str()? };
|
let addr = unsafe { CStr::from_ptr(address).to_str()? };
|
||||||
let taddr = TransparentAddress::decode(&NETWORK, &addr).unwrap();
|
let taddr = TransparentAddress::decode(&network, &addr).unwrap();
|
||||||
let amount = (&db_data)
|
let amount = (&db_data)
|
||||||
.get_target_and_anchor_heights()
|
.get_target_and_anchor_heights()
|
||||||
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
.map_err(|e| format_err!("Error while fetching anchor height: {}", e))
|
||||||
|
@ -803,9 +831,11 @@ pub extern "C" fn zcashlc_get_received_memo_as_utf8(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
id_note: i64,
|
id_note: i64,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
let memo = (&db_data).get_memo(NoteId::ReceivedNoteId(id_note))
|
let memo = (&db_data).get_memo(NoteId::ReceivedNoteId(id_note))
|
||||||
.map_err(|e| format_err!("An error occurred retrieving the memo, {}", e))
|
.map_err(|e| format_err!("An error occurred retrieving the memo, {}", e))
|
||||||
|
@ -833,9 +863,11 @@ pub extern "C" fn zcashlc_get_sent_memo_as_utf8(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
id_note: i64,
|
id_note: i64,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
let memo = (&db_data).get_memo(NoteId::SentNoteId(id_note))
|
let memo = (&db_data).get_memo(NoteId::SentNoteId(id_note))
|
||||||
.map_err(|e| format_err!("An error occurred retrieving the memo, {}", e))
|
.map_err(|e| format_err!("An error occurred retrieving the memo, {}", e))
|
||||||
|
@ -874,16 +906,18 @@ pub extern "C" fn zcashlc_validate_combined_chain(
|
||||||
db_cache_len: usize,
|
db_cache_len: usize,
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let block_db = block_db(db_cache, db_cache_len)?;
|
let block_db = block_db(db_cache, db_cache_len)?;
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
let validate_from = (&db_data)
|
let validate_from = (&db_data)
|
||||||
.get_max_height_hash()
|
.get_max_height_hash()
|
||||||
.map_err(|e| format_err!("Error while validating chain: {}", e))?;
|
.map_err(|e| format_err!("Error while validating chain: {}", e))?;
|
||||||
|
|
||||||
let val_res = validate_chain(&NETWORK, &block_db, validate_from);
|
let val_res = validate_chain(&network, &block_db, validate_from);
|
||||||
|
|
||||||
if let Err(e) = val_res {
|
if let Err(e) = val_res {
|
||||||
match e {
|
match e {
|
||||||
|
@ -905,12 +939,14 @@ pub extern "C" fn zcashlc_get_nearest_rewind_height(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
height: i32,
|
height: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
if height < 100 {
|
if height < 100 {
|
||||||
Ok(height)
|
Ok(height)
|
||||||
} else {
|
} else {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let height = BlockHeight::try_from(height)?;
|
let height = BlockHeight::try_from(height)?;
|
||||||
match get_rewind_height(&db_data) {
|
match get_rewind_height(&db_data) {
|
||||||
Ok(Some(best_height)) => {
|
Ok(Some(best_height)) => {
|
||||||
|
@ -937,9 +973,11 @@ pub extern "C" fn zcashlc_rewind_to_height(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
height: i32,
|
height: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
|
||||||
let height = BlockHeight::try_from(height)?;
|
let height = BlockHeight::try_from(height)?;
|
||||||
rewind_to_height(&db_data, height)
|
rewind_to_height(&db_data, height)
|
||||||
|
@ -970,17 +1008,19 @@ pub extern "C" fn zcashlc_scan_blocks(
|
||||||
db_data: *const u8,
|
db_data: *const u8,
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
scan_limit: u32,
|
scan_limit: u32,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let block_db = block_db(db_cache, db_cache_len)?;
|
let block_db = block_db(db_cache, db_cache_len)?;
|
||||||
let db_read = wallet_db(db_data, db_data_len)?;
|
let db_read = wallet_db(db_data, db_data_len, network)?;
|
||||||
let mut db_data = db_read.get_update_ops()?;
|
let mut db_data = db_read.get_update_ops()?;
|
||||||
let limit = if scan_limit <= 0 {
|
let limit = if scan_limit <= 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(scan_limit)
|
Some(scan_limit)
|
||||||
};
|
};
|
||||||
match scan_cached_blocks(&NETWORK, &block_db, &mut db_data, limit) {
|
match scan_cached_blocks(&network, &block_db, &mut db_data, limit) {
|
||||||
Ok(()) => Ok(1),
|
Ok(()) => Ok(1),
|
||||||
Err(e) => Err(format_err!("Error while scanning blocks: {}", e)),
|
Err(e) => Err(format_err!("Error while scanning blocks: {}", e)),
|
||||||
}
|
}
|
||||||
|
@ -1000,9 +1040,11 @@ pub extern "C" fn zcashlc_put_utxo(
|
||||||
script_bytes_len: usize,
|
script_bytes_len: usize,
|
||||||
value: i64,
|
value: i64,
|
||||||
height: i32,
|
height: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let mut db_data = db_data.get_update_ops()?;
|
let mut db_data = db_data.get_update_ops()?;
|
||||||
|
|
||||||
let addr = unsafe { CStr::from_ptr(address_str).to_str()? };
|
let addr = unsafe { CStr::from_ptr(address_str).to_str()? };
|
||||||
|
@ -1013,7 +1055,7 @@ pub extern "C" fn zcashlc_put_utxo(
|
||||||
let script_bytes = unsafe { slice::from_raw_parts(script_bytes, script_bytes_len) };
|
let script_bytes = unsafe { slice::from_raw_parts(script_bytes, script_bytes_len) };
|
||||||
let script = script_bytes.to_vec();
|
let script = script_bytes.to_vec();
|
||||||
|
|
||||||
let address = TransparentAddress::decode(&NETWORK, &addr).unwrap();
|
let address = TransparentAddress::decode(&network, &addr).unwrap();
|
||||||
|
|
||||||
let output = WalletTransparentOutput {
|
let output = WalletTransparentOutput {
|
||||||
address: address,
|
address: address,
|
||||||
|
@ -1036,12 +1078,14 @@ pub unsafe extern "C" fn zcashlc_clear_utxos(
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
taddress: *const c_char,
|
taddress: *const c_char,
|
||||||
above_height: i32,
|
above_height: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
let mut db_data = db_data.get_update_ops()?;
|
let mut db_data = db_data.get_update_ops()?;
|
||||||
let addr = CStr::from_ptr(taddress).to_str()?;
|
let addr = CStr::from_ptr(taddress).to_str()?;
|
||||||
let taddress = TransparentAddress::decode(&NETWORK, &addr).unwrap();
|
let taddress = TransparentAddress::decode(&network, &addr).unwrap();
|
||||||
let height = BlockHeight::from(above_height as u32);
|
let height = BlockHeight::from(above_height as u32);
|
||||||
match delete_utxos_above(&mut db_data, &taddress, height) {
|
match delete_utxos_above(&mut db_data, &taddress, height) {
|
||||||
Ok(rows) => Ok(rows as i32),
|
Ok(rows) => Ok(rows as i32),
|
||||||
|
@ -1057,14 +1101,16 @@ pub extern "C" fn zcashlc_decrypt_and_store_transaction(
|
||||||
db_data_len: usize,
|
db_data_len: usize,
|
||||||
tx: *const u8,
|
tx: *const u8,
|
||||||
tx_len: usize,
|
tx_len: usize,
|
||||||
|
network_id: u32,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_read = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_read = wallet_db(db_data, db_data_len, network)?;
|
||||||
let mut db_data = db_read.get_update_ops()?;
|
let mut db_data = db_read.get_update_ops()?;
|
||||||
let tx_bytes = unsafe { slice::from_raw_parts(tx, tx_len) };
|
let tx_bytes = unsafe { slice::from_raw_parts(tx, tx_len) };
|
||||||
let tx = Transaction::read(&tx_bytes[..])?;
|
let tx = Transaction::read(&tx_bytes[..])?;
|
||||||
|
|
||||||
match decrypt_and_store_transaction(&NETWORK, &mut db_data, &tx) {
|
match decrypt_and_store_transaction(&network, &mut db_data, &tx) {
|
||||||
Ok(()) => Ok(1),
|
Ok(()) => Ok(1),
|
||||||
Err(e) => Err(format_err!("Error while decrypting transaction: {}", e)),
|
Err(e) => Err(format_err!("Error while decrypting transaction: {}", e)),
|
||||||
}
|
}
|
||||||
|
@ -1093,9 +1139,11 @@ pub extern "C" fn zcashlc_create_to_address(
|
||||||
spend_params_len: usize,
|
spend_params_len: usize,
|
||||||
output_params: *const u8,
|
output_params: *const u8,
|
||||||
output_params_len: usize,
|
output_params_len: usize,
|
||||||
|
network_id: u32,
|
||||||
) -> i64 {
|
) -> i64 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let db_read = wallet_db(db_data, db_data_len)?;
|
let network = parse_network(network_id)?;
|
||||||
|
let db_read = wallet_db(db_data, db_data_len, network)?;
|
||||||
let mut db_data = db_read.get_update_ops()?;
|
let mut db_data = db_read.get_update_ops()?;
|
||||||
let account = if account >= 0 {
|
let account = if account >= 0 {
|
||||||
account as u32
|
account as u32
|
||||||
|
@ -1118,7 +1166,7 @@ pub extern "C" fn zcashlc_create_to_address(
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let extsk =
|
let extsk =
|
||||||
match decode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &extsk)
|
match decode_extended_spending_key(network.hrp_sapling_extended_spending_key(), &extsk)
|
||||||
{
|
{
|
||||||
Ok(Some(extsk)) => extsk,
|
Ok(Some(extsk)) => extsk,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
@ -1129,7 +1177,7 @@ pub extern "C" fn zcashlc_create_to_address(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let to = match RecipientAddress::decode(&NETWORK, &to) {
|
let to = match RecipientAddress::decode(&network, &to) {
|
||||||
Some(to) => to,
|
Some(to) => to,
|
||||||
None => {
|
None => {
|
||||||
return Err(format_err!("PaymentAddress is for the wrong network"));
|
return Err(format_err!("PaymentAddress is for the wrong network"));
|
||||||
|
@ -1149,7 +1197,7 @@ pub extern "C" fn zcashlc_create_to_address(
|
||||||
|
|
||||||
create_spend_to_address(
|
create_spend_to_address(
|
||||||
&mut db_data,
|
&mut db_data,
|
||||||
&NETWORK,
|
&network,
|
||||||
prover,
|
prover,
|
||||||
AccountId(account),
|
AccountId(account),
|
||||||
&extsk,
|
&extsk,
|
||||||
|
@ -1164,9 +1212,13 @@ pub extern "C" fn zcashlc_create_to_address(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn zcashlc_branch_id_for_height(height: i32) -> i32 {
|
pub extern "C" fn zcashlc_branch_id_for_height(
|
||||||
|
height: i32,
|
||||||
|
network_id: u32,
|
||||||
|
) -> i32 {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let branch: BranchId = BranchId::for_height(&NETWORK, BlockHeight::from(height as u32));
|
let network = parse_network(network_id)?;
|
||||||
|
let branch: BranchId = BranchId::for_height(&network, BlockHeight::from(height as u32));
|
||||||
let branch_id: u32 = u32::from(branch);
|
let branch_id: u32 = u32::from(branch);
|
||||||
Ok(branch_id as i32)
|
Ok(branch_id as i32)
|
||||||
});
|
});
|
||||||
|
@ -1209,9 +1261,10 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_private_key_from_seed(
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
account: i32,
|
account: i32,
|
||||||
index: i32,
|
index: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
|
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
let account = if account >= 0 {
|
let account = if account >= 0 {
|
||||||
account as u32
|
account as u32
|
||||||
|
@ -1224,7 +1277,7 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_private_key_from_seed(
|
||||||
} else {
|
} else {
|
||||||
return Err(format_err!("index argument must be positive"));
|
return Err(format_err!("index argument must be positive"));
|
||||||
};
|
};
|
||||||
let sk = derive_secret_key_from_seed(&NETWORK, &seed, AccountId(account), index).unwrap();
|
let sk = derive_secret_key_from_seed(&network, &seed, AccountId(account), index).unwrap();
|
||||||
let sk_wif = Wif::from_secret_key(&sk, true);
|
let sk_wif = Wif::from_secret_key(&sk, true);
|
||||||
|
|
||||||
Ok(CString::new(sk_wif.0.to_string()).unwrap().into_raw())
|
Ok(CString::new(sk_wif.0.to_string()).unwrap().into_raw())
|
||||||
|
@ -1239,9 +1292,11 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_seed(
|
||||||
seed_len: usize,
|
seed_len: usize,
|
||||||
account: i32,
|
account: i32,
|
||||||
index: i32,
|
index: i32,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
let seed = slice::from_raw_parts(seed, seed_len);
|
let seed = slice::from_raw_parts(seed, seed_len);
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let account = if account >= 0 {
|
let account = if account >= 0 {
|
||||||
account as u32
|
account as u32
|
||||||
} else {
|
} else {
|
||||||
|
@ -1253,9 +1308,9 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_seed(
|
||||||
} else {
|
} else {
|
||||||
return Err(format_err!("index argument must be positive"));
|
return Err(format_err!("index argument must be positive"));
|
||||||
};
|
};
|
||||||
let sk = derive_secret_key_from_seed(&NETWORK, &seed, AccountId(account), index);
|
let sk = derive_secret_key_from_seed(&network, &seed, AccountId(account), index);
|
||||||
let taddr = derive_transparent_address_from_secret_key(&sk.unwrap())
|
let taddr = derive_transparent_address_from_secret_key(&sk.unwrap())
|
||||||
.encode(&NETWORK);
|
.encode(&network);
|
||||||
|
|
||||||
Ok(CString::new(taddr).unwrap().into_raw())
|
Ok(CString::new(taddr).unwrap().into_raw())
|
||||||
});
|
});
|
||||||
|
@ -1266,9 +1321,10 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_seed(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_secret_key(
|
pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_secret_key(
|
||||||
tsk: *const c_char,
|
tsk: *const c_char,
|
||||||
|
network_id: u32,
|
||||||
) -> *mut c_char {
|
) -> *mut c_char {
|
||||||
let res = catch_panic(|| {
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
let tsk_wif = CStr::from_ptr(tsk).to_str()?;
|
let tsk_wif = CStr::from_ptr(tsk).to_str()?;
|
||||||
|
|
||||||
let sk: SecretKey = (&Wif(tsk_wif.to_string())).try_into().expect("invalid private key WIF");
|
let sk: SecretKey = (&Wif(tsk_wif.to_string())).try_into().expect("invalid private key WIF");
|
||||||
|
@ -1276,12 +1332,91 @@ pub unsafe extern "C" fn zcashlc_derive_transparent_address_from_secret_key(
|
||||||
// derive the corresponding t-address
|
// derive the corresponding t-address
|
||||||
let taddr =
|
let taddr =
|
||||||
derive_transparent_address_from_secret_key(&sk)
|
derive_transparent_address_from_secret_key(&sk)
|
||||||
.encode(&NETWORK);
|
.encode(&network);
|
||||||
Ok(CString::new(taddr).unwrap().into_raw())
|
Ok(CString::new(taddr).unwrap().into_raw())
|
||||||
});
|
});
|
||||||
unwrap_exc_or_null(res)
|
unwrap_exc_or_null(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn zcashlc_shield_funds(
|
||||||
|
db_data: *const u8,
|
||||||
|
db_data_len: usize,
|
||||||
|
account: i32,
|
||||||
|
tsk: *const c_char,
|
||||||
|
extsk: *const c_char,
|
||||||
|
memo: *const c_char,
|
||||||
|
spend_params: *const u8,
|
||||||
|
spend_params_len: usize,
|
||||||
|
output_params: *const u8,
|
||||||
|
output_params_len: usize,
|
||||||
|
network_id: u32,
|
||||||
|
) -> i64 {
|
||||||
|
let res = catch_panic(|| {
|
||||||
|
let network = parse_network(network_id)?;
|
||||||
|
let db_data = wallet_db(db_data, db_data_len, network)?;
|
||||||
|
let mut update_ops = (&db_data)
|
||||||
|
.get_update_ops()
|
||||||
|
.map_err(|e| format_err!("Could not obtain a writable database connection: {}", e))?;
|
||||||
|
|
||||||
|
let account = if account >= 0 {
|
||||||
|
account as u32
|
||||||
|
} else {
|
||||||
|
return Err(format_err!("account argument must be positive"));
|
||||||
|
};
|
||||||
|
let tsk_wif = unsafe { CStr::from_ptr(tsk) }.to_str()?;
|
||||||
|
let extsk = unsafe { CStr::from_ptr(extsk) }.to_str()?;
|
||||||
|
let memo = unsafe { CStr::from_ptr(memo) }.to_str()?;
|
||||||
|
let spend_params = Path::new(OsStr::from_bytes(unsafe {
|
||||||
|
slice::from_raw_parts(spend_params, spend_params_len)
|
||||||
|
}));
|
||||||
|
let output_params = Path::new(OsStr::from_bytes(unsafe {
|
||||||
|
slice::from_raw_parts(output_params, output_params_len)
|
||||||
|
}));
|
||||||
|
|
||||||
|
//grab secret private key for t-funds
|
||||||
|
let sk:SecretKey = (&Wif(tsk_wif.to_string())).try_into()?;
|
||||||
|
|
||||||
|
let extsk =
|
||||||
|
match decode_extended_spending_key(network.hrp_sapling_extended_spending_key(), &extsk)
|
||||||
|
{
|
||||||
|
Ok(Some(extsk)) => extsk,
|
||||||
|
Ok(None) => {
|
||||||
|
return Err(format_err!("ExtendedSpendingKey is for the wrong network"));
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
return Err(format_err!("Invalid ExtendedSpendingKey: {}", e));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let memo = Memo::from_str(&memo).map_err(|_| format_err!("Invalid memo"))?;
|
||||||
|
let memo_bytes = MemoBytes::from(memo);
|
||||||
|
// shield_funds(&db_cache, &db_data, account, &tsk, &extsk, &memo, &spend_params, &output_params)
|
||||||
|
shield_funds(&mut update_ops,
|
||||||
|
&network,
|
||||||
|
LocalTxProver::new(spend_params, output_params),
|
||||||
|
AccountId(account),
|
||||||
|
&sk,
|
||||||
|
&extsk,
|
||||||
|
&memo_bytes,
|
||||||
|
0) // fix off-by-one error. 10 confs already added in this function
|
||||||
|
.map_err(|e| format_err!("Error while shielding transaction: {}", e))
|
||||||
|
});
|
||||||
|
unwrap_exc_or(res, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utility functions
|
||||||
|
//
|
||||||
|
|
||||||
|
fn parse_network(value: u32) -> Result<Network, failure::Error> {
|
||||||
|
match value {
|
||||||
|
0 => Ok(TestNetwork),
|
||||||
|
1 => Ok(MainNetwork),
|
||||||
|
_ => Err(format_err!("Invalid network type: {}. Expected either 0 or 1 for Testnet or Mainnet, respectively.", value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helper code from: https://github.com/adityapk00/zecwallet-light-cli/blob/master/lib/src/lightwallet.rs
|
// Helper code from: https://github.com/adityapk00/zecwallet-light-cli/blob/master/lib/src/lightwallet.rs
|
||||||
//
|
//
|
||||||
|
@ -1310,70 +1445,4 @@ pub fn double_sha256(payload: &[u8]) -> Vec<u8> {
|
||||||
let h1 = Sha256::digest(&payload);
|
let h1 = Sha256::digest(&payload);
|
||||||
let h2 = Sha256::digest(&h1);
|
let h2 = Sha256::digest(&h1);
|
||||||
h2.to_vec()
|
h2.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn zcashlc_shield_funds(
|
|
||||||
db_data: *const u8,
|
|
||||||
db_data_len: usize,
|
|
||||||
account: i32,
|
|
||||||
tsk: *const c_char,
|
|
||||||
extsk: *const c_char,
|
|
||||||
memo: *const c_char,
|
|
||||||
spend_params: *const u8,
|
|
||||||
spend_params_len: usize,
|
|
||||||
output_params: *const u8,
|
|
||||||
output_params_len: usize,
|
|
||||||
) -> i64 {
|
|
||||||
let res = catch_panic(|| {
|
|
||||||
|
|
||||||
let db_data = wallet_db(db_data, db_data_len)?;
|
|
||||||
let mut update_ops = (&db_data)
|
|
||||||
.get_update_ops()
|
|
||||||
.map_err(|e| format_err!("Could not obtain a writable database connection: {}", e))?;
|
|
||||||
|
|
||||||
let account = if account >= 0 {
|
|
||||||
account as u32
|
|
||||||
} else {
|
|
||||||
return Err(format_err!("account argument must be positive"));
|
|
||||||
};
|
|
||||||
let tsk_wif = unsafe { CStr::from_ptr(tsk) }.to_str()?;
|
|
||||||
let extsk = unsafe { CStr::from_ptr(extsk) }.to_str()?;
|
|
||||||
let memo = unsafe { CStr::from_ptr(memo) }.to_str()?;
|
|
||||||
let spend_params = Path::new(OsStr::from_bytes(unsafe {
|
|
||||||
slice::from_raw_parts(spend_params, spend_params_len)
|
|
||||||
}));
|
|
||||||
let output_params = Path::new(OsStr::from_bytes(unsafe {
|
|
||||||
slice::from_raw_parts(output_params, output_params_len)
|
|
||||||
}));
|
|
||||||
|
|
||||||
//grab secret private key for t-funds
|
|
||||||
let sk:SecretKey = (&Wif(tsk_wif.to_string())).try_into()?;
|
|
||||||
|
|
||||||
let extsk =
|
|
||||||
match decode_extended_spending_key(NETWORK.hrp_sapling_extended_spending_key(), &extsk)
|
|
||||||
{
|
|
||||||
Ok(Some(extsk)) => extsk,
|
|
||||||
Ok(None) => {
|
|
||||||
return Err(format_err!("ExtendedSpendingKey is for the wrong network"));
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
return Err(format_err!("Invalid ExtendedSpendingKey: {}", e));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let memo = Memo::from_str(&memo).map_err(|_| format_err!("Invalid memo"))?;
|
|
||||||
let memo_bytes = MemoBytes::from(memo);
|
|
||||||
// shield_funds(&db_cache, &db_data, account, &tsk, &extsk, &memo, &spend_params, &output_params)
|
|
||||||
shield_funds(&mut update_ops,
|
|
||||||
&NETWORK,
|
|
||||||
LocalTxProver::new(spend_params, output_params),
|
|
||||||
AccountId(account),
|
|
||||||
&sk,
|
|
||||||
&extsk,
|
|
||||||
&memo_bytes,
|
|
||||||
ANCHOR_OFFSET)
|
|
||||||
.map_err(|e| format_err!("Error while shielding transaction: {}", e))
|
|
||||||
});
|
|
||||||
unwrap_exc_or(res, -1)
|
|
||||||
}
|
|
Loading…
Reference in New Issue