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

Store old blocks and txs after regenesis #1811

Merged
merged 33 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
08ba789
Store old blocks and txs after regenesis
Dentosal Apr 8, 2024
056fead
Seamless iteration with old and new blocks
Dentosal Apr 8, 2024
62a1a75
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
Dentosal Apr 9, 2024
04efca5
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
Dentosal Apr 9, 2024
0235fb6
Make first_block_height not return option as it always exists
Dentosal Apr 9, 2024
116d284
Fallback to old receipts if needed
Dentosal Apr 9, 2024
0009390
Start working on fuel-core-driver e2e tests
Dentosal Apr 11, 2024
6f80c34
Actually make it work and add tests
Dentosal Apr 15, 2024
c4ed9b2
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
Dentosal Apr 15, 2024
5f69c77
Add changelog entry
Dentosal Apr 15, 2024
df76ebe
Rename test
Dentosal Apr 15, 2024
1690040
Restore lints
Dentosal Apr 15, 2024
151e8d3
Cleanup
Dentosal Apr 15, 2024
27bee84
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
xgreenx Apr 16, 2024
e7ef64c
Address some PR feedback
Dentosal Apr 16, 2024
3a721e5
Remove new fields from StateConfig
Dentosal Apr 16, 2024
8d5f143
Expose fuel_core_bin as library; use it for e2e test
Dentosal Apr 17, 2024
f84e332
fmt Cargo.toml
Dentosal Apr 17, 2024
1cffc26
clippy
Dentosal Apr 17, 2024
38e49e7
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
Dentosal Apr 17, 2024
7709fd2
Add a sleep in e2e test to avoid patch race condition on db close
Dentosal Apr 17, 2024
0f6e351
Address review comment
Dentosal Apr 17, 2024
b630cd9
Use FuelService directly
Dentosal Apr 17, 2024
94fec14
WIP: keep old* tables
Dentosal Apr 17, 2024
0bc4bf4
Soemthing=)
xgreenx Apr 17, 2024
8c26e45
No spawn
xgreenx Apr 17, 2024
a6a2ade
Fix types on future-order-linearization
Dentosal Apr 17, 2024
81e8cb5
Merge branch 'master' into dento/regenesis-old-blocks-and-txs
Dentosal Apr 18, 2024
1122d37
Cleanup
Dentosal Apr 18, 2024
022f087
Fixed the issue with wrong progress because of the writing into the s…
xgreenx Apr 18, 2024
67ba362
Increase time limit to avoid flikiness
xgreenx Apr 18, 2024
ad83331
Apply comment and increase time for node start up
xgreenx Apr 18, 2024
b80e2b0
Removed useless second wait
xgreenx Apr 18, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Description of the upcoming release here.
- [#1821](https://github.com/FuelLabs/fuel-core/pull/1821): Propagate shutdown signal to (re)genesis. Also add progress bar for (re)genesis.
- [#1813](https://github.com/FuelLabs/fuel-core/pull/1813): Added back support for `/health` endpoint.
- [#1799](https://github.com/FuelLabs/fuel-core/pull/1799): Snapshot creation is now concurrent.
- [#1811](https://github.com/FuelLabs/fuel-core/pull/1811): Regenesis now preserves old blocks and transactions for GraphQL API.

### Changed

Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

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

Binary file not shown.
Binary file modified bin/fuel-core/chainspec/testnet/state_transition_bytecode.wasm
Binary file not shown.
5 changes: 4 additions & 1 deletion bin/fuel-core/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,11 @@ pub async fn run_cli() -> anyhow::Result<()> {
pub fn local_testnet_chain_config() -> ChainConfig {
const TESTNET_CHAIN_CONFIG: &[u8] =
include_bytes!("../chainspec/testnet/chain_config.json");
const TESTNET_CHAIN_CONFIG_STATE_BYTECODE: &[u8] =
include_bytes!("../chainspec/testnet/state_transition_bytecode.wasm");

let config: ChainConfig = serde_json::from_slice(TESTNET_CHAIN_CONFIG).unwrap();
let mut config: ChainConfig = serde_json::from_slice(TESTNET_CHAIN_CONFIG).unwrap();
config.state_transition_bytecode = TESTNET_CHAIN_CONFIG_STATE_BYTECODE.to_vec();
config
}

Expand Down
8 changes: 6 additions & 2 deletions bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl Command {
}
}

pub async fn exec(command: Command) -> anyhow::Result<()> {
pub fn get_service(command: Command) -> anyhow::Result<FuelService> {
#[cfg(any(feature = "rocks-db", feature = "rocksdb-production"))]
if command.db_prune && command.database_path.exists() {
fuel_core::combined_database::CombinedDatabase::prune(&command.database_path)?;
Expand All @@ -389,7 +389,11 @@ pub async fn exec(command: Command) -> anyhow::Result<()> {
// initialize the server
let combined_database = CombinedDatabase::from_config(&config.combined_db_config)?;

let service = FuelService::new(combined_database, config)?;
FuelService::new(combined_database, config)
}

pub async fn exec(command: Command) -> anyhow::Result<()> {
let service = get_service(command)?;

// Genesis could take a long time depending on the snapshot size. Start needs to be
// interruptible by the shutdown_signal
Expand Down
9 changes: 9 additions & 0 deletions bin/fuel-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![deny(clippy::arithmetic_side_effects)]
#![deny(clippy::cast_possible_truncation)]
#![deny(unused_crate_dependencies)]
#![deny(warnings)]

pub mod cli;
pub use fuel_core::service::FuelService;

use tikv_jemallocator as _; // Used only by the binary
9 changes: 1 addition & 8 deletions bin/fuel-core/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
#![deny(clippy::arithmetic_side_effects)]
#![deny(clippy::cast_possible_truncation)]
#![deny(unused_crate_dependencies)]
#![deny(warnings)]

// Use Jemalloc for main binary
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

use fuel_core::service::FuelService;

mod cli;
use fuel_core_bin::cli;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
Expand Down
59 changes: 57 additions & 2 deletions crates/chain-config/src/config/randomize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ use fuel_core_storage::{
ContractsStateKey,
};
use fuel_core_types::{
blockchain::primitives::DaBlockHeight,
blockchain::{
block::CompressedBlock,
consensus::{
poa::PoAConsensus,
Consensus,
},
header::PartialBlockHeader,
primitives::DaBlockHeight,
},
entities::{
coins::coin::{
CompressedCoin,
Expand All @@ -29,18 +37,29 @@ use fuel_core_types::{
relayer::message::MessageV1,
Message,
},
fuel_asm::{
op,
RegId,
},
fuel_tx::{
ContractId,
Transaction,
TransactionBuilder,
UniqueIdentifier,
UtxoId,
},
fuel_types::{
Address,
AssetId,
BlockHeight,
Bytes32,
ChainId,
Nonce,
},
fuel_vm::Salt,
fuel_vm::{
Salt,
Signature,
},
};

use crate::TableEntry;
Expand Down Expand Up @@ -171,3 +190,39 @@ impl Randomize for ContractsStateKey {
Self::new(&contract_id, &state_key)
}
}

impl Randomize for CompressedBlock {
fn randomize(mut rng: impl rand::Rng) -> Self {
let tx1: Transaction = Randomize::randomize(&mut rng);
let tx2: Transaction = Randomize::randomize(&mut rng);

let tx_ids = vec![tx1.id(&ChainId::default()), tx2.id(&ChainId::default())];

Self::test(
PartialBlockHeader::default().generate(&[tx1, tx2], &[], rng.gen()),
tx_ids,
)
}
}

impl Randomize for (BlockHeight, Consensus) {
fn randomize(mut rng: impl rand::Rng) -> Self {
(
rng.gen::<u32>().into(),
Consensus::PoA(PoAConsensus::new(Signature::from_bytes([rng.gen(); 64]))),
)
}
}

impl Randomize for Transaction {
fn randomize(mut rng: impl rand::Rng) -> Self {
let program: Vec<u8> = [op::ret(RegId::ONE)].into_iter().collect();
match rng.gen_range(0..2) {
0 => TransactionBuilder::create(program.into(), rng.gen(), vec![rng.gen()])
.finalize_as_transaction(),
1 => TransactionBuilder::script(program, vec![rng.gen(), rng.gen()])
.finalize_as_transaction(),
_ => unreachable!(),
}
}
}
27 changes: 24 additions & 3 deletions crates/chain-config/src/config/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use fuel_core_storage::{
ContractsLatestUtxo,
ContractsRawCode,
ContractsState,
FuelBlocks,
Messages,
SealedBlockConsensus,
Transactions,
},
ContractsAssetKey,
Expand Down Expand Up @@ -408,11 +410,29 @@ impl AsTable<Transactions> for StateConfig {
}

impl AddTable<Transactions> for StateConfigBuilder {
fn add(&mut self, _entries: Vec<TableEntry<Transactions>>) {
// Do not include these for now
fn add(&mut self, _entries: Vec<TableEntry<Transactions>>) {}
}

impl AsTable<FuelBlocks> for StateConfig {
fn as_table(&self) -> Vec<TableEntry<FuelBlocks>> {
Vec::new() // Do not include these for now
}
}

impl AddTable<FuelBlocks> for StateConfigBuilder {
fn add(&mut self, _entries: Vec<TableEntry<FuelBlocks>>) {}
}

impl AsTable<SealedBlockConsensus> for StateConfig {
fn as_table(&self) -> Vec<TableEntry<SealedBlockConsensus>> {
Vec::new() // Do not include these for now
}
}

impl AddTable<SealedBlockConsensus> for StateConfigBuilder {
fn add(&mut self, _entries: Vec<TableEntry<SealedBlockConsensus>>) {}
}

impl StateConfig {
pub fn sorted(mut self) -> Self {
self.coins = self
Expand Down Expand Up @@ -677,6 +697,8 @@ mod tests {
let mut rng = StdRng::seed_from_u64(0);
let state_config = StateConfig::randomize(&mut rng);

let chain_config = ChainConfig::local_testnet();

macro_rules! write_in_fragments {
($($fragment_ty: ty,)*) => {
[
Expand All @@ -692,7 +714,6 @@ mod tests {
}
}

let chain_config = ChainConfig::local_testnet();
let fragments = write_in_fragments!(
Coins,
Messages,
Expand Down
67 changes: 66 additions & 1 deletion crates/fuel-core/src/graphql_api/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::fuel_core_graphql_api::{
use fuel_core_storage::{
iter::{
BoxedIter,
IntoBoxedIter,
IterDirection,
},
transactional::AtomicView,
Expand All @@ -29,6 +30,7 @@ use fuel_core_txpool::types::{
use fuel_core_types::{
blockchain::{
block::CompressedBlock,
consensus::Consensus,
primitives::{
BlockId,
DaBlockHeight,
Expand Down Expand Up @@ -117,12 +119,56 @@ impl DatabaseBlocks for ReadView {
height: Option<BlockHeight>,
direction: IterDirection,
) -> BoxedIter<'_, StorageResult<CompressedBlock>> {
self.on_chain.blocks(height, direction)
// Chain together blocks from the off-chain db and the on-chain db
// The blocks in off-chain db, if any, are from time before regenesis

if let Some(height) = height {
match self.on_chain.latest_genesis_height() {
Ok(onchain_start_height) => {
match (height >= onchain_start_height, direction) {
(true, IterDirection::Forward) => {
self.on_chain.blocks(Some(height), direction)
}
(true, IterDirection::Reverse) => self
.on_chain
.blocks(Some(height), direction)
.chain(self.off_chain.old_blocks(None, direction))
.into_boxed(),
(false, IterDirection::Forward) => self
.off_chain
.old_blocks(Some(height), direction)
.chain(self.on_chain.blocks(None, direction))
.into_boxed(),
(false, IterDirection::Reverse) => {
self.off_chain.old_blocks(Some(height), direction)
}
}
}
Err(err) => core::iter::once(Err(err)).into_boxed(),
}
} else {
match direction {
IterDirection::Forward => self
.off_chain
.old_blocks(None, direction)
.chain(self.on_chain.blocks(None, direction))
.into_boxed(),
IterDirection::Reverse => self
.on_chain
.blocks(None, direction)
.chain(self.off_chain.old_blocks(None, direction))
.into_boxed(),
}
}
}

fn latest_height(&self) -> StorageResult<BlockHeight> {
self.on_chain.latest_height()
}

fn latest_genesis_height(&self) -> StorageResult<BlockHeight> {
self.on_chain.latest_genesis_height()
}
}

impl<M> StorageInspect<M> for ReadView
Expand Down Expand Up @@ -242,6 +288,25 @@ impl OffChainDatabase for ReadView {
self.off_chain.contract_salt(contract_id)
}

fn old_blocks(
&self,
height: Option<BlockHeight>,
direction: IterDirection,
) -> BoxedIter<'_, StorageResult<CompressedBlock>> {
self.off_chain.old_blocks(height, direction)
}

fn old_block_consensus(&self, height: BlockHeight) -> StorageResult<Consensus> {
self.off_chain.old_block_consensus(height)
}

fn old_transaction(
&self,
id: &TxId,
) -> StorageResult<Option<fuel_core_types::fuel_tx::Transaction>> {
self.off_chain.old_transaction(id)
}

fn relayed_tx_status(
&self,
id: Bytes32,
Expand Down
26 changes: 25 additions & 1 deletion crates/fuel-core/src/graphql_api/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use fuel_core_txpool::service::TxStatusMessage;
use fuel_core_types::{
blockchain::{
block::CompressedBlock,
consensus::Consensus,
primitives::{
BlockId,
DaBlockHeight,
Expand Down Expand Up @@ -91,6 +92,16 @@ pub trait OffChainDatabase: Send + Sync {

fn contract_salt(&self, contract_id: &ContractId) -> StorageResult<Salt>;

fn old_blocks(
&self,
height: Option<BlockHeight>,
direction: IterDirection,
) -> BoxedIter<'_, StorageResult<CompressedBlock>>;

fn old_block_consensus(&self, height: BlockHeight) -> StorageResult<Consensus>;

fn old_transaction(&self, id: &TxId) -> StorageResult<Option<Transaction>>;

fn relayed_tx_status(
&self,
id: Bytes32,
Expand Down Expand Up @@ -123,6 +134,9 @@ pub trait DatabaseBlocks:
) -> BoxedIter<'_, StorageResult<CompressedBlock>>;

fn latest_height(&self) -> StorageResult<BlockHeight>;

/// First (i.e. lowest) height stored in this db.
fn latest_genesis_height(&self) -> StorageResult<BlockHeight>;
}

/// Trait that specifies all the getters required for messages.
Expand Down Expand Up @@ -230,7 +244,14 @@ pub mod worker {
contracts::ContractsInfo,
messages::OwnedMessageIds,
},
graphql_api::storage::relayed_transactions::RelayedTransactionStatuses,
graphql_api::storage::{
old::{
OldFuelBlockConsensus,
OldFuelBlocks,
OldTransactions,
},
relayed_transactions::RelayedTransactionStatuses,
},
};
use fuel_core_services::stream::BoxStream;
use fuel_core_storage::{
Expand Down Expand Up @@ -264,6 +285,9 @@ pub mod worker {
+ StorageMutate<OwnedCoins, Error = StorageError>
+ StorageMutate<FuelBlockIdsToHeights, Error = StorageError>
+ StorageMutate<ContractsInfo, Error = StorageError>
+ StorageMutate<OldFuelBlocks, Error = StorageError>
+ StorageMutate<OldFuelBlockConsensus, Error = StorageError>
+ StorageMutate<OldTransactions, Error = StorageError>
+ StorageMutate<RelayedTransactionStatuses, Error = StorageError>
{
fn record_tx_id_owner(
Expand Down
Loading
Loading