Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[r2r] spv storage optimization #1 #1585

Merged
merged 76 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
a9e776e
save dev state — replaced enabled_spv_proof with SPVConf structure
borngraced Dec 14, 2022
47f76ad
save dev state
borngraced Dec 14, 2022
2731b25
impl get_total_block_headers_count_from_storage
borngraced Dec 16, 2022
275b5f3
save dev state — impl remove_block_headers_from_storage
borngraced Dec 16, 2022
64fb8c3
save dev state
borngraced Dec 17, 2022
2824d47
optimized spv block headers storage limit and starting block
borngraced Dec 17, 2022
c7f1afa
removed SPVConf from UtxoCoinField
borngraced Dec 17, 2022
866a0b5
save dev state — block_headers_limit_to_remove
borngraced Dec 17, 2022
f9ada57
save dev state — impl block_headers_limit_to_remove
borngraced Dec 18, 2022
462e3a6
save dev state — test_get_total_block_headers_from_storage unit test
borngraced Dec 19, 2022
7c56268
save dev state — test_remove_block_headers_from_storage unit test
borngraced Dec 19, 2022
08864ef
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Dec 19, 2022
862553e
optimize spv storage
borngraced Dec 21, 2022
3ce2b23
minor changes to get_last_block_height
borngraced Dec 21, 2022
4b8a654
fix validate header fn
borngraced Dec 22, 2022
9584f86
fix tests
borngraced Dec 22, 2022
9c09e19
save dev state — headers difficulty validation
borngraced Dec 22, 2022
ff3cf63
save dev state — calculate_retarget_height and unit test
borngraced Dec 22, 2022
4ccf4ac
minor changes
borngraced Dec 22, 2022
828fad6
minor changes
borngraced Dec 23, 2022
c218712
fixed block header validation check
borngraced Dec 26, 2022
55bfce4
fix doc comments
borngraced Dec 26, 2022
265ef71
SPVVerificationFailed error kind
borngraced Dec 26, 2022
66c228c
UnableToDeleteHeaders error kind
borngraced Dec 27, 2022
0a7ae98
max_stored_block_headers must be greater than retarget_interval
borngraced Dec 27, 2022
526ef03
enhanced SPVConf and removed dup field
borngraced Dec 27, 2022
a7f6ddb
review changes and test_spv_conf_validate_starting_block_header
borngraced Dec 28, 2022
d558268
update doc comments
borngraced Dec 28, 2022
a054fb4
starting block header fixes
shamardy Dec 29, 2022
ad244e1
SPVConfNoVerification and SPVConfWithVerification
borngraced Jan 2, 2023
0ae51f7
spv_conf deserialization unit test
borngraced Jan 5, 2023
e5fc0a2
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 5, 2023
89b7aa2
remove Default impl
borngraced Jan 9, 2023
40bee1e
remove enable_spv_proof
shamardy Jan 9, 2023
174321c
Refactor SPVConf enum to a struct
shamardy Jan 9, 2023
300e63f
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 9, 2023
752a8a9
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 11, 2023
11855f1
fix test_block_header_utxo_loop
borngraced Jan 11, 2023
db01e59
fix review notes
borngraced Jan 11, 2023
575d228
StartingHeader -> StartingBlockHeader
borngraced Jan 12, 2023
d0b3465
validate_starting_block_header
borngraced Jan 12, 2023
315e24c
validate starting header based on difficulty algorithm
shamardy Jan 13, 2023
c8595a6
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 13, 2023
8efb2fe
fix test_block_header_utxo_loop
borngraced Jan 14, 2023
02a6c76
fix wasm
borngraced Jan 14, 2023
7798a5b
validate_spv_conf
borngraced Jan 14, 2023
35d72e1
fix todo
borngraced Jan 16, 2023
f6b1c0e
validate spv_conf in UtxoArcBuilder
borngraced Jan 16, 2023
8b6d3cb
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 16, 2023
d99c965
refactor spv_conf and added SPVVerificationHeader
borngraced Jan 18, 2023
a9d7445
validate_btc_starting_header_bits
borngraced Jan 18, 2023
6a9f92f
minor changes to SPVVerificationHeader
borngraced Jan 18, 2023
fb67253
Merge remote-tracking branch 'origin/dev' into spv-optimizations
borngraced Jan 18, 2023
c84db96
fix conflicts
borngraced Jan 18, 2023
c4af5a4
fix test_btc_block_header_sync test
borngraced Jan 19, 2023
3ff2893
replace BlockHeaderHashError
borngraced Jan 19, 2023
876611f
some changes to SPVVerificationHeader
borngraced Jan 20, 2023
22ab29b
fix wasm
borngraced Jan 20, 2023
2b24cf6
fix test_enable_coins_with_hd_account_id
borngraced Jan 20, 2023
c7847b1
rename remove_block_headers_from_storage to remove_headers_to_height
borngraced Jan 20, 2023
fe01f20
fix review notes on utxo_arc_builder
borngraced Jan 21, 2023
3048280
fix review notes on spv conf
borngraced Jan 22, 2023
94c2a30
impl get_verification_header
borngraced Jan 23, 2023
388876c
refactor block_header_status_channel
borngraced Jan 23, 2023
44224ff
fix review notes and refactoring
borngraced Jan 23, 2023
d380e5c
fix docs
borngraced Jan 24, 2023
b024b2e
removed retarget header from mainnet_next_block_bits params
borngraced Jan 24, 2023
649bfe1
test_spv_conf_with_verification unit test
borngraced Jan 24, 2023
1e9b0e1
impl validate starting block header from rpc!
borngraced Jan 24, 2023
f1e3e72
fix review notes
borngraced Jan 26, 2023
3e346eb
use correct bit for genesis block - btc testnet
borngraced Jan 26, 2023
f957ddc
refactor remove_headers_up_to_height_sql
borngraced Jan 26, 2023
e4d05df
fix review notes.
borngraced Jan 27, 2023
7239b0e
fix reveiw notes
borngraced Jan 28, 2023
3b41a0a
fix minor review notes
borngraced Jan 31, 2023
82d1bcb
use map_to_mm for error handling
borngraced Feb 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ impl BlockHeaderStorageOps for IndexedDBBlockHeadersStorage {

async fn get_block_height_by_hash(&self, _hash: H256) -> Result<Option<i64>, BlockHeaderStorageError> { Ok(None) }

async fn remove_headers_to_height(&self, _height: u64) -> Result<(), BlockHeaderStorageError> { Ok(()) }
async fn remove_headers_up_to_height(&self, _to_height: u64) -> Result<(), BlockHeaderStorageError> { Ok(()) }
}
4 changes: 2 additions & 2 deletions mm2src/coins/utxo/utxo_block_header_storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl BlockHeaderStorageOps for BlockHeaderStorage {
self.inner.get_block_height_by_hash(hash).await
}

async fn remove_headers_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError> {
self.inner.remove_headers_to_height(to_height).await
async fn remove_headers_up_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError> {
self.inner.remove_headers_up_to_height(to_height).await
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ fn get_block_height_by_hash(for_coin: &str) -> Result<String, BlockHeaderStorage
Ok(sql)
}

fn remove_headers_to_height_sql(for_coin: &str, to_height: u64) -> Result<String, BlockHeaderStorageError> {
fn remove_headers_up_to_height_sql(for_coin: &str, to_height: u64) -> Result<String, BlockHeaderStorageError> {
let table_name = get_table_name_and_validate(for_coin)?;
let sql = format!("DELETE FROM {table_name} WHERE block_height < {to_height};");
let sql = format!("DELETE FROM {table_name} WHERE block_height <= {to_height};");

Ok(sql)
}
Expand Down Expand Up @@ -303,10 +303,10 @@ impl BlockHeaderStorageOps for SqliteBlockHeadersStorage {
})
}

async fn remove_headers_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError> {
async fn remove_headers_up_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError> {
let coin = self.ticker.clone();
let selfi = self.clone();
let sql = remove_headers_to_height_sql(&coin, to_height)?;
let sql = remove_headers_up_to_height_sql(&coin, to_height)?;

async_blocking(move || {
let conn = selfi.conn.lock().unwrap();
Expand Down Expand Up @@ -476,7 +476,7 @@ mod sql_block_headers_storage_tests {
}

#[test]
fn test_remove_headers_to_height() {
fn test_remove_headers_up_to_height() {
let for_coin = "get";
let storage = SqliteBlockHeadersStorage::in_memory(for_coin.into());
let table = block_headers_cache_table(for_coin);
Expand All @@ -503,7 +503,7 @@ mod sql_block_headers_storage_tests {
assert!(!storage.is_table_empty(&table));

// Remove 2 headers from storage.
block_on(storage.remove_headers_to_height(201594)).unwrap();
block_on(storage.remove_headers_up_to_height(201594)).unwrap();

// Validate that blockers 201593..201594 are removed from storage.
for h in 201593..201594 {
Expand Down
3 changes: 1 addition & 2 deletions mm2src/coins/utxo/utxo_builder/utxo_arc_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ pub(crate) async fn block_header_utxo_loop<T: UtxoCommonOps>(

// Check if we need to max the number of headers to be stored in storage.
shamardy marked this conversation as resolved.
Show resolved Hide resolved
if let Some(max_stored_block_headers) = spv_conf.max_stored_block_headers {
// to_block_height - 1(needed to keep previous header) headers will be removed from storage.
if let Err(err) =
remove_excessive_headers_from_storage(storage, to_block_height, max_stored_block_headers).await
{
Expand Down Expand Up @@ -428,7 +427,7 @@ async fn remove_excessive_headers_from_storage(
let max_allowed_headers = max_allowed_headers.get();
if last_height_to_be_added > max_allowed_headers {
let height = last_height_to_be_added - max_allowed_headers;
return storage.remove_headers_to_height(height).await;
return storage.remove_headers_up_to_height(height).await;
}

Ok(())
Expand Down
4 changes: 2 additions & 2 deletions mm2src/coins/utxo/utxo_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4385,11 +4385,11 @@ fn test_block_header_utxo_loop() {
assert!(expected_steps.lock().unwrap().is_empty());

// Vlaidate max_stored_block_headers
// Since max_stored_block_headers == 1(used as previous height) + 15, headers from 2 - 3 shouldn't be in
// Since max_stored_block_headers15, headers from 2 - 5 shouldn't be in
shamardy marked this conversation as resolved.
Show resolved Hide resolved
// storage anymore.
for i in 2..=19 {
let header = client.block_headers_storage().get_block_header(i).await.unwrap();
if i >= 4 {
if i >= 5 {
assert!(header.is_some());
break;
}
Expand Down
22 changes: 12 additions & 10 deletions mm2src/mm2_bitcoin/spv_validation/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,28 @@ impl SPVConf {
let rpc_header = SPVBlockHeader::from_block_header_and_height(rpc_header, height);
let spv_header = &self.starting_block_header;

// Currently, BlockHeader::Compact is used in spv block header validation but some coins from rpc will return
// Currently, BlockHeader::Compact is used in spv block heazder validation but some coins from rpc will return
shamardy marked this conversation as resolved.
Show resolved Hide resolved
// BlockHeader::U32, therefore, we need only the inner value in this case to validate the header bits.
let rpc_header_bits: u32 = rpc_header.bits.into();
let spv_header_bits: u32 = spv_header.bits.clone().into();
if rpc_header_bits != spv_header_bits {
return Err(SPVError::SPVBlockHeaderError(
"Block header not acceptable - bad header bits".to_string(),
));
return Err(SPVError::SPVBlockHeaderError(format!(
"Block header bits not acceptable - expected: {spv_header_bits} - found: {rpc_header_bits}"
)));
};

if rpc_header.hash != spv_header.hash {
return Err(SPVError::SPVBlockHeaderError(
"Block header not acceptable - bad header hash".to_string(),
));
return Err(SPVError::SPVBlockHeaderError(format!(
"Block header hash not acceptable - expected: {} - found: {}",
spv_header.hash, rpc_header.hash,
)));
};

if rpc_header.time != spv_header.time {
return Err(SPVError::SPVBlockHeaderError(
"Block header not acceptable - bad header time".to_string(),
));
return Err(SPVError::SPVBlockHeaderError(format!(
"Block header time not acceptable - expected: {} - found: {}",
spv_header.time, rpc_header.time,
)));
};

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion mm2src/mm2_bitcoin/spv_validation/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,5 @@ pub trait BlockHeaderStorageOps: Send + Sync + 'static {

async fn get_block_height_by_hash(&self, hash: H256) -> Result<Option<i64>, BlockHeaderStorageError>;

async fn remove_headers_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError>;
async fn remove_headers_up_to_height(&self, to_height: u64) -> Result<(), BlockHeaderStorageError>;
}
2 changes: 1 addition & 1 deletion mm2src/mm2_bitcoin/spv_validation/src/work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ pub(crate) mod tests {
Ok(None)
}

async fn remove_headers_to_height(&self, _height: u64) -> Result<(), BlockHeaderStorageError> { Ok(()) }
async fn remove_headers_up_to_height(&self, _height: u64) -> Result<(), BlockHeaderStorageError> { Ok(()) }
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion mm2src/mm2_test_helpers/src/for_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ pub fn tbtc_with_spv_conf() -> Json {
"starting_block_header": {
"height": 0,
"hash": "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943",
"bits": 487063544,
"bits": 486604799,
"time": 1296688602,
},
"validation_params": {
Expand Down