From 7566ce60c1781c8b6678f037de915bd823220dde Mon Sep 17 00:00:00 2001 From: Maico Leberle Date: Sun, 19 Nov 2023 10:38:36 -0300 Subject: [PATCH 1/4] feat: integrate Byron phase-1 validations (#123) --- Cargo.lock | 23 +++--- Cargo.toml | 2 - src/storage/applydb/mod.rs | 149 ++++++++++++++++++++++++++++++++++--- src/sync/ledger.rs | 11 ++- src/sync/mod.rs | 2 +- 5 files changed, 158 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 798bc85d..e3212d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1272,7 +1272,7 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "pallas" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "pallas-addresses", "pallas-applying", @@ -1289,7 +1289,7 @@ dependencies = [ [[package]] name = "pallas-addresses" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "base58", "bech32 0.9.1", @@ -1304,8 +1304,9 @@ dependencies = [ [[package]] name = "pallas-applying" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ + "pallas-addresses", "pallas-codec", "pallas-crypto", "pallas-primitives", @@ -1316,7 +1317,7 @@ dependencies = [ [[package]] name = "pallas-codec" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "hex", "minicbor", @@ -1327,7 +1328,7 @@ dependencies = [ [[package]] name = "pallas-configs" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "base64 0.21.4", "hex", @@ -1341,7 +1342,7 @@ dependencies = [ [[package]] name = "pallas-crypto" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "cryptoxide", "hex", @@ -1354,7 +1355,7 @@ dependencies = [ [[package]] name = "pallas-network" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "byteorder", "hex", @@ -1369,7 +1370,7 @@ dependencies = [ [[package]] name = "pallas-primitives" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "base58", "bech32 0.9.1", @@ -1384,7 +1385,7 @@ dependencies = [ [[package]] name = "pallas-rolldb" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "async-stream", "bincode", @@ -1401,7 +1402,7 @@ dependencies = [ [[package]] name = "pallas-traverse" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "hex", "pallas-addresses", @@ -1415,7 +1416,7 @@ dependencies = [ [[package]] name = "pallas-utxorpc" version = "0.19.1" -source = "git+https://github.com/txpipe/pallas.git#919529eaa0432af9547aad4f6089755b68cff89d" +source = "git+https://github.com/txpipe/pallas.git#68b46c36a80775e3511b38447e870ccde44b04b3" dependencies = [ "pallas-codec", "pallas-primitives", diff --git a/Cargo.toml b/Cargo.toml index b8795194..ad44e52c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,6 @@ authors = ["Santiago Carmuega "] [dependencies] -# pallas = "0.19.0" -# pallas = { path = "../pallas/pallas" } pallas = { git = "https://github.com/txpipe/pallas.git", features = ["unstable"] } gasket = { version = "^0.5", features = ["derive"] } diff --git a/src/storage/applydb/mod.rs b/src/storage/applydb/mod.rs index e9fe5644..15ed1a06 100644 --- a/src/storage/applydb/mod.rs +++ b/src/storage/applydb/mod.rs @@ -1,6 +1,17 @@ pub mod genesis; -use pallas::{crypto::hash::Hash, ledger::traverse::MultiEraBlock}; +use pallas::{ + applying::{ + types::{ByronProtParams, Environment, MultiEraProtParams, UTxOs}, + validate, + }, + codec::utils::CborWrap, + crypto::hash::Hash, + ledger::{ + primitives::byron::{Tx, TxIn, TxOut}, + traverse::{Era, MultiEraBlock, MultiEraInput, MultiEraOutput, MultiEraTx}, + }, +}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, @@ -8,7 +19,7 @@ use std::{ sync::Arc, }; use thiserror::Error; -use tracing::{error, info}; +use tracing::{error, info, warn}; use rocksdb::{Options, WriteBatch, DB}; @@ -34,6 +45,9 @@ pub enum Error { #[error("cbor decoding")] Cbor, + + #[error("unimplemented validation for this era")] + UnimplementedEra, } impl From for Error { @@ -77,7 +91,7 @@ pub struct ApplyBatch<'a> { block_hash: BlockHash, utxo_inserts: HashMap, stxi_inserts: HashMap, - utxo_deletes: Vec, + utxo_deletes: HashMap, } impl<'a> ApplyBatch<'a> { @@ -88,7 +102,7 @@ impl<'a> ApplyBatch<'a> { block_hash, utxo_inserts: HashMap::new(), stxi_inserts: HashMap::new(), - utxo_deletes: Vec::new(), + utxo_deletes: HashMap::new(), } } @@ -96,6 +110,19 @@ impl<'a> ApplyBatch<'a> { self.utxo_inserts.contains_key(&UtxoRef(tx, output)) } + // Meant to be used to get the UTxO associated with a transaction input, assuming the current + // block has already been traversed, appropriately filling utxo_inserts and utxo_deletes. + pub fn get_same_block_utxo(&self, tx_hash: TxHash, ind: OutputIndex) -> Option { + // utxo_inserts contains the UTxOs produced in the current block which haven't been spent. + self.utxo_inserts + .get(&UtxoRef(tx_hash, ind)) + // utxo_deletes contains UTxOs previously stored in the DB, which we don't care + // about, and UTxOs produced (and spent) by transactions in the current block, + // which we care about. + .or(self.utxo_deletes.get(&UtxoRef(tx_hash, ind))) + .map(Vec::::clone) + } + pub fn insert_utxo(&mut self, tx: TxHash, output: OutputIndex, body: UtxoBody) { self.utxo_inserts.insert(UtxoRef(tx, output), body); } @@ -105,8 +132,8 @@ impl<'a> ApplyBatch<'a> { let k = UtxoRef(tx, idx); - self.stxi_inserts.insert(k.clone(), body); - self.utxo_deletes.push(k); + self.stxi_inserts.insert(k.clone(), body.clone()); + self.utxo_deletes.insert(k.clone(), body); } pub fn spend_utxo_same_block(&mut self, tx: TxHash, idx: OutputIndex) { @@ -116,8 +143,8 @@ impl<'a> ApplyBatch<'a> { let body = self.utxo_inserts.remove(&k).unwrap(); - self.stxi_inserts.insert(k.clone(), body); - self.utxo_deletes.push(k) + self.stxi_inserts.insert(k.clone(), body.clone()); + self.utxo_deletes.insert(k.clone(), body); } } @@ -129,7 +156,7 @@ impl<'a> From> for WriteBatch { UtxoKV::stage_upsert(from.db, DBSerde(key), DBBytes(value), &mut batch); } - for key in from.utxo_deletes { + for (key, _) in from.utxo_deletes { UtxoKV::stage_delete(from.db, DBSerde(key), &mut batch); } @@ -272,7 +299,7 @@ impl ApplyDB { Ok(dbval.map(|x| x.0)) } - pub fn apply_block(&mut self, cbor: &[u8]) -> Result<(), Error> { + pub fn apply_block(&mut self, cbor: &[u8], prot_magic: &u32) -> Result<(), Error> { let block = MultiEraBlock::decode(cbor).map_err(|_| Error::Cbor)?; let slot = block.slot(); let hash = block.hash(); @@ -305,6 +332,22 @@ impl ApplyDB { } } + for tx in txs.iter() { + if tx.era() == Era::Byron { + match self.get_inputs(tx, &batch) { + Ok(inputs) => { + let utxos: UTxOs = Self::mk_utxo(&inputs); + let env: Environment = Self::mk_environment(&block, prot_magic)?; + match validate(tx, &utxos, &env) { + Ok(()) => (), + Err(err) => warn!("Transaction validation failed ({:?})", err), + } + } + Err(err) => warn!("Skipping validation ({:?})", err), + } + } + } + let batch = WriteBatch::from(batch); self.db @@ -314,6 +357,90 @@ impl ApplyDB { Ok(()) } + fn get_inputs( + &self, + metx: &MultiEraTx, + batch: &ApplyBatch, + ) -> Result, Error> { + let mut res: Vec<(TxIn, TxOut)> = Vec::new(); + if let MultiEraTx::Byron(mtxp) = &metx { + let tx: &Tx = &mtxp.transaction; + let inputs: &Vec = &tx.inputs; + for input in inputs { + if let TxIn::Variant0(CborWrap((tx_hash, output_index))) = &input { + let hash: TxHash = *tx_hash; + let idx: OutputIndex = *output_index as u64; + // The input UTxO may be in the database or in the same block. + let utxo: UtxoBody = self.get_utxo(hash, idx)?.map_or( + batch + .get_same_block_utxo(hash, idx) + .ok_or(Error::MissingUtxo(hash, idx)), + Ok, + )?; + match MultiEraOutput::decode(Era::Byron, &utxo) { + Ok(tx_out) => res.push(( + TxIn::Variant0(CborWrap((hash, idx as u32))), + tx_out.as_byron().ok_or(Error::UnimplementedEra)?.clone(), + )), + Err(_) => unreachable!(), + } + } + } + } + Ok(res) + } + + fn mk_utxo<'a>(entries: &'a [(TxIn, TxOut)]) -> UTxOs<'a> { + let mut utxos: UTxOs<'a> = UTxOs::new(); + for (input, output) in entries.iter() { + let multi_era_input: MultiEraInput = MultiEraInput::from_byron(input); + let multi_era_output: MultiEraOutput = MultiEraOutput::from_byron(output); + utxos.insert(multi_era_input, multi_era_output); + } + utxos + } + + fn mk_environment(block: &MultiEraBlock, prot_magic: &u32) -> Result { + if block.era() == Era::Byron { + let slot: u64 = block.header().slot(); + if slot <= 322876 { + // These are the genesis values. + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 4096, + }), + prot_magic: *prot_magic, + }) + } else if slot > 322876 && slot <= 1784895 { + // Block hash were the update proposal was submitted: + // 850805044e0df6c13ced2190db7b11489672b0225d478a35a6db71fbfb33afc0 + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 65536, + }), + prot_magic: *prot_magic, + }) + } else { + // Block hash were the update proposal was submitted: + // d798a8d617b25fc6456ffe2d90895a2c15a7271b671dab2d18d46f3d0e4ef495 + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 8192, + }), + prot_magic: *prot_magic, + }) + } + } else { + Err(Error::UnimplementedEra) + } + } + pub fn undo_block(&mut self, cbor: &[u8]) -> Result<(), Error> { let block = MultiEraBlock::decode(cbor).map_err(|_| Error::Cbor)?; let slot = block.slot(); @@ -437,7 +564,7 @@ mod tests { } } - db.apply_block(&cbor).unwrap(); + db.apply_block(&cbor, &764824073).unwrap(); // This is mainnet's protocol magic number. for tx in block.txs() { for input in tx.consumes() { diff --git a/src/sync/ledger.rs b/src/sync/ledger.rs index fa21d72a..2a223da2 100644 --- a/src/sync/ledger.rs +++ b/src/sync/ledger.rs @@ -12,6 +12,7 @@ pub type UpstreamPort = gasket::messaging::tokio::InputPort; pub struct Stage { ledger: ApplyDB, genesis: GenesisFile, + prot_magic: u32, pub upstream: UpstreamPort, @@ -23,10 +24,11 @@ pub struct Stage { } impl Stage { - pub fn new(ledger: ApplyDB, genesis: GenesisFile) -> Self { + pub fn new(ledger: ApplyDB, genesis: GenesisFile, prot_magic: u64) -> Self { Self { ledger, genesis, + prot_magic: prot_magic as u32, upstream: Default::default(), // downstream: Default::default(), block_count: Default::default(), @@ -35,8 +37,6 @@ impl Stage { } } -impl Stage {} - pub struct Worker; #[async_trait::async_trait(?Send)] @@ -58,7 +58,10 @@ impl gasket::framework::Worker for Worker { match unit { RollEvent::Apply(slot, _, cbor) => { info!(slot, "applying block"); - stage.ledger.apply_block(cbor).or_panic()?; + stage + .ledger + .apply_block(cbor, &stage.prot_magic) + .or_panic()?; } RollEvent::Undo(slot, _, cbor) => { info!(slot, "undoing block"); diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 255f0518..42c11a94 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -70,7 +70,7 @@ pub fn pipeline( let mut roll = roll::Stage::new(wal, cursor_chain, cursor_ledger); let mut chain = chain::Stage::new(chain); - let mut ledger = ledger::Stage::new(ledger, genesis); + let mut ledger = ledger::Stage::new(ledger, genesis, config.network_magic); let (to_roll, from_pull) = gasket::messaging::tokio::mpsc_channel(50); pull.downstream.connect(to_roll); From 1bf5a42402273e33b617393ea6ec2850fe691c67 Mon Sep 17 00:00:00 2001 From: Santiago Carmuega Date: Sun, 19 Nov 2023 17:35:16 -0300 Subject: [PATCH 2/4] feat: introduce eval command (#126) --- book/src/SUMMARY.md | 1 + book/src/running/eval.md | 18 ++++++++ src/bin/dolos/data.rs | 30 ++++++++++++ src/bin/dolos/eval.rs | 95 ++++++++++++++++++++++++++++++++++++++ src/bin/dolos/main.rs | 3 ++ src/storage/applydb/mod.rs | 93 +++++++++++++++++++------------------ src/sync/ledger.rs | 2 +- 7 files changed, 196 insertions(+), 46 deletions(-) create mode 100644 book/src/running/eval.md create mode 100644 src/bin/dolos/eval.rs diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 997ba9bc..84fd6b04 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -17,6 +17,7 @@ - [Sync](./running/sync.md) - [Serve](./running/serve.md) - [Daemon](./running/daemon.md) + - [Eval](./running/eval.md) - [API](./api/README.md) - [gRPC](./api/grpc.md) - [Ouroboros](./api/ouroboros.md) diff --git a/book/src/running/eval.md b/book/src/running/eval.md new file mode 100644 index 00000000..5b0ffaa0 --- /dev/null +++ b/book/src/running/eval.md @@ -0,0 +1,18 @@ +# `eval` command + +The `eval` is an utility for evaluating transactions. It takes tx data from an external source and uses the current ledger state to evaluate phase-1 validation rules. + +## Usage + +To execute the evaluation, run the following command from your terminal: + +```bash +dolos eval --file --era --magic --slot +``` + +The args should be interpreted as: + +- `--file `: the path to the file containing the tx data as hex-encoded cbor. +- `--era `: the id of the era that should be used to interpret the transaction data. +- `--magic `: the protocol magic of the network. +- `--slot `: the slot that should be used for retrieving protocol parameters. \ No newline at end of file diff --git a/src/bin/dolos/data.rs b/src/bin/dolos/data.rs index d4e3f722..d32ab8cd 100644 --- a/src/bin/dolos/data.rs +++ b/src/bin/dolos/data.rs @@ -1,3 +1,28 @@ +use std::path::Path; + +use miette::IntoDiagnostic; + +use pallas::{ledger::traverse::MultiEraBlock, storage::rolldb::chain}; + +#[allow(dead_code)] +fn dump_txs(chain: &chain::Store) -> miette::Result<()> { + for header in chain.crawl() { + let (slot, hash) = header.into_diagnostic()?; + println!("dumping {slot}"); + + let block = chain.get_block(hash).into_diagnostic()?.unwrap(); + let block = MultiEraBlock::decode(&block).into_diagnostic()?; + + for tx in block.txs() { + let cbor = hex::encode(tx.encode()); + let path = format!("{}.tx", tx.hash()); + std::fs::write(Path::new(&path), cbor).into_diagnostic()?; + } + } + + Ok(()) +} + #[derive(Debug, clap::Args)] pub struct Args {} @@ -31,5 +56,10 @@ pub fn run(config: &super::Config, _args: &Args) -> miette::Result<()> { println!("chain is empty"); } + // WIP utility to dump tx data for debugging purposes. Should be implemented as + // a subcommand. + + // dump_txs(&chain)?; + Ok(()) } diff --git a/src/bin/dolos/eval.rs b/src/bin/dolos/eval.rs new file mode 100644 index 00000000..9bc218af --- /dev/null +++ b/src/bin/dolos/eval.rs @@ -0,0 +1,95 @@ +use miette::{Context, IntoDiagnostic}; +use pallas::{ + applying::{validate, Environment, UTxOs}, + ledger::{ + primitives::byron::TxIn, + traverse::{Era, MultiEraInput, MultiEraOutput, MultiEraTx}, + }, +}; +use std::path::PathBuf; + +use dolos::storage::applydb::ApplyDB; + +#[derive(Debug, clap::Args)] +pub struct Args { + #[arg(long, short)] + file: PathBuf, + + #[arg(long, short)] + era: u16, + + #[arg(long, short)] + magic: u32, + + #[arg(long, short)] + slot: u64, +} + +type ResolveInputs = Vec<(TxIn, Vec)>; + +pub fn resolve_inputs(tx: &MultiEraTx<'_>, ledger: &ApplyDB) -> miette::Result { + let mut set = vec![]; + + for input in tx.inputs() { + let hash = input.hash(); + let idx = input.index(); + + let bytes = ledger + .get_utxo(*hash, idx) + .into_diagnostic() + .context("fetching utxo from ledger")? + .ok_or(miette::miette!("utxo not found"))?; + + //TODO: allow to pass extra utxos manually, to mimic what happens when + // consuming utxos from the same block; + + let txin = pallas::ledger::primitives::byron::TxIn::Variant0( + pallas::codec::utils::CborWrap((*hash, idx as u32)), + ); + + set.push((txin, bytes)); + } + + Ok(set) +} + +pub fn run(config: &super::Config, args: &Args) -> miette::Result<()> { + crate::common::setup_tracing(&config.logging)?; + + let (_, _, ledger) = crate::common::open_data_stores(config)?; + + let cbor = std::fs::read_to_string(&args.file) + .into_diagnostic() + .context("reading tx from file")?; + + let cbor = hex::decode(&cbor) + .into_diagnostic() + .context("decoding hex content from file")?; + + let era = Era::try_from(args.era).unwrap(); + + let tx = pallas::ledger::traverse::MultiEraTx::decode_for_era(era, &cbor) + .into_diagnostic() + .context("decoding tx cbor")?; + + let mut utxos: UTxOs = UTxOs::new(); + let resolved = resolve_inputs(&tx, &ledger)?; + + for (input, output) in resolved.iter() { + let key = MultiEraInput::from_byron(&input); + + let value = MultiEraOutput::decode(Era::Byron, &output) + .into_diagnostic() + .context("decoding utxo cbor")?; + + utxos.insert(key, value); + } + + let env: Environment = ApplyDB::mk_environment(args.slot, args.magic) + .into_diagnostic() + .context("resolving pparams")?; + + validate(&tx, &utxos, &env).unwrap(); + + Ok(()) +} diff --git a/src/bin/dolos/main.rs b/src/bin/dolos/main.rs index 1da25113..1cde90d4 100644 --- a/src/bin/dolos/main.rs +++ b/src/bin/dolos/main.rs @@ -7,6 +7,7 @@ use std::path::PathBuf; mod common; mod daemon; mod data; +mod eval; mod serve; mod sync; @@ -16,6 +17,7 @@ enum Command { Sync(sync::Args), Data(data::Args), Serve(serve::Args), + Eval(eval::Args), } #[derive(Debug, Parser)] @@ -99,6 +101,7 @@ fn main() -> Result<()> { Command::Sync(x) => sync::run(&config, &x)?, Command::Data(x) => data::run(&config, &x)?, Command::Serve(x) => serve::run(config, &x)?, + Command::Eval(x) => eval::run(&config, &x)?, }; Ok(()) diff --git a/src/storage/applydb/mod.rs b/src/storage/applydb/mod.rs index 15ed1a06..cbeef428 100644 --- a/src/storage/applydb/mod.rs +++ b/src/storage/applydb/mod.rs @@ -110,10 +110,12 @@ impl<'a> ApplyBatch<'a> { self.utxo_inserts.contains_key(&UtxoRef(tx, output)) } - // Meant to be used to get the UTxO associated with a transaction input, assuming the current - // block has already been traversed, appropriately filling utxo_inserts and utxo_deletes. + // Meant to be used to get the UTxO associated with a transaction input, + // assuming the current block has already been traversed, appropriately + // filling utxo_inserts and utxo_deletes. pub fn get_same_block_utxo(&self, tx_hash: TxHash, ind: OutputIndex) -> Option { - // utxo_inserts contains the UTxOs produced in the current block which haven't been spent. + // utxo_inserts contains the UTxOs produced in the current block which haven't + // been spent. self.utxo_inserts .get(&UtxoRef(tx_hash, ind)) // utxo_deletes contains UTxOs previously stored in the DB, which we don't care @@ -299,7 +301,7 @@ impl ApplyDB { Ok(dbval.map(|x| x.0)) } - pub fn apply_block(&mut self, cbor: &[u8], prot_magic: &u32) -> Result<(), Error> { + pub fn apply_block(&mut self, cbor: &[u8], prot_magic: u32) -> Result<(), Error> { let block = MultiEraBlock::decode(cbor).map_err(|_| Error::Cbor)?; let slot = block.slot(); let hash = block.hash(); @@ -332,12 +334,13 @@ impl ApplyDB { } } + // TODO: move out of storage for tx in txs.iter() { if tx.era() == Era::Byron { match self.get_inputs(tx, &batch) { Ok(inputs) => { let utxos: UTxOs = Self::mk_utxo(&inputs); - let env: Environment = Self::mk_environment(&block, prot_magic)?; + let env: Environment = Self::mk_environment(block.slot(), prot_magic)?; match validate(tx, &utxos, &env) { Ok(()) => (), Err(err) => warn!("Transaction validation failed ({:?})", err), @@ -357,7 +360,8 @@ impl ApplyDB { Ok(()) } - fn get_inputs( + // TODO: move out of storage + pub fn get_inputs( &self, metx: &MultiEraTx, batch: &ApplyBatch, @@ -390,7 +394,8 @@ impl ApplyDB { Ok(res) } - fn mk_utxo<'a>(entries: &'a [(TxIn, TxOut)]) -> UTxOs<'a> { + // TODO: move out of storage + pub fn mk_utxo<'a>(entries: &'a [(TxIn, TxOut)]) -> UTxOs<'a> { let mut utxos: UTxOs<'a> = UTxOs::new(); for (input, output) in entries.iter() { let multi_era_input: MultiEraInput = MultiEraInput::from_byron(input); @@ -400,44 +405,42 @@ impl ApplyDB { utxos } - fn mk_environment(block: &MultiEraBlock, prot_magic: &u32) -> Result { - if block.era() == Era::Byron { - let slot: u64 = block.header().slot(); - if slot <= 322876 { - // These are the genesis values. - Ok(Environment { - prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, - max_tx_size: 4096, - }), - prot_magic: *prot_magic, - }) - } else if slot > 322876 && slot <= 1784895 { - // Block hash were the update proposal was submitted: - // 850805044e0df6c13ced2190db7b11489672b0225d478a35a6db71fbfb33afc0 - Ok(Environment { - prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, - max_tx_size: 65536, - }), - prot_magic: *prot_magic, - }) - } else { - // Block hash were the update proposal was submitted: - // d798a8d617b25fc6456ffe2d90895a2c15a7271b671dab2d18d46f3d0e4ef495 - Ok(Environment { - prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, - max_tx_size: 8192, - }), - prot_magic: *prot_magic, - }) - } + // TODO: move out of storage + pub fn mk_environment(slot: u64, prot_magic: u32) -> Result { + if slot <= 322876 { + // These are the genesis values. + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 4096, + }), + prot_magic, + }) + } else if slot > 322876 && slot <= 1784895 { + // Block hash were the update proposal was submitted: + // 850805044e0df6c13ced2190db7b11489672b0225d478a35a6db71fbfb33afc0 + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 65536, + }), + prot_magic, + }) + } else if slot < 4492800 { + // Block hash were the update proposal was submitted: + // d798a8d617b25fc6456ffe2d90895a2c15a7271b671dab2d18d46f3d0e4ef495 + Ok(Environment { + prot_params: MultiEraProtParams::Byron(ByronProtParams { + min_fees_const: 155381, + min_fees_factor: 44, + max_tx_size: 8192, + }), + prot_magic, + }) } else { - Err(Error::UnimplementedEra) + unimplemented!("we don't have pparams after byron") } } @@ -564,7 +567,7 @@ mod tests { } } - db.apply_block(&cbor, &764824073).unwrap(); // This is mainnet's protocol magic number. + db.apply_block(&cbor, 764824073).unwrap(); // This is mainnet's protocol magic number. for tx in block.txs() { for input in tx.consumes() { diff --git a/src/sync/ledger.rs b/src/sync/ledger.rs index 2a223da2..d46fc357 100644 --- a/src/sync/ledger.rs +++ b/src/sync/ledger.rs @@ -60,7 +60,7 @@ impl gasket::framework::Worker for Worker { info!(slot, "applying block"); stage .ledger - .apply_block(cbor, &stage.prot_magic) + .apply_block(cbor, stage.prot_magic) .or_panic()?; } RollEvent::Undo(slot, _, cbor) => { From 1d853c88a7c81982e03dc2b2a4d695da5e4177d1 Mon Sep 17 00:00:00 2001 From: Santiago Carmuega Date: Sun, 19 Nov 2023 18:02:27 -0300 Subject: [PATCH 3/4] chore: fix lint warnings --- src/bin/dolos/eval.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/dolos/eval.rs b/src/bin/dolos/eval.rs index 9bc218af..f1fa40fa 100644 --- a/src/bin/dolos/eval.rs +++ b/src/bin/dolos/eval.rs @@ -76,9 +76,9 @@ pub fn run(config: &super::Config, args: &Args) -> miette::Result<()> { let resolved = resolve_inputs(&tx, &ledger)?; for (input, output) in resolved.iter() { - let key = MultiEraInput::from_byron(&input); + let key = MultiEraInput::from_byron(input); - let value = MultiEraOutput::decode(Era::Byron, &output) + let value = MultiEraOutput::decode(Era::Byron, output) .into_diagnostic() .context("decoding utxo cbor")?; From 638de6b153bbc2bff56675c4ecd0a5aabe8679dc Mon Sep 17 00:00:00 2001 From: Santiago Carmuega Date: Tue, 12 Dec 2023 18:11:30 -0300 Subject: [PATCH 4/4] refactor: move validation out of storage (#132) Co-authored-by: Maico --- Cargo.lock | 446 +++++++++++++++---------------- examples/sync-mainnet/dolos.toml | 1 + examples/sync-preprod/dolos.toml | 1 + examples/sync-preview/dolos.toml | 1 + src/bin/dolos/bootstrap.rs | 2 +- src/bin/dolos/common.rs | 7 +- src/bin/dolos/eval.rs | 74 ++--- src/model.rs | 4 +- src/storage/applydb/genesis.rs | 14 +- src/storage/applydb/mod.rs | 201 +++++++------- src/sync/ledger.rs | 61 ++++- src/sync/mod.rs | 7 +- 12 files changed, 424 insertions(+), 395 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32af0377..f19cc91f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -63,30 +63,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -103,7 +103,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -125,18 +125,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -234,9 +234,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -293,7 +293,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -322,9 +322,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "blake2" @@ -455,9 +455,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -465,9 +465,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -477,21 +477,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -501,9 +501,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "lazy_static", @@ -538,9 +538,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" @@ -636,6 +636,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -687,7 +693,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -711,7 +717,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -722,7 +728,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -737,9 +743,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", "serde", @@ -901,7 +907,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "windows-sys 0.52.0", ] @@ -913,7 +919,7 @@ checksum = "02c69ce7e7c0f17aa18fdd9d0de39727adb9c6281f2ad12f57cbe54ae6e76e7d" dependencies = [ "az", "bytemuck", - "half", + "half 2.3.1", "typenum", ] @@ -942,7 +948,7 @@ dependencies = [ "futures-core", "futures-sink", "nanorand", - "spin 0.9.8", + "spin", ] [[package]] @@ -977,9 +983,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -992,9 +998,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1002,15 +1008,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -1025,32 +1031,32 @@ checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -1087,7 +1093,7 @@ checksum = "d114a9d0572b1b505ac26bdcd669218b2ab5861d1b36ff72da4011dcc8725169" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -1102,9 +1108,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "js-sys", @@ -1115,9 +1121,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -1137,9 +1143,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -1147,7 +1153,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1160,6 +1166,16 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "half" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1168,9 +1184,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -1201,9 +1217,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1212,9 +1228,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1256,7 +1272,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -1319,9 +1335,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1340,12 +1356,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.1", + "hashbrown 0.14.3", "serde", ] @@ -1389,9 +1405,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" @@ -1404,9 +1420,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1448,9 +1464,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libloading" @@ -1559,7 +1575,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -1574,7 +1590,7 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7005aaf257a59ff4de471a9d5538ec868a21586534fff7f85dd97d4043a6139" dependencies = [ - "half", + "half 1.8.2", "minicbor-derive", ] @@ -1606,9 +1622,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -1816,9 +1832,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -1832,7 +1848,7 @@ version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -1849,7 +1865,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -1885,7 +1901,7 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "pallas" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "pallas-addresses", "pallas-applying", @@ -1905,7 +1921,7 @@ dependencies = [ [[package]] name = "pallas-addresses" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "base58", "bech32 0.9.1", @@ -1920,7 +1936,7 @@ dependencies = [ [[package]] name = "pallas-applying" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "pallas-addresses", "pallas-codec 0.20.0 (git+https://github.com/txpipe/pallas.git)", @@ -1945,7 +1961,7 @@ dependencies = [ [[package]] name = "pallas-codec" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "hex", "minicbor", @@ -1956,9 +1972,9 @@ dependencies = [ [[package]] name = "pallas-configs" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "hex", "pallas-addresses", "pallas-codec 0.20.0 (git+https://github.com/txpipe/pallas.git)", @@ -1984,7 +2000,7 @@ dependencies = [ [[package]] name = "pallas-crypto" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "cryptoxide", "hex", @@ -1997,7 +2013,7 @@ dependencies = [ [[package]] name = "pallas-hardano" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "binary-layout", "tap", @@ -2023,7 +2039,7 @@ dependencies = [ [[package]] name = "pallas-network" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "byteorder", "hex", @@ -2038,7 +2054,7 @@ dependencies = [ [[package]] name = "pallas-primitives" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "base58", "bech32 0.9.1", @@ -2053,7 +2069,7 @@ dependencies = [ [[package]] name = "pallas-rolldb" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "async-stream", "bincode", @@ -2070,7 +2086,7 @@ dependencies = [ [[package]] name = "pallas-traverse" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "hex", "pallas-addresses", @@ -2084,7 +2100,7 @@ dependencies = [ [[package]] name = "pallas-txbuilder" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "hex", "pallas-addresses", @@ -2100,7 +2116,7 @@ dependencies = [ [[package]] name = "pallas-utxorpc" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "pallas-codec 0.20.0 (git+https://github.com/txpipe/pallas.git)", "pallas-primitives", @@ -2111,7 +2127,7 @@ dependencies = [ [[package]] name = "pallas-wallet" version = "0.20.0" -source = "git+https://github.com/txpipe/pallas.git#472692c4fa32d35ce5a5873931e3bde432b8ab51" +source = "git+https://github.com/txpipe/pallas.git#04232c6a4ceea115293cb13bd2928ae2eee88daf" dependencies = [ "bech32 0.9.1", "bip39", @@ -2178,9 +2194,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -2189,7 +2205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.2", + "indexmap 2.1.0", ] [[package]] @@ -2209,7 +2225,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -2275,14 +2291,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -2406,15 +2422,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2426,9 +2433,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -2438,9 +2445,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -2449,9 +2456,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d84fdd47036b038fc80dd333d10b6aab10d5d31f4a366e20014def75328d33" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" @@ -2459,7 +2466,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -2495,17 +2502,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.20" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", - "spin 0.5.2", + "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2556,7 +2562,7 @@ version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -2565,9 +2571,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", @@ -2577,18 +2583,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", "untrusted", @@ -2602,9 +2608,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -2632,9 +2638,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -2693,7 +2699,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half", + "half 1.8.2", "serde", ] @@ -2705,14 +2711,14 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -2753,11 +2759,11 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_json", "serde_with_macros 3.4.0", @@ -2773,7 +2779,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -2785,7 +2791,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -2794,7 +2800,7 @@ version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "itoa", "ryu", "serde", @@ -2872,9 +2878,9 @@ checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smawk" @@ -2884,9 +2890,9 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -2894,20 +2900,14 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -2982,7 +2982,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -3032,9 +3032,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -3087,13 +3087,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys 0.48.0", ] @@ -3121,22 +3121,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -3204,9 +3204,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -3215,7 +3215,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] @@ -3232,13 +3232,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -3275,9 +3275,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3305,7 +3305,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.4", + "base64 0.21.5", "bytes", "futures-core", "futures-util", @@ -3333,7 +3333,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b00ec4842256d1fe0a46176e2ef5bc357664c66e7d91aff5a7d43d83a65f47" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "futures-core", "http", @@ -3373,7 +3373,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "bytes", "futures-core", "futures-util", @@ -3416,7 +3416,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -3431,20 +3431,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -3456,9 +3456,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" @@ -3487,7 +3487,7 @@ checksum = "2eea6765137e2414c44c7b1e07c73965a118a72c46148e1e168b3fc9d3ccf3aa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] @@ -3531,15 +3531,15 @@ checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -3644,9 +3644,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3654,24 +3654,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -3681,9 +3681,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3691,22 +3691,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-streams" @@ -3723,9 +3723,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4010,7 +4010,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.40", ] [[package]] diff --git a/examples/sync-mainnet/dolos.toml b/examples/sync-mainnet/dolos.toml index 728cc438..c1acffd6 100644 --- a/examples/sync-mainnet/dolos.toml +++ b/examples/sync-mainnet/dolos.toml @@ -1,6 +1,7 @@ [upstream] peer_address = "relays-new.cardano-mainnet.iohk.io:3001" network_magic = 764824073 +network_id = 1 [rolldb] path = "./tmp/rolldb" diff --git a/examples/sync-preprod/dolos.toml b/examples/sync-preprod/dolos.toml index 8815b0d6..1fe33d59 100644 --- a/examples/sync-preprod/dolos.toml +++ b/examples/sync-preprod/dolos.toml @@ -1,6 +1,7 @@ [upstream] peer_address = "preprod-node.world.dev.cardano.org:30000" network_magic = 1 +network_id = 0 [rolldb] path = "./tmp/rolldb" diff --git a/examples/sync-preview/dolos.toml b/examples/sync-preview/dolos.toml index f28d77cf..7bbec484 100644 --- a/examples/sync-preview/dolos.toml +++ b/examples/sync-preview/dolos.toml @@ -1,6 +1,7 @@ [upstream] peer_address = "preview-node.world.dev.cardano.org:30002" network_magic = 2 +network_id = 0 [rolldb] path = "./tmp/rolldb" diff --git a/src/bin/dolos/bootstrap.rs b/src/bin/dolos/bootstrap.rs index 6596d565..533d2ccc 100644 --- a/src/bin/dolos/bootstrap.rs +++ b/src/bin/dolos/bootstrap.rs @@ -179,7 +179,7 @@ pub fn run(config: &super::Config, args: &Args) -> miette::Result<()> { .context("adding chain entry")?; ledger - .apply_block(&block) + .apply_block(&blockd) .into_diagnostic() .context("applyting ledger block")?; } diff --git a/src/bin/dolos/common.rs b/src/bin/dolos/common.rs index 29687129..e89f229c 100644 --- a/src/bin/dolos/common.rs +++ b/src/bin/dolos/common.rs @@ -28,7 +28,12 @@ pub fn open_data_stores(config: &crate::Config) -> Result { let chain = chain::Store::open(rolldb_path.join("chain")).map_err(Error::storage)?; - let ledger = ApplyDB::open(rolldb_path.join("ledger")).map_err(Error::storage)?; + let ledger = ApplyDB::open( + rolldb_path.join("ledger"), + config.upstream.network_magic as u32, + config.upstream.network_id, + ) + .map_err(Error::storage)?; Ok((wal, chain, ledger)) } diff --git a/src/bin/dolos/eval.rs b/src/bin/dolos/eval.rs index f1fa40fa..19d6ad20 100644 --- a/src/bin/dolos/eval.rs +++ b/src/bin/dolos/eval.rs @@ -1,14 +1,9 @@ use miette::{Context, IntoDiagnostic}; use pallas::{ applying::{validate, Environment, UTxOs}, - ledger::{ - primitives::byron::TxIn, - traverse::{Era, MultiEraInput, MultiEraOutput, MultiEraTx}, - }, + ledger::traverse::{Era, MultiEraInput, MultiEraOutput}, }; -use std::path::PathBuf; - -use dolos::storage::applydb::ApplyDB; +use std::{borrow::Cow, collections::HashMap, path::PathBuf}; #[derive(Debug, clap::Args)] pub struct Args { @@ -18,41 +13,10 @@ pub struct Args { #[arg(long, short)] era: u16, - #[arg(long, short)] - magic: u32, - #[arg(long, short)] slot: u64, } -type ResolveInputs = Vec<(TxIn, Vec)>; - -pub fn resolve_inputs(tx: &MultiEraTx<'_>, ledger: &ApplyDB) -> miette::Result { - let mut set = vec![]; - - for input in tx.inputs() { - let hash = input.hash(); - let idx = input.index(); - - let bytes = ledger - .get_utxo(*hash, idx) - .into_diagnostic() - .context("fetching utxo from ledger")? - .ok_or(miette::miette!("utxo not found"))?; - - //TODO: allow to pass extra utxos manually, to mimic what happens when - // consuming utxos from the same block; - - let txin = pallas::ledger::primitives::byron::TxIn::Variant0( - pallas::codec::utils::CborWrap((*hash, idx as u32)), - ); - - set.push((txin, bytes)); - } - - Ok(set) -} - pub fn run(config: &super::Config, args: &Args) -> miette::Result<()> { crate::common::setup_tracing(&config.logging)?; @@ -72,24 +36,40 @@ pub fn run(config: &super::Config, args: &Args) -> miette::Result<()> { .into_diagnostic() .context("decoding tx cbor")?; - let mut utxos: UTxOs = UTxOs::new(); - let resolved = resolve_inputs(&tx, &ledger)?; + let mut utxos = HashMap::new(); + ledger + .resolve_inputs_for_tx(&tx, &mut utxos) + .into_diagnostic() + .context("resolving tx inputs")?; + + let mut utxos2 = UTxOs::new(); - for (input, output) in resolved.iter() { - let key = MultiEraInput::from_byron(input); + for (ref_, output) in utxos.iter() { + let txin = pallas::ledger::primitives::byron::TxIn::Variant0( + pallas::codec::utils::CborWrap((ref_.0.clone(), ref_.1 as u32)), + ); + + let key = MultiEraInput::Byron( + >>::from(Cow::Owned(txin)), + ); + + let era = Era::try_from(output.0) + .into_diagnostic() + .context("parsing era")?; - let value = MultiEraOutput::decode(Era::Byron, output) + let value = MultiEraOutput::decode(era, &output.1) .into_diagnostic() - .context("decoding utxo cbor")?; + .context("decoding utxo")?; - utxos.insert(key, value); + utxos2.insert(key, value); } - let env: Environment = ApplyDB::mk_environment(args.slot, args.magic) + let env: Environment = ledger + .get_active_pparams(args.slot) .into_diagnostic() .context("resolving pparams")?; - validate(&tx, &utxos, &env).unwrap(); + validate(&tx, &utxos2, &env).unwrap(); Ok(()) } diff --git a/src/model.rs b/src/model.rs index d21afd04..0e37f601 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,11 +1,11 @@ -use pallas::{crypto::hash::Hash, ledger::traverse::Era, network::miniprotocols::Point}; +use pallas::{crypto::hash::Hash, network::miniprotocols::Point}; pub type BlockSlot = u64; pub type BlockHash = Hash<32>; pub type RawBlock = Vec; pub type TxHash = Hash<32>; pub type OutputIdx = u64; -pub type UtxoBody = (Era, Vec); +pub type UtxoBody = (u16, Vec); // #[derive(Debug, Clone)] // pub struct BlockWithContext { diff --git a/src/storage/applydb/genesis.rs b/src/storage/applydb/genesis.rs index b83190ba..9e22d8e1 100644 --- a/src/storage/applydb/genesis.rs +++ b/src/storage/applydb/genesis.rs @@ -6,7 +6,7 @@ use tracing::info; use crate::{ prelude::*, - storage::kvtable::{DBBytes, DBSerde, KVTable}, + storage::kvtable::{DBSerde, KVTable}, }; use super::{ApplyDB, UtxoKV, UtxoRef}; @@ -21,14 +21,14 @@ fn build_byron_txout(addr: ByronAddress, amount: u64) -> TxOut { } } -fn genesis_utxo_to_kv(utxo: GenesisUtxo) -> Result<(DBSerde, DBBytes), Error> { +fn genesis_utxo_to_kv(utxo: GenesisUtxo) -> Result<(DBSerde, DBSerde), Error> { let (tx, addr, amount) = utxo; let key = DBSerde(UtxoRef(tx, 0)); let txout = build_byron_txout(addr, amount); let txout = pallas::codec::minicbor::to_vec(txout).map_err(Error::config)?; - let value = DBBytes(txout); + let value = DBSerde((0u16, txout)); Ok((key, value)) } @@ -64,10 +64,12 @@ mod tests { fn assert_genesis_utxo_exists(db: &ApplyDB, tx_hex: &str, addr_base58: &str, amount: u64) { let tx = Hash::<32>::from_str(tx_hex).unwrap(); - let cbor = db.get_utxo(tx, 0).unwrap(); + let utxo_body = db.get_utxo(tx, 0).unwrap(); - assert!(cbor.is_some(), "utxo not found"); - let cbor = cbor.unwrap(); + assert!(utxo_body.is_some(), "utxo not found"); + let (era, cbor) = utxo_body.unwrap(); + + assert_eq!(era, 0); let txout: Result = pallas::codec::minicbor::decode(&cbor); diff --git a/src/storage/applydb/mod.rs b/src/storage/applydb/mod.rs index cbeef428..4e019085 100644 --- a/src/storage/applydb/mod.rs +++ b/src/storage/applydb/mod.rs @@ -1,16 +1,9 @@ pub mod genesis; use pallas::{ - applying::{ - types::{ByronProtParams, Environment, MultiEraProtParams, UTxOs}, - validate, - }, - codec::utils::CborWrap, + applying::types::{ByronProtParams, Environment, FeePolicy, MultiEraProtParams}, crypto::hash::Hash, - ledger::{ - primitives::byron::{Tx, TxIn, TxOut}, - traverse::{Era, MultiEraBlock, MultiEraInput, MultiEraOutput, MultiEraTx}, - }, + ledger::traverse::{MultiEraBlock, MultiEraTx}, }; use serde::{Deserialize, Serialize}; use std::{ @@ -19,7 +12,7 @@ use std::{ sync::Arc, }; use thiserror::Error; -use tracing::{error, info, warn}; +use tracing::{error, info}; use rocksdb::{Options, WriteBatch, DB}; @@ -29,7 +22,7 @@ use super::kvtable::*; type TxHash = Hash<32>; type OutputIndex = u64; -type UtxoBody = Vec; +type UtxoBody = (u16, Vec); type BlockSlot = u64; #[derive(Error, Debug)] @@ -61,14 +54,14 @@ pub struct UtxoRef(pub TxHash, pub OutputIndex); pub struct UtxoKV; -impl KVTable, DBBytes> for UtxoKV { +impl KVTable, DBSerde> for UtxoKV { const CF_NAME: &'static str = "UtxoKV"; } // Spent transaction inputs pub struct StxiKV; -impl KVTable, DBBytes> for StxiKV { +impl KVTable, DBSerde> for StxiKV { const CF_NAME: &'static str = "StxiKV"; } @@ -122,7 +115,7 @@ impl<'a> ApplyBatch<'a> { // about, and UTxOs produced (and spent) by transactions in the current block, // which we care about. .or(self.utxo_deletes.get(&UtxoRef(tx_hash, ind))) - .map(Vec::::clone) + .map(Clone::clone) } pub fn insert_utxo(&mut self, tx: TxHash, output: OutputIndex, body: UtxoBody) { @@ -155,7 +148,7 @@ impl<'a> From> for WriteBatch { let mut batch = WriteBatch::default(); for (key, value) in from.utxo_inserts { - UtxoKV::stage_upsert(from.db, DBSerde(key), DBBytes(value), &mut batch); + UtxoKV::stage_upsert(from.db, DBSerde(key), DBSerde(value), &mut batch); } for (key, _) in from.utxo_deletes { @@ -163,7 +156,7 @@ impl<'a> From> for WriteBatch { } for (key, value) in from.stxi_inserts { - StxiKV::stage_upsert(from.db, DBSerde(key), DBBytes(value), &mut batch); + StxiKV::stage_upsert(from.db, DBSerde(key), DBSerde(value), &mut batch); } let k = DBInt(from.block_slot); @@ -241,7 +234,7 @@ impl<'a> From> for WriteBatch { let mut batch = WriteBatch::default(); for (key, value) in from.utxo_recovery { - UtxoKV::stage_upsert(from.db, DBSerde(key), DBBytes(value), &mut batch); + UtxoKV::stage_upsert(from.db, DBSerde(key), DBSerde(value), &mut batch); } for key in from.utxo_deletes { @@ -262,10 +255,14 @@ impl<'a> From> for WriteBatch { #[derive(Clone)] pub struct ApplyDB { db: Arc, + + // TODO: should be extracted from genesis config data + prot_magic: u32, + network_id: u8, } impl ApplyDB { - pub fn open(path: impl AsRef) -> Result { + pub fn open(path: impl AsRef, prot_magic: u32, network_id: u8) -> Result { let mut opts = Options::default(); opts.create_if_missing(true); opts.create_missing_column_families(true); @@ -277,7 +274,11 @@ impl ApplyDB { ) .map_err(|_| super::kvtable::Error::IO)?; - Ok(Self { db: Arc::new(db) }) + Ok(Self { + db: Arc::new(db), + prot_magic, + network_id, + }) } pub fn is_empty(&self) -> bool { @@ -301,8 +302,52 @@ impl ApplyDB { Ok(dbval.map(|x| x.0)) } - pub fn apply_block(&mut self, cbor: &[u8], prot_magic: u32) -> Result<(), Error> { - let block = MultiEraBlock::decode(cbor).map_err(|_| Error::Cbor)?; + pub fn resolve_inputs_for_tx( + &self, + tx: &MultiEraTx<'_>, + utxos: &mut HashMap, + ) -> Result<(), Error> { + for consumed in tx.consumes() { + let hash = *consumed.hash(); + let idx = consumed.index(); + + let utxo_ref = UtxoRef(hash, idx); + + if !utxos.contains_key(&utxo_ref) { + let utxo = self + .get_utxo(hash, idx)? + .ok_or(Error::MissingUtxo(hash, idx))?; + + utxos.insert(utxo_ref, utxo); + }; + } + + Ok(()) + } + + pub fn resolve_inputs_for_block( + &self, + block: &MultiEraBlock<'_>, + utxos: &mut HashMap, + ) -> Result<(), Error> { + let txs = block.txs(); + + for tx in txs.iter() { + for (idx, produced) in tx.produces() { + let body = produced.encode(); + let era = tx.era().into(); + utxos.insert(UtxoRef(tx.hash(), idx as u64), (era, body)); + } + } + + for tx in txs.iter() { + self.resolve_inputs_for_tx(tx, utxos)?; + } + + Ok(()) + } + + pub fn apply_block(&mut self, block: &MultiEraBlock<'_>) -> Result<(), Error> { let slot = block.slot(); let hash = block.hash(); @@ -313,7 +358,8 @@ impl ApplyDB { for tx in txs.iter() { for (idx, produced) in tx.produces() { let body = produced.encode(); - batch.insert_utxo(tx.hash(), idx as u64, body); + let era = tx.era().into(); + batch.insert_utxo(tx.hash(), idx as u64, (era, body)); } } @@ -334,23 +380,6 @@ impl ApplyDB { } } - // TODO: move out of storage - for tx in txs.iter() { - if tx.era() == Era::Byron { - match self.get_inputs(tx, &batch) { - Ok(inputs) => { - let utxos: UTxOs = Self::mk_utxo(&inputs); - let env: Environment = Self::mk_environment(block.slot(), prot_magic)?; - match validate(tx, &utxos, &env) { - Ok(()) => (), - Err(err) => warn!("Transaction validation failed ({:?})", err), - } - } - Err(err) => warn!("Skipping validation ({:?})", err), - } - } - } - let batch = WriteBatch::from(batch); self.db @@ -360,87 +389,53 @@ impl ApplyDB { Ok(()) } - // TODO: move out of storage - pub fn get_inputs( - &self, - metx: &MultiEraTx, - batch: &ApplyBatch, - ) -> Result, Error> { - let mut res: Vec<(TxIn, TxOut)> = Vec::new(); - if let MultiEraTx::Byron(mtxp) = &metx { - let tx: &Tx = &mtxp.transaction; - let inputs: &Vec = &tx.inputs; - for input in inputs { - if let TxIn::Variant0(CborWrap((tx_hash, output_index))) = &input { - let hash: TxHash = *tx_hash; - let idx: OutputIndex = *output_index as u64; - // The input UTxO may be in the database or in the same block. - let utxo: UtxoBody = self.get_utxo(hash, idx)?.map_or( - batch - .get_same_block_utxo(hash, idx) - .ok_or(Error::MissingUtxo(hash, idx)), - Ok, - )?; - match MultiEraOutput::decode(Era::Byron, &utxo) { - Ok(tx_out) => res.push(( - TxIn::Variant0(CborWrap((hash, idx as u32))), - tx_out.as_byron().ok_or(Error::UnimplementedEra)?.clone(), - )), - Err(_) => unreachable!(), - } - } - } - } - Ok(res) - } - - // TODO: move out of storage - pub fn mk_utxo<'a>(entries: &'a [(TxIn, TxOut)]) -> UTxOs<'a> { - let mut utxos: UTxOs<'a> = UTxOs::new(); - for (input, output) in entries.iter() { - let multi_era_input: MultiEraInput = MultiEraInput::from_byron(input); - let multi_era_output: MultiEraOutput = MultiEraOutput::from_byron(output); - utxos.insert(multi_era_input, multi_era_output); - } - utxos - } - - // TODO: move out of storage - pub fn mk_environment(slot: u64, prot_magic: u32) -> Result { - if slot <= 322876 { + pub fn get_active_pparams(&self, block_slot: u64) -> Result { + if block_slot <= 322876 { // These are the genesis values. Ok(Environment { prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, + fee_policy: FeePolicy { + summand: 155381, + multiplier: 44, + }, max_tx_size: 4096, }), - prot_magic, + block_slot, + prot_magic: self.prot_magic, + network_id: self.network_id, }) - } else if slot > 322876 && slot <= 1784895 { + } else if block_slot > 322876 && block_slot <= 1784895 { // Block hash were the update proposal was submitted: // 850805044e0df6c13ced2190db7b11489672b0225d478a35a6db71fbfb33afc0 Ok(Environment { prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, + fee_policy: FeePolicy { + summand: 155381, + multiplier: 44, + }, max_tx_size: 65536, }), - prot_magic, + block_slot, + prot_magic: self.prot_magic, + network_id: self.network_id, }) - } else if slot < 4492800 { + } else if block_slot < 4492800 { // Block hash were the update proposal was submitted: // d798a8d617b25fc6456ffe2d90895a2c15a7271b671dab2d18d46f3d0e4ef495 Ok(Environment { prot_params: MultiEraProtParams::Byron(ByronProtParams { - min_fees_const: 155381, - min_fees_factor: 44, + fee_policy: FeePolicy { + summand: 155381, + multiplier: 44, + }, max_tx_size: 8192, }), - prot_magic, + block_slot, + prot_magic: self.prot_magic, + network_id: self.network_id, }) } else { - unimplemented!("we don't have pparams after byron") + Err(Error::UnimplementedEra) } } @@ -502,7 +497,7 @@ impl ApplyDB { UtxoKV::stage_upsert( &self.db, DBSerde(UtxoRef(hash, index)), - DBBytes(vec![]), + DBSerde((1, vec![])), &mut batch, ); @@ -516,7 +511,7 @@ impl ApplyDB { StxiKV::stage_upsert( &self.db, DBSerde(UtxoRef(hash, index)), - DBBytes(vec![]), + DBSerde((1, vec![])), &mut batch, ); @@ -530,7 +525,7 @@ mod tests { pub fn with_tmp_db(op: fn(db: ApplyDB) -> ()) { let path = tempfile::tempdir().unwrap().into_path(); - let db = ApplyDB::open(path.clone()).unwrap(); + let db = ApplyDB::open(path.clone(), 764824073, 1).unwrap(); op(db); @@ -567,7 +562,7 @@ mod tests { } } - db.apply_block(&cbor, 764824073).unwrap(); // This is mainnet's protocol magic number. + db.apply_block(&block).unwrap(); for tx in block.txs() { for input in tx.consumes() { diff --git a/src/sync/ledger.rs b/src/sync/ledger.rs index d46fc357..4fc5ffa2 100644 --- a/src/sync/ledger.rs +++ b/src/sync/ledger.rs @@ -1,10 +1,54 @@ +use std::borrow::Cow; +use std::collections::HashMap; + use gasket::framework::*; +use pallas::applying::{validate, UTxOs}; use pallas::ledger::configs::byron::GenesisFile; -use tracing::info; +use pallas::ledger::traverse::{Era, MultiEraBlock, MultiEraInput, MultiEraOutput}; +use tracing::{info, warn}; use crate::prelude::*; use crate::storage::applydb::ApplyDB; +pub fn execute_phase1_validation( + ledger: &ApplyDB, + block: &MultiEraBlock<'_>, +) -> Result<(), WorkerError> { + let mut utxos = HashMap::new(); + ledger + .resolve_inputs_for_block(&block, &mut utxos) + .or_panic()?; + + let mut utxos2 = UTxOs::new(); + + for (ref_, output) in utxos.iter() { + let txin = pallas::ledger::primitives::byron::TxIn::Variant0( + pallas::codec::utils::CborWrap((ref_.0.clone(), ref_.1 as u32)), + ); + + let key = MultiEraInput::Byron( + >>::from(Cow::Owned(txin)), + ); + + let era = Era::try_from(output.0).or_panic()?; + let value = MultiEraOutput::decode(era, &output.1).or_panic()?; + + utxos2.insert(key, value); + } + + let env = ledger.get_active_pparams(block.slot()).or_panic()?; + + for tx in block.txs().iter() { + let res = validate(&tx, &utxos2, &env); + + if let Err(err) = res { + warn!(?err, "validation error"); + } + } + + Ok(()) +} + pub type UpstreamPort = gasket::messaging::tokio::InputPort; #[derive(Stage)] @@ -12,7 +56,6 @@ pub type UpstreamPort = gasket::messaging::tokio::InputPort; pub struct Stage { ledger: ApplyDB, genesis: GenesisFile, - prot_magic: u32, pub upstream: UpstreamPort, @@ -24,13 +67,11 @@ pub struct Stage { } impl Stage { - pub fn new(ledger: ApplyDB, genesis: GenesisFile, prot_magic: u64) -> Self { + pub fn new(ledger: ApplyDB, genesis: GenesisFile) -> Self { Self { ledger, genesis, - prot_magic: prot_magic as u32, upstream: Default::default(), - // downstream: Default::default(), block_count: Default::default(), wal_count: Default::default(), } @@ -58,10 +99,12 @@ impl gasket::framework::Worker for Worker { match unit { RollEvent::Apply(slot, _, cbor) => { info!(slot, "applying block"); - stage - .ledger - .apply_block(cbor, stage.prot_magic) - .or_panic()?; + + let block = MultiEraBlock::decode(cbor).or_panic()?; + + execute_phase1_validation(&stage.ledger, &block)?; + + stage.ledger.apply_block(&block).or_panic()?; } RollEvent::Undo(slot, _, cbor) => { info!(slot, "undoing block"); diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 42c11a94..01c53ccf 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -17,8 +17,9 @@ pub mod roll; #[derive(Deserialize)] pub struct Config { - peer_address: String, - network_magic: u64, + pub peer_address: String, + pub network_magic: u64, + pub network_id: u8, } fn define_gasket_policy(config: &Option) -> gasket::runtime::Policy { @@ -70,7 +71,7 @@ pub fn pipeline( let mut roll = roll::Stage::new(wal, cursor_chain, cursor_ledger); let mut chain = chain::Stage::new(chain); - let mut ledger = ledger::Stage::new(ledger, genesis, config.network_magic); + let mut ledger = ledger::Stage::new(ledger, genesis); let (to_roll, from_pull) = gasket::messaging::tokio::mpsc_channel(50); pull.downstream.connect(to_roll);