Skip to content

Commit

Permalink
[Accumulator] Implements sequencer accumulator (#1932)
Browse files Browse the repository at this point in the history
* remove curse inscription todo

* implements sequencer accumulator

* fixup ord conflict

* fixup ord conflict

* save sequencer accumulator info when gensis
  • Loading branch information
baichuan3 authored Jun 18, 2024
1 parent 26da7fd commit 3244cc3
Show file tree
Hide file tree
Showing 18 changed files with 162 additions and 56 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/rooch-genesis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ moveos-stdlib = { workspace = true }
moveos = { workspace = true }
moveos-store = { workspace = true }
moveos-config = { workspace = true }
accumulator = { workspace = true }

rooch-framework = { workspace = true }
rooch-types = { workspace = true }
Expand Down
18 changes: 18 additions & 0 deletions crates/rooch-genesis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use accumulator::accumulator_info::AccumulatorInfo;
use accumulator::{Accumulator, MerkleAccumulator};
use anyhow::{ensure, Result};
use framework_builder::stdlib_version::StdlibVersion;
use framework_builder::Stdlib;
Expand All @@ -25,6 +27,7 @@ use rooch_framework::natives::gas_parameter::gas_member::{
};
use rooch_framework::ROOCH_FRAMEWORK_ADDRESS;
use rooch_indexer::store::traits::IndexerStoreTrait;
use rooch_store::meta_store::MetaStore;
use rooch_store::transaction_store::TransactionStore;
use rooch_types::address::BitcoinAddress;
use rooch_types::bitcoin::genesis::BitcoinGenesisContext;
Expand All @@ -33,6 +36,7 @@ use rooch_types::indexer::event::IndexerEvent;
use rooch_types::indexer::state::{handle_object_change, IndexerObjectStateChanges};
use rooch_types::indexer::transaction::IndexerTransaction;
use rooch_types::rooch_network::{BuiltinChainID, RoochNetwork};
use rooch_types::sequencer::SequencerInfo;
use rooch_types::transaction::rooch::RoochTransaction;
use rooch_types::transaction::{LedgerTransaction, LedgerTxData};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -331,12 +335,26 @@ impl RoochGenesis {
.get::<moveos_types::moveos_std::genesis::GenesisContext>()?
.expect("Moveos Genesis context should exist");
let tx_ledger_data = LedgerTxData::L2Tx(self.genesis_tx());

// Init tx accumulator
let genesis_tx_accumulator = MerkleAccumulator::new_with_info(
AccumulatorInfo::default(),
rooch_db.rooch_store.get_transaction_accumulator_store(),
);
let genesis_accumulator_root =
genesis_tx_accumulator.append(vec![tx_ledger_data.clone().tx_hash()].as_slice())?;
genesis_tx_accumulator.flush()?;

let ledger_tx = LedgerTransaction::build_ledger_transaction(
tx_ledger_data,
moveos_genesis_context.timestamp,
genesis_tx_order,
vec![],
genesis_accumulator_root,
);
let sequencer_info =
SequencerInfo::new(genesis_tx_order, genesis_tx_accumulator.get_info());
rooch_db.rooch_store.save_sequencer_info(sequencer_info)?;
rooch_db.rooch_store.save_transaction(ledger_tx.clone())?;

// Save the genesis to indexer
Expand Down
1 change: 1 addition & 0 deletions crates/rooch-rpc-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ moveos-types = { workspace = true }
move-bytecode-utils = { workspace = true }
raw-store = { workspace = true }
moveos-config = { workspace = true }
accumulator = { workspace = true }

rooch-config = { workspace = true }
rooch-types = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/rooch-sequencer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ move-resource-viewer = { workspace = true }
moveos = { workspace = true }
moveos-store = { workspace = true }
moveos-types = { workspace = true }
accumulator = { workspace = true }

rooch-types = { workspace = true }
rooch-store = { workspace = true }
Expand Down
48 changes: 37 additions & 11 deletions crates/rooch-sequencer/src/actor/sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,64 @@ use crate::messages::{
GetSequencerOrderMessage, GetTransactionByHashMessage, GetTransactionsByHashMessage,
GetTxHashsMessage, TransactionSequenceMessage,
};
use accumulator::{Accumulator, MerkleAccumulator};
use anyhow::Result;
use async_trait::async_trait;
use coerce::actor::{context::ActorContext, message::Handler, Actor};
use moveos_types::h256::{self, H256};
use rooch_store::meta_store::MetaStore;
use rooch_store::transaction_store::TransactionStore;
use rooch_store::RoochStore;
use rooch_types::crypto::{RoochKeyPair, Signature};
use rooch_types::sequencer::SequencerInfo;
use rooch_types::transaction::{LedgerTransaction, LedgerTxData};
use tracing::info;

pub struct SequencerActor {
last_order: u64,
last_sequencer_info: SequencerInfo,
tx_accumulator: MerkleAccumulator,
sequencer_key: RoochKeyPair,
rooch_store: RoochStore,
}

impl SequencerActor {
pub fn new(sequencer_key: RoochKeyPair, rooch_store: RoochStore) -> Result<Self> {
// The genesis tx order is 0, so the sequencer order should not be None
let last_order = rooch_store
// The sequencer info would be inited when genesis, so the sequencer info should not be None
let last_sequencer_info = rooch_store
.get_meta_store()
.get_sequencer_order()?
.map(|order| order.last_order)
.ok_or_else(|| anyhow::anyhow!("Load sequencer tx order failed"))?;
.get_sequencer_info()?
.ok_or_else(|| anyhow::anyhow!("Load sequencer info failed"))?;
let (last_order, last_accumulator_info) = (
last_sequencer_info.last_order,
last_sequencer_info.last_accumulator_info.clone(),
);
info!("Load latest sequencer order {:?}", last_order);
info!(
"Load latest sequencer accumulator info {:?}",
last_accumulator_info
);
let tx_accumulator = MerkleAccumulator::new_with_info(
last_accumulator_info,
rooch_store.get_transaction_accumulator_store(),
);

Ok(Self {
last_order,
last_sequencer_info,
tx_accumulator,
sequencer_key,
rooch_store,
})
}

pub fn last_order(&self) -> u64 {
self.last_order
self.last_sequencer_info.last_order
}

pub fn sequence(&mut self, mut tx_data: LedgerTxData) -> Result<LedgerTransaction> {
let now = SystemTime::now();
let tx_timestamp = now.duration_since(SystemTime::UNIX_EPOCH)?.as_millis() as u64;

let tx_order = self.last_order + 1;
let tx_order = self.last_sequencer_info.last_order + 1;

let hash = tx_data.tx_hash();
let mut witness_data = hash.as_ref().to_vec();
Expand All @@ -56,16 +73,25 @@ impl SequencerActor {
let tx_order_signature = Signature::sign(&witness_hash.0, &self.sequencer_key)
.as_ref()
.to_vec();

// Calc transaction accumulator
let tx_accumulator_root = self.tx_accumulator.append(vec![hash].as_slice())?;
self.tx_accumulator.flush()?;

let tx = LedgerTransaction::build_ledger_transaction(
tx_data,
tx_timestamp,
tx_order,
tx_order_signature,
tx_accumulator_root,
);

let sequencer_info =
SequencerInfo::new(tx.sequence_info.tx_order, self.tx_accumulator.get_info());
self.rooch_store.save_sequencer_info(sequencer_info)?;
self.rooch_store.save_transaction(tx.clone())?;
info!("sequencer tx: {} order: {:?}", hash, tx_order);
self.last_order = tx_order;
self.last_sequencer_info.last_order = tx_order;
Ok(tx)
}
}
Expand Down Expand Up @@ -124,6 +150,6 @@ impl Handler<GetSequencerOrderMessage> for SequencerActor {
_msg: GetSequencerOrderMessage,
_ctx: &mut ActorContext,
) -> Result<u64> {
Ok(self.last_order)
Ok(self.last_sequencer_info.last_order)
}
}
2 changes: 1 addition & 1 deletion crates/rooch-sequencer/tests/test_sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rooch_types::{
fn init_rooch_db(opt: &RoochOpt) -> Result<RoochDB> {
let rooch_db = RoochDB::init(opt.store_config())?;
let network = opt.network();
let genesis = RoochGenesis::load_or_init(network, &rooch_db)?;
let _genesis = RoochGenesis::load_or_init(network, &rooch_db)?;
Ok(rooch_db)
}

Expand Down
1 change: 1 addition & 0 deletions crates/rooch-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ raw-store = { workspace = true }
moveos-config = { workspace = true }
moveos-types = { workspace = true }
moveos-store = { workspace = true }
accumulator = { workspace = true }

rooch-types = { workspace = true }
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
// Copyright (c) The Starcoin Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::TX_ACCUMULATOR_NODE_PREFIX_NAME;
use accumulator::{AccumulatorNode, AccumulatorTreeStore};
use anyhow::Result;
use moveos_types::h256::H256;
use raw_store::CodecKVStore;
use raw_store::{derive_store, CodecKVStore, StoreInstance};

derive_store!(
TransactionAccumulatorStore,
H256,
AccumulatorNode,
TX_ACCUMULATOR_NODE_PREFIX_NAME
);

#[derive(Clone)]
pub struct AccumulatorStore<S>
Expand All @@ -17,6 +25,16 @@ where
store: S,
}

impl AccumulatorStore<TransactionAccumulatorStore> {
pub fn new_transaction_accumulator_store(
instance: StoreInstance,
) -> AccumulatorStore<TransactionAccumulatorStore> {
Self {
store: TransactionAccumulatorStore::new(instance),
}
}
}

impl<S> AccumulatorTreeStore for AccumulatorStore<S>
where
S: CodecKVStore<H256, AccumulatorNode>,
Expand Down
35 changes: 23 additions & 12 deletions crates/rooch-store/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use crate::accumulator_store::{AccumulatorStore, TransactionAccumulatorStore};
use crate::meta_store::{MetaDBStore, MetaStore};
use crate::transaction_store::{TransactionDBStore, TransactionStore};
use accumulator::AccumulatorTreeStore;
use anyhow::Result;
use moveos_types::h256::H256;
use once_cell::sync::Lazy;
use raw_store::{ColumnFamilyName, StoreInstance};
use rooch_types::sequencer::SequencerOrder;
use rooch_types::sequencer::SequencerInfo;
use rooch_types::transaction::LedgerTransaction;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;

pub mod accumulator_store;
pub mod meta_store;
pub mod transaction_store;

// pub const DEFAULT_PREFIX_NAME: ColumnFamilyName = "default";
pub const TRANSACTION_PREFIX_NAME: ColumnFamilyName = "transaction";
pub const TX_SEQUENCE_INFO_MAPPING_PREFIX_NAME: ColumnFamilyName = "tx_sequence_info_mapping";

pub const META_SEQUENCER_ORDER_PREFIX_NAME: ColumnFamilyName = "meta_sequencer_order";
pub const META_SEQUENCER_INFO_PREFIX_NAME: ColumnFamilyName = "meta_sequencer_info";
pub const TX_ACCUMULATOR_NODE_PREFIX_NAME: ColumnFamilyName = "transaction_acc_node";

///db store use prefix_name vec to init
/// Please note that adding a prefix needs to be added in vec simultaneously, remember!!
static VEC_PREFIX_NAME: Lazy<Vec<ColumnFamilyName>> = Lazy::new(|| {
vec![
TRANSACTION_PREFIX_NAME,
TX_SEQUENCE_INFO_MAPPING_PREFIX_NAME,
META_SEQUENCER_ORDER_PREFIX_NAME,
META_SEQUENCER_INFO_PREFIX_NAME,
TX_ACCUMULATOR_NODE_PREFIX_NAME,
]
});

Expand All @@ -43,13 +48,17 @@ impl StoreMeta {
pub struct RoochStore {
pub transaction_store: TransactionDBStore,
pub meta_store: MetaDBStore,
pub transaction_accumulator_store: AccumulatorStore<TransactionAccumulatorStore>,
}

impl RoochStore {
pub fn new(instance: StoreInstance) -> Result<Self> {
let store = Self {
transaction_store: TransactionDBStore::new(instance.clone()),
meta_store: MetaDBStore::new(instance),
meta_store: MetaDBStore::new(instance.clone()),
transaction_accumulator_store: AccumulatorStore::new_transaction_accumulator_store(
instance,
),
};
Ok(store)
}
Expand All @@ -61,6 +70,10 @@ impl RoochStore {
pub fn get_meta_store(&self) -> &MetaDBStore {
&self.meta_store
}

pub fn get_transaction_accumulator_store(&self) -> Arc<dyn AccumulatorTreeStore> {
Arc::new(self.transaction_accumulator_store.clone())
}
}

impl Display for RoochStore {
Expand All @@ -76,9 +89,7 @@ impl Debug for RoochStore {

impl TransactionStore for RoochStore {
fn save_transaction(&self, tx: LedgerTransaction) -> Result<()> {
let sequencer_order = SequencerOrder::new(tx.sequence_info.tx_order);
self.transaction_store.save_transaction(tx)?;
self.meta_store.save_sequencer_order(sequencer_order)
self.transaction_store.save_transaction(tx)
}

fn get_transaction_by_hash(&self, hash: H256) -> Result<Option<LedgerTransaction>> {
Expand All @@ -98,11 +109,11 @@ impl TransactionStore for RoochStore {
}

impl MetaStore for RoochStore {
fn get_sequencer_order(&self) -> Result<Option<SequencerOrder>> {
self.get_meta_store().get_sequencer_order()
fn get_sequencer_info(&self) -> Result<Option<SequencerInfo>> {
self.get_meta_store().get_sequencer_info()
}

fn save_sequencer_order(&self, sequencer_order: SequencerOrder) -> Result<()> {
self.get_meta_store().save_sequencer_order(sequencer_order)
fn save_sequencer_info(&self, sequencer_info: SequencerInfo) -> Result<()> {
self.get_meta_store().save_sequencer_info(sequencer_info)
}
}
Loading

0 comments on commit 3244cc3

Please sign in to comment.