Skip to content

Commit

Permalink
feat(consensus)!: add sidechain id in the genesis block (#1135)
Browse files Browse the repository at this point in the history
Description
---
* Created the definition of a `ExtraData` (following Bitcoin and
Ethereum naming) type for storing additional information inside blocks:
    * It contains a key-value map of arbitrary binary data
* For now only a key exists for sidechain ids, but it can be extended in
the future
* The binary value max size is limited by definition via `MaxSizeBytes`
(copied from the minotari codebase)
* Updated the definition for `Block`, `ParkedBlock` and
`ForeignProposal` to include an optional `extra_data` field
* Updated the SQLite storage for the new field
* Updated the protobuf definitions with the new field
* Updated the typescript bindings
* Genesis blocks now encode the sidechain id ( if present in the config)
in the new `extra_data` field
* New `check_sidechain_id` validation in consensus block validation, to
check the sidechain id in the extra data of genesis blocks

Motivation and Context
---
We should have the sidechain id in the genesis block for the shard and
epoch. Including it in all blocks would be wasteful, so only genesis
blocks should include it.

To make it more general for the future, we want to create an optional
field in blocks to store any type of data, and use it to store the
sidechain id.

How Has This Been Tested?
---
Manually with `tari_swarm`:
* Setting up a `sidechain_deployment_key` in the `minotari_wallet`
* Settiup up a `validator_node_sidechain_id` in `validator_node`
* Setting up `sidechain_id` in the `indexer`
* Performing transactions to advance the network and inspecting the
blocks in the database

Also tested with no sidechain

What process can a PR reviewer use to test or verify this change?
---
See previous section

Breaking Changes
---

- [ ] None
- [ ] Requires data directory to be deleted
- [x] Other - Network reset as the block definition and validation has
changed
  • Loading branch information
mrnaveira committed Sep 10, 2024
1 parent 2b5ba47 commit d983b36
Show file tree
Hide file tree
Showing 41 changed files with 902 additions and 503 deletions.
25 changes: 16 additions & 9 deletions applications/tari_indexer/src/event_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ use futures::StreamExt;
use log::*;
use tari_bor::decode;
use tari_common::configuration::Network;
use tari_crypto::tari_utilities::message_format::MessageFormat;
use tari_crypto::{ristretto::RistrettoPublicKey, tari_utilities::message_format::MessageFormat};
use tari_dan_app_utilities::consensus_constants::ConsensusConstants;
use tari_dan_common_types::{committee::Committee, Epoch, NumPreshards, PeerAddress, ShardGroup};
use tari_dan_p2p::proto::rpc::{GetTransactionResultRequest, PayloadResultStatus, SyncBlocksRequest};
use tari_dan_storage::consensus_models::{Block, BlockId, Decision, TransactionRecord};
use tari_dan_storage::consensus_models::{Block, BlockError, BlockId, Decision, TransactionRecord};
use tari_engine_types::{
commit_result::{ExecuteResult, TransactionResult},
events::Event,
Expand Down Expand Up @@ -96,6 +96,7 @@ struct TransactionMetadata {

pub struct EventScanner {
network: Network,
sidechain_id: Option<RistrettoPublicKey>,
epoch_manager: Box<dyn EpochManagerReader<Addr = PeerAddress>>,
client_factory: TariValidatorNodeRpcClientFactory,
substate_store: SqliteSubstateStore,
Expand All @@ -105,13 +106,15 @@ pub struct EventScanner {
impl EventScanner {
pub fn new(
network: Network,
sidechain_id: Option<RistrettoPublicKey>,
epoch_manager: Box<dyn EpochManagerReader<Addr = PeerAddress>>,
client_factory: TariValidatorNodeRpcClientFactory,
substate_store: SqliteSubstateStore,
event_filters: Vec<EventFilter>,
) -> Self {
Self {
network,
sidechain_id,
epoch_manager,
client_factory,
substate_store,
Expand Down Expand Up @@ -447,10 +450,10 @@ impl EventScanner {
.collect()
}

fn build_genesis_block_id(&self, num_preshards: NumPreshards) -> BlockId {
fn build_genesis_block_id(&self, num_preshards: NumPreshards) -> Result<BlockId, BlockError> {
// TODO: this should return the actual genesis for the shard group and epoch
let start_block = Block::zero_block(self.network, num_preshards);
*start_block.id()
let start_block = Block::zero_block(self.network, num_preshards, self.sidechain_id.clone())?;
Ok(*start_block.id())
}

async fn get_oldest_scanned_epoch(&self) -> Result<Option<Epoch>, anyhow::Error> {
Expand All @@ -470,10 +473,14 @@ impl EventScanner {
let start_block_id = self
.substate_store
.with_read_tx(|tx| tx.get_last_scanned_block_id(epoch, shard_group))?;
let start_block_id = start_block_id.unwrap_or_else(|| {
let consensus_constants = ConsensusConstants::from(self.network);
self.build_genesis_block_id(consensus_constants.num_preshards)
});

let start_block_id = match start_block_id {
Some(block_id) => block_id,
None => {
let consensus_constants = ConsensusConstants::from(self.network);
self.build_genesis_block_id(consensus_constants.num_preshards)?
},
};

committee.shuffle();
let mut last_block_id = start_block_id;
Expand Down
1 change: 1 addition & 0 deletions applications/tari_indexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ pub async fn run_indexer(config: ApplicationConfig, mut shutdown_signal: Shutdow
.map_err(|e| ExitError::new(ExitCode::ConfigError, format!("Invalid event filters: {}", e)))?;
let event_scanner = Arc::new(EventScanner::new(
config.network,
config.indexer.sidechain_id,
Box::new(services.epoch_manager.clone()),
services.validator_node_client_factory.clone(),
services.substate_store.clone(),
Expand Down
56 changes: 49 additions & 7 deletions applications/tari_validator_node/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use tari_common::{
#[cfg(not(feature = "metrics"))]
use tari_consensus::traits::hooks::NoopHooks;
use tari_core::transactions::transaction_components::ValidatorNodeSignature;
use tari_crypto::tari_utilities::ByteArray;
use tari_crypto::{ristretto::RistrettoPublicKey, tari_utilities::ByteArray};
use tari_dan_app_utilities::{
base_layer_scanner,
consensus_constants::ConsensusConstants,
Expand Down Expand Up @@ -191,7 +191,15 @@ pub async fn spawn_services(
// Connect to shard db
let state_store =
SqliteStateStore::connect(&format!("sqlite://{}", config.validator_node.state_db_path().display()))?;
state_store.with_write_tx(|tx| bootstrap_state(tx, config.network, consensus_constants.num_preshards))?;
let sidechain_id = config.validator_node.validator_node_sidechain_id.clone();
state_store.with_write_tx(|tx| {
bootstrap_state(
tx,
config.network,
consensus_constants.num_preshards,
sidechain_id.clone(),
)
})?;

info!(target: LOG_TARGET, "Epoch manager initializing");
let epoch_manager_config = EpochManagerConfig {
Expand Down Expand Up @@ -265,6 +273,7 @@ pub async fn spawn_services(
let signing_service = consensus::TariSignatureService::new(keypair.clone());
let (consensus_join_handle, consensus_handle) = consensus::spawn(
config.network,
sidechain_id,
state_store.clone(),
local_address,
signing_service,
Expand Down Expand Up @@ -450,7 +459,12 @@ async fn spawn_p2p_rpc(
Ok(())
}

fn bootstrap_state<TTx>(tx: &mut TTx, network: Network, num_preshards: NumPreshards) -> Result<(), StorageError>
fn bootstrap_state<TTx>(
tx: &mut TTx,
network: Network,
num_preshards: NumPreshards,
sidechain_id: Option<RistrettoPublicKey>,
) -> Result<(), StorageError>
where
TTx: StateStoreWriteTransaction + Deref,
TTx::Target: StateStoreReadTransaction,
Expand All @@ -473,7 +487,14 @@ where
None,
None,
);
create_substate(tx, network, num_preshards, PUBLIC_IDENTITY_RESOURCE_ADDRESS, value)?;
create_substate(
tx,
network,
num_preshards,
&sidechain_id,
PUBLIC_IDENTITY_RESOURCE_ADDRESS,
value,
)?;

let mut xtr_resource = Resource::new(
ResourceType::Confidential,
Expand All @@ -498,7 +519,14 @@ where
state: cbor!({"vault" => XTR_FAUCET_VAULT_ADDRESS}).unwrap(),
},
};
create_substate(tx, network, num_preshards, XTR_FAUCET_COMPONENT_ADDRESS, value)?;
create_substate(
tx,
network,
num_preshards,
&sidechain_id,
XTR_FAUCET_COMPONENT_ADDRESS,
value,
)?;

xtr_resource.increase_total_supply(Amount::MAX);
let value = Vault::new(ResourceContainer::Confidential {
Expand All @@ -509,13 +537,21 @@ where
locked_revealed_amount: Default::default(),
});

create_substate(tx, network, num_preshards, XTR_FAUCET_VAULT_ADDRESS, value)?;
create_substate(
tx,
network,
num_preshards,
&sidechain_id,
XTR_FAUCET_VAULT_ADDRESS,
value,
)?;
}

create_substate(
tx,
network,
num_preshards,
&sidechain_id,
CONFIDENTIAL_TARI_RESOURCE_ADDRESS,
xtr_resource,
)?;
Expand All @@ -527,6 +563,7 @@ fn create_substate<TTx, TId, TVal>(
tx: &mut TTx,
network: Network,
num_preshards: NumPreshards,
sidechain_id: &Option<RistrettoPublicKey>,
substate_id: TId,
value: TVal,
) -> Result<(), StorageError>
Expand All @@ -537,7 +574,12 @@ where
TId: Into<SubstateId>,
TVal: Into<SubstateValue>,
{
let genesis_block = Block::genesis(network, Epoch(0), ShardGroup::all_shards(num_preshards));
let genesis_block = Block::genesis(
network,
Epoch(0),
ShardGroup::all_shards(num_preshards),
sidechain_id.clone(),
)?;
let substate_id = substate_id.into();
let id = VersionedSubstateId::new(substate_id, 0);
SubstateRecord {
Expand Down
3 changes: 3 additions & 0 deletions applications/tari_validator_node/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use tari_consensus::{
hotstuff::{ConsensusWorker, ConsensusWorkerContext, HotstuffConfig, HotstuffWorker},
traits::ConsensusSpec,
};
use tari_crypto::ristretto::RistrettoPublicKey;
use tari_dan_app_utilities::{
consensus_constants::ConsensusConstants,
template_manager::implementation::TemplateManager,
Expand Down Expand Up @@ -60,6 +61,7 @@ pub type ConsensusTransactionValidator = BoxedValidator<ValidationContext, Trans

pub async fn spawn(
network: Network,
sidechain_id: Option<RistrettoPublicKey>,
store: SqliteStateStore<PeerAddress>,
local_addr: PeerAddress,
signing_service: TariSignatureService,
Expand All @@ -83,6 +85,7 @@ pub async fn spawn(

let hs_config = HotstuffConfig {
network,
sidechain_id,
max_base_layer_blocks_behind: consensus_constants.max_base_layer_blocks_behind,
max_base_layer_blocks_ahead: consensus_constants.max_base_layer_blocks_ahead,
num_preshards: consensus_constants.num_preshards,
Expand Down
39 changes: 20 additions & 19 deletions bindings/dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
export * from "./types/AccessRule";
export * from "./types/Account";
export * from "./types/Amount";
export * from "./types/ArgDef";
export * from "./types/Arg";
export * from "./types/ArgDef";
export * from "./types/AuthHook";
export * from "./types/Block";
export * from "./types/BucketId";
export * from "./types/Claims";
export * from "./types/Command";
export * from "./types/Committee";
export * from "./types/CommitteeInfo";
export * from "./types/CommitteeShardInfo";
export * from "./types/Committee";
export * from "./types/ComponentAccessRules";
export * from "./types/ComponentAddress";
export * from "./types/ComponentBody";
export * from "./types/ComponentHeader";
export * from "./types/ComponentKey";
export * from "./types/ConfidentialClaim";
export * from "./types/ConfidentialOutputStatement";
export * from "./types/ConfidentialOutput";
export * from "./types/ConfidentialOutputStatement";
export * from "./types/ConfidentialStatement";
export * from "./types/ConfidentialTransferInputSelection";
export * from "./types/ConfidentialWithdrawProof";
Expand All @@ -28,11 +28,12 @@ export * from "./types/EntityId";
export * from "./types/Epoch";
export * from "./types/Event";
export * from "./types/Evidence";
export * from "./types/ExecutedTransaction";
export * from "./types/ExecuteResult";
export * from "./types/ExecutedTransaction";
export * from "./types/ExtraData";
export * from "./types/FeeBreakdown";
export * from "./types/FeeClaimAddress";
export * from "./types/FeeClaim";
export * from "./types/FeeClaimAddress";
export * from "./types/FeeCostBreakdown";
export * from "./types/FeeReceipt";
export * from "./types/FeeSource";
Expand All @@ -41,10 +42,10 @@ export * from "./types/ForeignProposalAtom";
export * from "./types/FunctionDef";
export * from "./types/IndexedValue";
export * from "./types/IndexedWellKnownTypes";
export * from "./types/InstructionResult";
export * from "./types/Instruction";
export * from "./types/JrpcPermissions";
export * from "./types/InstructionResult";
export * from "./types/JrpcPermission";
export * from "./types/JrpcPermissions";
export * from "./types/LeaderFee";
export * from "./types/LockFlag";
export * from "./types/LogEntry";
Expand All @@ -53,14 +54,14 @@ export * from "./types/Metadata";
export * from "./types/MintConfidentialOutputAtom";
export * from "./types/NetworkCommitteeInfo";
export * from "./types/NodeHeight";
export * from "./types/NonFungibleAddressContents";
export * from "./types/NonFungible";
export * from "./types/NonFungibleAddress";
export * from "./types/NonFungibleAddressContents";
export * from "./types/NonFungibleContainer";
export * from "./types/NonFungibleId";
export * from "./types/NonFungibleIndexAddress";
export * from "./types/NonFungibleIndex";
export * from "./types/NonFungibleIndexAddress";
export * from "./types/NonFungibleToken";
export * from "./types/NonFungible";
export * from "./types/NumPreshards";
export * from "./types/Ordering";
export * from "./types/OwnerRule";
Expand All @@ -70,47 +71,47 @@ export * from "./types/QuorumCertificate";
export * from "./types/QuorumDecision";
export * from "./types/RejectReason";
export * from "./types/RequireRule";
export * from "./types/Resource";
export * from "./types/ResourceAccessRules";
export * from "./types/ResourceAddress";
export * from "./types/ResourceContainer";
export * from "./types/Resource";
export * from "./types/ResourceType";
export * from "./types/RestrictedAccessRule";
export * from "./types/RuleRequirement";
export * from "./types/Shard";
export * from "./types/ShardEvidence";
export * from "./types/ShardGroup";
export * from "./types/Shard";
export * from "./types/Substate";
export * from "./types/SubstateAddress";
export * from "./types/SubstateDestroyed";
export * from "./types/SubstateDiff";
export * from "./types/SubstateId";
export * from "./types/SubstateLockType";
export * from "./types/SubstateRecord";
export * from "./types/SubstateRequirementLockIntent";
export * from "./types/SubstateRequirement";
export * from "./types/Substate";
export * from "./types/SubstateRequirementLockIntent";
export * from "./types/SubstateType";
export * from "./types/SubstateValue";
export * from "./types/TemplateDef";
export * from "./types/TemplateDefV1";
export * from "./types/Transaction";
export * from "./types/TransactionAtom";
export * from "./types/TransactionPoolRecord";
export * from "./types/TransactionPoolStage";
export * from "./types/TransactionReceiptAddress";
export * from "./types/TransactionReceipt";
export * from "./types/TransactionReceiptAddress";
export * from "./types/TransactionResult";
export * from "./types/TransactionSignature";
export * from "./types/TransactionStatus";
export * from "./types/Transaction";
export * from "./types/Type";
export * from "./types/UnclaimedConfidentialOutputAddress";
export * from "./types/UnclaimedConfidentialOutput";
export * from "./types/UnclaimedConfidentialOutputAddress";
export * from "./types/UnsignedTransaction";
export * from "./types/ValidatorSignature";
export * from "./types/VaultId";
export * from "./types/Vault";
export * from "./types/VersionedSubstateIdLockIntent";
export * from "./types/VaultId";
export * from "./types/VersionedSubstateId";
export * from "./types/VersionedSubstateIdLockIntent";
export * from "./types/ViewableBalanceProof";
export * from "./base-node-client";
export * from "./tari-indexer-client";
Expand Down
Loading

0 comments on commit d983b36

Please sign in to comment.