Skip to content

Commit

Permalink
add chain_selector mod
Browse files Browse the repository at this point in the history
  • Loading branch information
Davidson-Souza committed Feb 29, 2024
1 parent 617db08 commit 9f56f17
Show file tree
Hide file tree
Showing 13 changed files with 1,125 additions and 1,005 deletions.
56 changes: 53 additions & 3 deletions crates/floresta-chain/src/pruned_utreexo/chain_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,11 @@ impl<PersistedState: ChainStore> ChainState<PersistedState> {
})?;
Ok(())
}

fn get_assumeutreexo_index(&self) -> (BlockHash, u32) {
let guard = read_lock!(self);
guard.consensus.parameters.assumeutreexo_index
}
}

impl<PersistedState: ChainStore> BlockchainInterface for ChainState<PersistedState> {
Expand Down Expand Up @@ -886,6 +891,48 @@ impl<PersistedState: ChainStore> BlockchainInterface for ChainState<PersistedSta
}
}
impl<PersistedState: ChainStore> UpdatableChainstate for ChainState<PersistedState> {
fn mark_chain_as_valid(&self, _height: u32, hash: BlockHash) -> Result<bool, BlockchainError> {
let (assume_utreexo_hash, _) = self.get_assumeutreexo_index();

let mut assumed_hash = hash;

// Walks the chain until finding our assumeutxo block.
// Since this block was passed in before starting florestad, this value should be
// lesser than or equal our current tip. If we don't find that block, it means the
// assumeutxo block was reorged out (or never was in the main chain). That's weird, but we
// should take precoution against it
while let Ok(header) = self.get_block_header(&assumed_hash) {
if header.block_hash() == assume_utreexo_hash {
break;
}
// We've reached genesis and didn't our block
if self.is_genesis(&header) {
break;
}
assumed_hash = self.get_ancestor(&header)?.block_hash();
}

// The assumeutreexo value passed is **not** in the main chain, start validaton from geneis
if assumed_hash != assume_utreexo_hash {
warn!("We are in a diffenrent chain than our defualt or provided assumeutreexo value. Restarting from genesis");

let mut guard = write_lock!(self);

guard.best_block.validation_index = assumed_hash; // Should be equal to genesis
guard.acc = Stump::new();

return Ok(false);
}

// The assumeutreexo value passed is inside our main chain, start from that point
let mut guard = write_lock!(self);
let acc = guard.consensus.parameters.network_roots.clone();
guard.best_block.validation_index = assumed_hash;
guard.acc = acc;

Ok(true)
}

fn invalidate_block(&self, block: BlockHash) -> Result<(), BlockchainError> {
let height = self.get_disk_block_header(&block)?.height();
if height.is_none() {
Expand Down Expand Up @@ -997,12 +1044,12 @@ impl<PersistedState: ChainStore> UpdatableChainstate for ChainState<PersistedSta
Ok(())
}

fn accept_header(&self, header: BlockHeader) -> Result<(), BlockchainError> {
fn accept_header(&self, header: BlockHeader) -> Result<bool, BlockchainError> {
trace!("Accepting header {header:?}");
let _header = self.get_disk_block_header(&header.block_hash());
if _header.is_ok() {
self.maybe_reindex(&_header?);
return Ok(()); // We already have this header
return Ok(true); // We already have this header
}
// The best block we know of
let best_block = self.get_best_block()?;
Expand All @@ -1027,11 +1074,14 @@ impl<PersistedState: ChainStore> UpdatableChainstate for ChainState<PersistedSta
if header.block_hash() == inner.assume_valid.0 {
inner.assume_valid.1 = height;
}

Ok(true)
} else {
trace!("Header not in the best chain");
self.maybe_reorg(header)?;

Ok(false)
}
Ok(())
}
fn get_root_hashes(&self) -> Vec<NodeHash> {
let inner = read_lock!(self);
Expand Down
45 changes: 45 additions & 0 deletions crates/floresta-chain/src/pruned_utreexo/chainparams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use bitcoin::blockdata::constants::genesis_block;
use bitcoin::Block;
use bitcoin::BlockHash;
use bitcoin::Target;
use rustreexo::accumulator::node_hash::NodeHash;
use rustreexo::accumulator::stump::Stump;

use crate::prelude::*;
use crate::Network;
Expand Down Expand Up @@ -49,6 +51,8 @@ pub struct ChainParams {
/// A list of exceptions to the rules, where the key is the block hash and the value is the
/// verification flags
pub exceptions: HashMap<BlockHash, c_uint>,
pub network_roots: Stump,
pub assumeutreexo_index: (BlockHash, u32),
}

impl ChainParams {
Expand All @@ -62,6 +66,32 @@ impl ChainParams {
}
}

fn get_signet_roots() -> Stump {
let roots: Vec<NodeHash> = [
"8e6fcdcf05020fa1f7131a59a7050b33ca74852f5e82a5fbe236402bc4c8a928",
"f4c92949c71be7613699977eebf6d3bd5c8fd3e538a01380583e5aba14273425",
"d73ceb2748d342b14a269d7c0feb34aca1341a6367cc75cff6db8422eb01916d",
"a012e516784ccb7af26d7b356bf645e6a167cce5b48b9368c58c523acd25f6bf",
"e6e74ebc1d01ac47541c90afaac208c9b0f16226d2d046742032374e925a79ae",
"235b255558e994e6c5b6011469e891436cbf18107a939847e6e5df4cb939a96b",
"a9f45482564f0cb103067636c39fe30df1fa04b6b04d438c655530d991432761",
"d46716b7ccaf8d9eff11557527056f6100e016126df369eef95b9c9874467d40",
"7039b9053ef819d35c079eb4dcdd37029653a325bf416768e7de16bacf2c90af",
"f7a626339303030fc1b71d228e74aebdc2126cb7a2c5e01eb036225ea9dd41c2",
"b21123705cb4cef5a104705037ccd80ae7281789aa07cd468d5949c7e62df37b",
"ca931559f3ad9c91b9510f5dbfa42467e40ad8a0069d8f273de6079e9b115232",
"954ca698b58b6e6cdcc89948c841059d892578b7d67a249965fff83de5aaa7e3",
]
.iter()
.map(|hash| NodeHash::from_str(hash).unwrap())
.collect();

Stump {
roots,
leaves: 1477499,
}
}

#[cfg(feature = "bitcoinconsensus")]
fn get_exceptions() -> HashMap<BlockHash, c_uint> {
// For some reason, some blocks in the mainnet and testnet have different rules than it should
Expand Down Expand Up @@ -89,13 +119,15 @@ fn get_exceptions() -> HashMap<BlockHash, c_uint> {
fn get_exceptions() -> HashMap<BlockHash, c_uint> {
HashMap::new()
}

impl From<Network> for ChainParams {
fn from(net: Network) -> Self {
let genesis = genesis_block(net.into());
let max_target = ChainParams::max_target(net);
let exceptions = get_exceptions();
match net {
Network::Bitcoin => ChainParams {
assumeutreexo_index: (genesis.block_hash(), 0),
genesis,
max_target,
pow_allow_min_diff: false,
Expand All @@ -110,8 +142,10 @@ impl From<Network> for ChainParams {
segwit_activation_height: 481824,
csv_activation_height: 419328,
exceptions,
network_roots: Stump::default(),
},
Network::Testnet => ChainParams {
assumeutreexo_index: (genesis.block_hash(), 0),
genesis,
max_target,
pow_allow_min_diff: true,
Expand All @@ -126,6 +160,7 @@ impl From<Network> for ChainParams {
segwit_activation_height: 834_624,
csv_activation_height: 770_112,
exceptions,
network_roots: Stump::default(),
},
Network::Signet => ChainParams {
genesis,
Expand All @@ -142,8 +177,17 @@ impl From<Network> for ChainParams {
bip66_activation_height: 1,
segwit_activation_height: 1,
exceptions,
network_roots: get_signet_roots(),
assumeutreexo_index: (
BlockHash::from_str(
"0000001321625245a27e0be82a640106d019e35e48a024a17df1ceeb9b1f2131",
)
.unwrap(),
74551,
),
},
Network::Regtest => ChainParams {
assumeutreexo_index: (genesis.block_hash(), 0),
genesis,
max_target,
pow_allow_min_diff: false,
Expand All @@ -158,6 +202,7 @@ impl From<Network> for ChainParams {
bip66_activation_height: 0,
segwit_activation_height: 0,
exceptions,
network_roots: Stump::default(),
},
}
}
Expand Down
10 changes: 9 additions & 1 deletion crates/floresta-chain/src/pruned_utreexo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ pub trait UpdatableChainstate {
/// Accepts a new header to our chain. This method is called before connect_block, and
/// makes some basic checks on a header and saves it on disk. We only accept a block as
/// valid after calling connect_block.
fn accept_header(&self, header: BlockHeader) -> Result<(), BlockchainError>;
///
/// This function returns whether this block is on our best-known chain, or in a fork
fn accept_header(&self, header: BlockHeader) -> Result<bool, BlockchainError>;
/// Not used for now, but in a future blockchain with mempool, we can process transactions
/// that are not in a block yet.
fn handle_transaction(&self) -> Result<(), BlockchainError>;
Expand Down Expand Up @@ -121,6 +123,12 @@ pub trait UpdatableChainstate {
final_height: u32,
acc: Stump,
) -> Result<PartialChainState, BlockchainError>;

/// Marks a chain as fully-valid
///
/// This mimics the behavour of checking every block before this block, and continues
/// from this point
fn mark_chain_as_valid(&self, height: u32, hash: BlockHash) -> Result<bool, BlockchainError>;
}

/// [ChainStore] is a trait defining how we interact with our chain database. This definitions
Expand Down
6 changes: 5 additions & 1 deletion crates/floresta-chain/src/pruned_utreexo/partial_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ impl UpdatableChainstate for PartialChainState {

// these are unimplemented, and will panic if called

fn accept_header(&self, _header: BlockHeader) -> Result<(), BlockchainError> {
fn accept_header(&self, _header: BlockHeader) -> Result<bool, BlockchainError> {
unimplemented!("partialChainState shouldn't be used to accept new headers")
}

Expand All @@ -367,6 +367,10 @@ impl UpdatableChainstate for PartialChainState {
fn process_rescan_block(&self, _block: &bitcoin::Block) -> Result<(), BlockchainError> {
unimplemented!("we don't do rescan")
}

fn mark_chain_as_valid(&self, _height: u32, _hash: BlockHash) -> Result<bool, BlockchainError> {
unimplemented!("no need to mark as valid")
}
}

impl BlockchainInterface for PartialChainState {
Expand Down
2 changes: 2 additions & 0 deletions crates/floresta-wire/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub use p2p_wire::node;
pub use p2p_wire::node_context;
#[cfg(not(target_arch = "wasm32"))]
pub use p2p_wire::node_interface;
#[cfg(not(target_arch = "wasm32"))]
pub use p2p_wire::running_node;

/// NodeHooks is a trait that defines the hooks that a node can use to interact with the network
/// and the blockchain. Every time an event happens, the node will call the corresponding hook.
Expand Down
Loading

0 comments on commit 9f56f17

Please sign in to comment.