This commit changes the way walletBirthday is stored in the synchronizer and intinitializer. Wallets syncing from creation/restore would have a problem where the birthday stored in the Blocks Table would be the one corresponding to the chekpoint found a the time of syncing, but the compact block downloader would start downloading blocks from the height provided by the user when the wallet was restored. This would cause a `validationFailed` error at the height checkpoint.height + 1 and restart downloading from checkpoint.height and then resume correctly. Darksidewalletd test setUp was changed re be able to reproduce the error since injection guaranteed correctness and it was not possible to reproduce the error with it since the wallet birthday height provided matched exactly with the checkpoint on disk and that's the only case that avoided this error. Closes #444
This commit is contained in:
parent
96520aeb7c
commit
3be694c920
|
@ -78,6 +78,8 @@ public class Initializer {
|
||||||
private(set) var downloader: CompactBlockDownloader
|
private(set) var downloader: CompactBlockDownloader
|
||||||
private(set) var network: ZcashNetwork
|
private(set) var network: ZcashNetwork
|
||||||
private(set) public var viewingKeys: [UnifiedViewingKey]
|
private(set) public var viewingKeys: [UnifiedViewingKey]
|
||||||
|
/// The effective birthday of the wallet based on the height provided when initializing
|
||||||
|
/// and the checkpoints available on this SDK
|
||||||
private(set) public var walletBirthday: BlockHeight
|
private(set) public var walletBirthday: BlockHeight
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,8 +203,8 @@ public class Initializer {
|
||||||
throw InitializerError.dataDbInitFailed
|
throw InitializerError.dataDbInitFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
let checkpoint = Checkpoint.birthday(with: self.walletBirthday, network: network)
|
let checkpoint = Checkpoint.birthday(with: self.walletBirthday, network: network)
|
||||||
|
do {
|
||||||
try rustBackend.initBlocksTable(
|
try rustBackend.initBlocksTable(
|
||||||
dbData: dataDbURL,
|
dbData: dataDbURL,
|
||||||
height: Int32(checkpoint.height),
|
height: Int32(checkpoint.height),
|
||||||
|
@ -216,6 +218,7 @@ public class Initializer {
|
||||||
} catch {
|
} catch {
|
||||||
throw InitializerError.dataDbInitFailed
|
throw InitializerError.dataDbInitFailed
|
||||||
}
|
}
|
||||||
|
self.walletBirthday = checkpoint.height
|
||||||
|
|
||||||
let lastDownloaded = (try? downloader.storage.latestHeight()) ?? walletBirthday
|
let lastDownloaded = (try? downloader.storage.latestHeight()) ?? walletBirthday
|
||||||
// resume from last downloaded block
|
// resume from last downloaded block
|
||||||
|
|
|
@ -158,7 +158,6 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
self.status = .disconnected
|
self.status = .disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Starts the synchronizer
|
/// Starts the synchronizer
|
||||||
/// - Throws: CompactBlockProcessorError when failures occur
|
/// - Throws: CompactBlockProcessorError when failures occur
|
||||||
public func start(retry: Bool = false) throws {
|
public func start(retry: Bool = false) throws {
|
||||||
|
|
|
@ -35,7 +35,7 @@ class AdvancedReOrgTests: XCTestCase {
|
||||||
try super.setUpWithError()
|
try super.setUpWithError()
|
||||||
coordinator = try TestCoordinator(
|
coordinator = try TestCoordinator(
|
||||||
seed: seedPhrase,
|
seed: seedPhrase,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday + 50, //don't use an exact birthday, users never do.
|
||||||
channelProvider: ChannelProvider(),
|
channelProvider: ChannelProvider(),
|
||||||
network: network
|
network: network
|
||||||
)
|
)
|
||||||
|
|
|
@ -125,7 +125,7 @@ class TestCoordinator {
|
||||||
outputParamsURL: try __outputParamsURL(),
|
outputParamsURL: try __outputParamsURL(),
|
||||||
spendingKey: spendingKey,
|
spendingKey: spendingKey,
|
||||||
unifiedViewingKey: unifiedViewingKey,
|
unifiedViewingKey: unifiedViewingKey,
|
||||||
walletBirthday: Checkpoint.birthday(with: birthday, network: network),
|
walletBirthday: walletBirthday,
|
||||||
network: network,
|
network: network,
|
||||||
loggerProxy: SampleLogger(logLevel: .debug)
|
loggerProxy: SampleLogger(logLevel: .debug)
|
||||||
)
|
)
|
||||||
|
@ -289,59 +289,25 @@ enum TestSynchronizerBuilder {
|
||||||
outputParamsURL: URL,
|
outputParamsURL: URL,
|
||||||
spendingKey: String,
|
spendingKey: String,
|
||||||
unifiedViewingKey: UnifiedViewingKey,
|
unifiedViewingKey: UnifiedViewingKey,
|
||||||
walletBirthday: Checkpoint,
|
walletBirthday: BlockHeight,
|
||||||
network: ZcashNetwork,
|
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,
|
|
||||||
lowerBoundHeight: lowerBoundHeight,
|
|
||||||
network: network,
|
|
||||||
cacheDbURL: cacheDbURL,
|
cacheDbURL: cacheDbURL,
|
||||||
dataDbURL: dataDbURL,
|
dataDbURL: dataDbURL,
|
||||||
pendingDbURL: pendingDbURL,
|
pendingDbURL: pendingDbURL,
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
service: service,
|
network: network,
|
||||||
repository: repository,
|
|
||||||
accountRepository: accountRepository,
|
|
||||||
storage: CompactBlockStorage(url: cacheDbURL, readonly: false),
|
|
||||||
spendParamsURL: spendParamsURL,
|
spendParamsURL: spendParamsURL,
|
||||||
outputParamsURL: outputParamsURL,
|
outputParamsURL: outputParamsURL,
|
||||||
viewingKeys: [unifiedViewingKey],
|
viewingKeys: [unifiedViewingKey],
|
||||||
walletBirthday: walletBirthday.height,
|
walletBirthday: walletBirthday,
|
||||||
|
alias: "",
|
||||||
loggerProxy: loggerProxy
|
loggerProxy: loggerProxy
|
||||||
)
|
)
|
||||||
|
|
||||||
let config = CompactBlockProcessor.Configuration(
|
let synchronizer = try SDKSynchronizer(initializer: initializer)
|
||||||
cacheDb: initializer.cacheDbURL,
|
|
||||||
dataDb: initializer.dataDbURL,
|
|
||||||
downloadBatchSize: 100,
|
|
||||||
retries: 5,
|
|
||||||
maxBackoffInterval: ZcashSDK.defaultMaxBackOffInterval,
|
|
||||||
rewindDistance: ZcashSDK.defaultRewindDistance,
|
|
||||||
walletBirthday: walletBirthday.height,
|
|
||||||
saplingActivation: lowerBoundHeight,
|
|
||||||
network: network
|
|
||||||
)
|
|
||||||
|
|
||||||
let processor = CompactBlockProcessor(
|
|
||||||
service: service,
|
|
||||||
storage: storage,
|
|
||||||
backend: rustBackend,
|
|
||||||
config: config,
|
|
||||||
repository: repository,
|
|
||||||
accountRepository: accountRepository
|
|
||||||
)
|
|
||||||
|
|
||||||
let synchronizer = try SDKSynchronizer(
|
|
||||||
status: .unprepared,
|
|
||||||
initializer: initializer,
|
|
||||||
transactionManager: OutboundTransactionManagerBuilder.build(initializer: initializer),
|
|
||||||
transactionRepository: repository,
|
|
||||||
utxoRepository: UTXORepositoryBuilder.build(initializer: initializer),
|
|
||||||
blockProcessor: processor
|
|
||||||
)
|
|
||||||
|
|
||||||
try synchronizer.prepare()
|
try synchronizer.prepare()
|
||||||
|
|
||||||
return ([spendingKey], synchronizer)
|
return ([spendingKey], synchronizer)
|
||||||
|
@ -361,7 +327,7 @@ enum TestSynchronizerBuilder {
|
||||||
spendParamsURL: URL,
|
spendParamsURL: URL,
|
||||||
outputParamsURL: URL,
|
outputParamsURL: URL,
|
||||||
seedBytes: [UInt8],
|
seedBytes: [UInt8],
|
||||||
walletBirthday: Checkpoint,
|
walletBirthday: BlockHeight,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
loggerProxy: Logger? = nil
|
loggerProxy: Logger? = nil
|
||||||
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
||||||
|
|
Loading…
Reference in New Issue