Add a check to ensure that blocks passed to `put_blocks` are sequential.
This commit is contained in:
parent
1b5a24a655
commit
d55fa09464
|
@ -494,6 +494,8 @@ pub trait WalletWrite: WalletRead {
|
|||
/// Updates the state of the wallet database by persisting the provided block information,
|
||||
/// along with the note commitments that were detected when scanning the block for transactions
|
||||
/// pertaining to this wallet.
|
||||
///
|
||||
/// `blocks` must be sequential, in order of increasing block height
|
||||
fn put_blocks(
|
||||
&mut self,
|
||||
block: Vec<ScannedBlock<sapling::Nullifier>>,
|
||||
|
|
|
@ -57,6 +57,9 @@ pub enum SqliteClientError {
|
|||
/// different hash. This indicates that a required rewind was not performed.
|
||||
BlockConflict(BlockHeight),
|
||||
|
||||
/// A range of blocks provided to the database as a unit was non-sequential
|
||||
NonSequentialBlocks,
|
||||
|
||||
/// A requested rewind would violate invariants of the storage layer. The payload returned with
|
||||
/// this error is (safe rewind height, requested height).
|
||||
RequestedRewindInvalid(BlockHeight, BlockHeight),
|
||||
|
@ -118,6 +121,7 @@ impl fmt::Display for SqliteClientError {
|
|||
SqliteClientError::Io(e) => write!(f, "{}", e),
|
||||
SqliteClientError::InvalidMemo(e) => write!(f, "{}", e),
|
||||
SqliteClientError::BlockConflict(h) => write!(f, "A block hash conflict occurred at height {}; rewind required.", u32::from(*h)),
|
||||
SqliteClientError::NonSequentialBlocks => write!(f, "`put_blocks` requires that the provided block range be sequential"),
|
||||
SqliteClientError::DiversifierIndexOutOfRange => write!(f, "The space of available diversifier indices is exhausted"),
|
||||
SqliteClientError::KeyDerivationError(acct_id) => write!(f, "Key derivation failed for account {:?}", acct_id),
|
||||
SqliteClientError::AccountIdDiscontinuity => write!(f, "Wallet account identifiers must be sequential."),
|
||||
|
|
|
@ -412,6 +412,10 @@ impl<P: consensus::Parameters> WalletWrite for WalletDb<rusqlite::Connection, P>
|
|||
let mut end_height = None;
|
||||
|
||||
for block in blocks.into_iter() {
|
||||
if end_height.iter().any(|prev| block.height() != *prev + 1) {
|
||||
return Err(SqliteClientError::NonSequentialBlocks);
|
||||
}
|
||||
|
||||
// Insert the block into the database.
|
||||
wallet::put_block(
|
||||
wdb.conn.0,
|
||||
|
|
Loading…
Reference in New Issue