Skip to content

Commit

Permalink
feat: upgrade to stable structures 0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ielashi committed Sep 21, 2023
1 parent 4b48647 commit 4d0e10f
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 49 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ ic-cdk = "0.10.0"
ic-cdk-macros = "0.7.0"
ic-http = { path = "./ic-http" }
ic-metrics-encoder = "1.0.0"
ic-stable-structures = "0.5.2"
ic-stable-structures = "0.6.0-beta.1"
lazy_static = "1.4.0"
serde = "1.0.171"
serde_bytes = "0.11"
Expand Down
5 changes: 3 additions & 2 deletions bootstrap/state-builder/src/build_address_utxos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use ic_btc_canister::types::{into_bitcoin_network, Address, AddressUtxo};
use ic_btc_interface::Network;
use ic_btc_types::{OutPoint, Txid};
use ic_stable_structures::{
storable::Blob, BoundedStorable, DefaultMemoryImpl, StableBTreeMap, Storable,
storable::{max_size, Blob},
DefaultMemoryImpl, StableBTreeMap, Storable,
};
use std::{
fs::File,
Expand Down Expand Up @@ -44,7 +45,7 @@ fn main() {
let reader = BufReader::new(utxos_file);

let memory = DefaultMemoryImpl::default();
let mut address_utxos: StableBTreeMap<Blob<{ AddressUtxo::MAX_SIZE as usize }>, (), _> =
let mut address_utxos: StableBTreeMap<Blob<{ max_size::<AddressUtxo>() as usize }>, (), _> =
StableBTreeMap::init(memory.clone());

for (i, line) in reader.lines().enumerate() {
Expand Down
8 changes: 2 additions & 6 deletions canister/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ic_btc_test_utils::{
BlockBuilder as ExternalBlockBuilder, TransactionBuilder as ExternalTransactionBuilder,
};
use ic_btc_types::{Block, OutPoint, Transaction};
use ic_stable_structures::{BoundedStorable, Memory, StableBTreeMap};
use ic_stable_structures::{storable::Storable, Memory, StableBTreeMap};
use proptest::prelude::RngCore;
use std::{
ops::{Bound, RangeBounds},
Expand Down Expand Up @@ -122,11 +122,7 @@ fn build_chain_with_genesis_block(
}

/// Returns true if the instances of `StableBTreeMap` provided are equal.
pub fn is_stable_btreemap_equal<
M: Memory,
K: BoundedStorable + Ord + Eq + Clone,
V: BoundedStorable + Eq,
>(
pub fn is_stable_btreemap_equal<M: Memory, K: Storable + Ord + Eq + Clone, V: Storable + Eq>(
a: &StableBTreeMap<K, V, M>,
b: &StableBTreeMap<K, V, M>,
) -> bool {
Expand Down
51 changes: 27 additions & 24 deletions canister/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use ic_btc_interface::{
UtxosFilterInRequest,
};
use ic_btc_types::{BlockHash, OutPoint, Txid};
use ic_stable_structures::{storable::Blob, BoundedStorable, Storable as StableStructuresStorable};
use ic_stable_structures::{
storable::{max_size, Blob, Bound as StorableBound},
Storable as StableStructuresStorable,
};
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use std::{
Expand Down Expand Up @@ -135,13 +138,13 @@ impl StableStructuresStorable for Address {
fn from_bytes(bytes: Cow<[u8]>) -> Self {
Self(String::from_utf8(bytes.to_vec()).expect("Loading address cannot fail."))
}
}

impl BoundedStorable for Address {
// The longest addresses are bech32 addresses, and a bech32 string can be at most 90 chars.
// See https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
const MAX_SIZE: u32 = 90;
const IS_FIXED_SIZE: bool = false;
const BOUND: StorableBound = StorableBound::Bounded {
// The longest addresses are bech32 addresses, and a bech32 string can be at most 90 chars.
// See https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
max_size: 90,
is_fixed_size: false,
};
}

#[derive(PartialEq, Eq, Debug, Clone)]
Expand Down Expand Up @@ -180,16 +183,16 @@ impl StableStructuresStorable for AddressUtxo {
)),
}
}
}

impl BoundedStorable for AddressUtxo {
const MAX_SIZE: u32 = Address::MAX_SIZE + 4 /* height bytes */ + OutPoint::MAX_SIZE;
const IS_FIXED_SIZE: bool = false;
const BOUND: StorableBound = StorableBound::Bounded {
max_size: max_size::<Address>() + 4 /* height bytes */ + max_size::<OutPoint>(),
is_fixed_size: false,
};
}

pub struct AddressUtxoRange {
start_bound: Blob<{ AddressUtxo::MAX_SIZE as usize }>,
end_bound: Blob<{ AddressUtxo::MAX_SIZE as usize }>,
start_bound: Blob<{ max_size::<AddressUtxo>() as usize }>,
end_bound: Blob<{ max_size::<AddressUtxo>() as usize }>,
}

impl AddressUtxoRange {
Expand Down Expand Up @@ -240,12 +243,12 @@ impl AddressUtxoRange {
}
}

impl RangeBounds<Blob<{ AddressUtxo::MAX_SIZE as usize }>> for AddressUtxoRange {
fn start_bound(&self) -> Bound<&Blob<{ AddressUtxo::MAX_SIZE as usize }>> {
impl RangeBounds<Blob<{ max_size::<AddressUtxo>() as usize }>> for AddressUtxoRange {
fn start_bound(&self) -> Bound<&Blob<{ max_size::<AddressUtxo>() as usize }>> {
Bound::Included(&self.start_bound)
}

fn end_bound(&self) -> Bound<&Blob<{ AddressUtxo::MAX_SIZE as usize }>> {
fn end_bound(&self) -> Bound<&Blob<{ max_size::<AddressUtxo>() as usize }>> {
Bound::Included(&self.end_bound)
}
}
Expand Down Expand Up @@ -306,13 +309,13 @@ impl StableStructuresStorable for BlockHeaderBlob {
fn from_bytes(bytes: Cow<[u8]>) -> Self {
Self::from(bytes.to_vec())
}
}

impl BoundedStorable for BlockHeaderBlob {
// A Bitcoin block header is always 80 bytes. See:
// https://developer.bitcoin.org/reference/block_chain.html#block-headers
const MAX_SIZE: u32 = 80;
const IS_FIXED_SIZE: bool = true;
const BOUND: StorableBound = StorableBound::Bounded {
// A Bitcoin block header is always 80 bytes. See:
// https://developer.bitcoin.org/reference/block_chain.html#block-headers
max_size: 80,
is_fixed_size: true,
};
}

impl From<&bitcoin::BlockHeader> for BlockHeaderBlob {
Expand All @@ -334,9 +337,9 @@ impl From<Vec<u8>> for BlockHeaderBlob {
fn from(bytes: Vec<u8>) -> Self {
assert_eq!(
bytes.len() as u32,
Self::MAX_SIZE,
max_size::<Self>(),
"BlockHeader must {} bytes",
Self::MAX_SIZE,
max_size::<Self>(),
);
Self(bytes)
}
Expand Down
10 changes: 7 additions & 3 deletions canister/src/utxo_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate::{
use bitcoin::{Script, TxOut as BitcoinTxOut};
use ic_btc_interface::{Height, Network, Satoshi};
use ic_btc_types::{Block, BlockHash, OutPoint, Transaction, Txid};
use ic_stable_structures::{storable::Blob, BoundedStorable, StableBTreeMap, Storable as _};
use ic_stable_structures::{
storable::{max_size, Blob},
StableBTreeMap, Storable as _,
};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeSet, iter::Iterator, str::FromStr};
mod utxos;
Expand All @@ -32,7 +35,7 @@ pub struct UtxoSet {
// An index for fast retrievals of an address's UTXOs.
// NOTE: Stable structures don't need to be serialized.
#[serde(skip, default = "init_address_utxos")]
address_utxos: StableBTreeMap<Blob<{ AddressUtxo::MAX_SIZE as usize }>, (), Memory>,
address_utxos: StableBTreeMap<Blob<{ max_size::<AddressUtxo>() as usize }>, (), Memory>,

// A map of an address and its current balance.
// NOTE: Stable structures don't need to be serialized.
Expand Down Expand Up @@ -446,7 +449,8 @@ impl UtxoSet {
}
}

fn init_address_utxos() -> StableBTreeMap<Blob<{ AddressUtxo::MAX_SIZE as usize }>, (), Memory> {
fn init_address_utxos() -> StableBTreeMap<Blob<{ max_size::<AddressUtxo>() as usize }>, (), Memory>
{
StableBTreeMap::init(crate::memory::get_address_utxos_memory())
}

Expand Down
25 changes: 14 additions & 11 deletions types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use bitcoin::{
};
use candid::CandidType;
use ic_btc_interface::{Network, Txid as PublicTxid};
use ic_stable_structures::{BoundedStorable, Storable};
use ic_stable_structures::{
storable::{max_size, Bound},
Storable,
};
use serde::{Deserialize, Serialize};
use std::{borrow::Cow, cell::RefCell, str::FromStr};

Expand Down Expand Up @@ -215,11 +218,11 @@ impl Storable for BlockHash {
fn from_bytes(bytes: Cow<[u8]>) -> Self {
Self::from(bytes.to_vec())
}
}

impl BoundedStorable for BlockHash {
const MAX_SIZE: u32 = 32;
const IS_FIXED_SIZE: bool = true;
const BOUND: Bound = Bound::Bounded {
max_size: 32,
is_fixed_size: true,
};
}

impl BlockHash {
Expand All @@ -232,9 +235,9 @@ impl From<Vec<u8>> for BlockHash {
fn from(bytes: Vec<u8>) -> Self {
assert_eq!(
bytes.len() as u32,
Self::MAX_SIZE,
max_size::<Self>(),
"BlockHash must {} bytes",
Self::MAX_SIZE
max_size::<Self>(),
);
Self(bytes)
}
Expand Down Expand Up @@ -348,11 +351,11 @@ impl Storable for OutPoint {
vout: u32::from_le_bytes(bytes[32..36].try_into().unwrap()),
}
}
}

impl BoundedStorable for OutPoint {
const MAX_SIZE: u32 = OutPoint::size();
const IS_FIXED_SIZE: bool = true;
const BOUND: Bound = Bound::Bounded {
max_size: OutPoint::size(),
is_fixed_size: true,
};
}

#[test]
Expand Down

0 comments on commit 4d0e10f

Please sign in to comment.