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

DA compression #1609

Merged
merged 139 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
15662c8
Add initial work towards DA compression crate
Dentosal Jan 18, 2024
f17cc70
Merge branch 'master' into dento/da-compression
Dentosal Jan 18, 2024
3101be6
Add distilled and compressed header and tx types
Dentosal Jan 18, 2024
4a2372f
Add changelog
Dentosal Jan 18, 2024
941e5e5
Attempt nice types interface, that wont work since Rust is missing sp…
Dentosal Jan 19, 2024
e65062d
Nevermind, type-based madness was possible and actually quite neat
Dentosal Jan 19, 2024
f322d0f
Remove malleable fields
Dentosal Jan 19, 2024
20f7269
WIP
Dentosal Jan 27, 2024
018c088
WIP
Dentosal Jan 29, 2024
75ab4a0
WIP
Dentosal Jan 29, 2024
7fb55be
Derive Compact: initial work
Dentosal Jan 29, 2024
3e4f0e0
WIP: compaction
Dentosal Jan 29, 2024
b795cf7
Merge branch 'master' into dento/da-compression
Dentosal Jan 31, 2024
a910bce
Impl compaction
Dentosal Jan 31, 2024
e6b1726
Correctly compact sequence types
Dentosal Jan 31, 2024
7fbb4c8
WIP: roundtrip and size tests
Dentosal Jan 31, 2024
8ae7407
Default key, performance fixes, misc stuff
Dentosal Jan 31, 2024
1919aa8
Combine db traits together
Dentosal Jan 31, 2024
ec4f257
Simplify the derive code
Dentosal Feb 1, 2024
08616b3
Fix key add bug
Dentosal Feb 1, 2024
ecde26c
Migrate the derive macro and compaction machinery to fuel-vm repo
Dentosal Feb 1, 2024
fae559b
Work towards properly architected (de)compression services
Dentosal Feb 12, 2024
0ce4650
Fix compression and it's tests
Dentosal Jul 23, 2024
e1fe97b
Merge branch 'dento/da-compression' of https://github.com/FuelLabs/fu…
Dentosal Jul 23, 2024
5ecc9e6
Merge branch 'master' into dento/da-compression
Dentosal Jul 23, 2024
ff8e753
Add decompression and a roundtrip test
Dentosal Jul 23, 2024
ea082cd
Merge branch 'master' into dento/da-compression
Dentosal Sep 2, 2024
bddc56a
Update to match latest VM PR changes
Dentosal Sep 3, 2024
043d447
Merge branch 'master' into dento/da-compression
Dentosal Sep 3, 2024
f09f51a
Update to latest fuel-vm and fix most clippy issues as well
Dentosal Sep 3, 2024
980dd14
Update to latest vm changes
Dentosal Sep 3, 2024
e08328a
Update to latest vm changes
Dentosal Sep 3, 2024
7a9961a
Merge branch 'master' into dento/da-compression
Dentosal Sep 3, 2024
0bbf912
Merge branch 'master' into dento/da-compression
Dentosal Sep 3, 2024
b2bde19
Update to latest vm changes
Dentosal Sep 4, 2024
0431104
Mock tx id and pointer lookups for tests
Dentosal Sep 4, 2024
9b2965b
cargo sort
Dentosal Sep 4, 2024
14ba4d8
Merge branch 'master' into dento/da-compression
Dentosal Sep 5, 2024
dad1b0f
Update to match fuel-vm changes
Dentosal Sep 5, 2024
dc6b40a
Update to match latest fuel-vm changes
Dentosal Sep 6, 2024
902619d
Update to match fuel-vm changes
Dentosal Sep 9, 2024
3749902
Swap to the github version of fuel-vm
Dentosal Sep 10, 2024
f79f6b3
Remove macOS .DS_Store files
Dentosal Sep 11, 2024
e3f8f61
Merge da compression db into the offchain db
Dentosal Sep 11, 2024
2d5ea21
Remove tests based on mock registry, these are already tested in fuel-vm
Dentosal Sep 11, 2024
cb85812
Fix the GraphQL endpoint; it now actually returns the compressed blocks
Dentosal Sep 16, 2024
0b1c2e2
Fetch UtxoIds when compacting; fix GraphQL types
Dentosal Sep 17, 2024
e324674
Update snapshot tests
Dentosal Sep 17, 2024
7e8424e
Remove some commented-out code
Dentosal Sep 17, 2024
7f23891
Update Cargo.lock
Dentosal Sep 17, 2024
bd800e1
Merge branch 'master' into dento/da-compression
Dentosal Sep 17, 2024
070454e
cargo sort
Dentosal Sep 17, 2024
b8ece00
Merge branch 'master' into dento/da-compression
Dentosal Sep 18, 2024
350d9df
Prettify Cargo.toml
Dentosal Sep 18, 2024
020656a
Fix types after merge
Dentosal Sep 18, 2024
6c1e932
npx prettify
Dentosal Sep 18, 2024
28db660
Remove unneeded self-dep
Dentosal Sep 18, 2024
d060c71
Approve snapshot
Dentosal Sep 18, 2024
b6d7343
Remove unused functions
Dentosal Sep 18, 2024
22dbc4e
Cargo fix
Dentosal Sep 18, 2024
35147c6
Update changelog
Dentosal Sep 18, 2024
99f8756
Clean up
Dentosal Sep 18, 2024
7fe1dfc
fmt
Dentosal Sep 18, 2024
da83ea1
Update Cargo.toml
Dentosal Sep 19, 2024
4748041
Add proptest-based ser/de tests for compressed blocks
Dentosal Sep 20, 2024
c36397d
Merge branch 'master' into dento/da-compression
Dentosal Sep 20, 2024
896b2d1
Add a test that shows compressed blocks are available from non-produc…
Dentosal Sep 20, 2024
8529440
Merge branch 'master' into dento/da-compression
Dentosal Sep 20, 2024
9542cbf
Cleanup
Dentosal Sep 20, 2024
3612ed8
Shuffle stuff around for aesthetic reasons
Dentosal Sep 20, 2024
c06173d
Include registrations_root merkle root, but keep it zeroed for now
Dentosal Sep 20, 2024
8ac98e5
Cleanup, more lints
Dentosal Sep 20, 2024
de44afb
Merge branch 'master' into dento/da-compression
Dentosal Sep 22, 2024
454351d
doc link fix
Dentosal Sep 22, 2024
a155b65
Feature fix attempt
Dentosal Sep 23, 2024
5cb035c
prettify
Dentosal Sep 23, 2024
465b04c
prettify more
Dentosal Sep 23, 2024
b615ad6
Optimize cache evictor
Dentosal Sep 23, 2024
c334ea2
Remove redundant trait bounds
Dentosal Sep 24, 2024
50d53d1
PR review: cleanup
Dentosal Sep 25, 2024
e0ddd85
Rewrite "we have enough keys" assertion in registry evictor
Dentosal Sep 25, 2024
e0e505d
Get rid of PostcardSerialized
Dentosal Sep 25, 2024
5cf05e1
Split TemporalRegistry trait to be per keyspace
Dentosal Sep 25, 2024
fdb8337
Simplify directory structure
Dentosal Sep 25, 2024
e165e9e
Use a separate GraphQL complexity cost for da compressed blocks
Dentosal Sep 25, 2024
e036b82
Use PartialBlockHeader in compressed block header (instead of custom …
Dentosal Sep 25, 2024
9a75b4b
Use enum for versioning
Dentosal Sep 25, 2024
dcc32ba
Move commented-out height check code to a note in the doc comment
Dentosal Sep 25, 2024
9eba468
Merge branch 'master' into dento/da-compression
Dentosal Sep 25, 2024
0957584
Merge branch 'master' into dento/da-compression
Dentosal Sep 26, 2024
946a2e8
Use separate db table for each temporal registry keyspace
Dentosal Sep 26, 2024
7fe125f
Remove RegistryKeyspaceValue type
Dentosal Sep 26, 2024
8d5fdf2
Change infallible TryFrom into From impl
Dentosal Sep 26, 2024
137aee2
cargo sort
Dentosal Sep 26, 2024
c5ac5db
Remove thiserror dependency (no_std support)
Dentosal Sep 26, 2024
2a4c190
cargo sort
Dentosal Sep 26, 2024
c04b7dc
Make cache evictor keyspace-agnostic
Dentosal Sep 26, 2024
34bfcd9
Minor improvements to the compression crate (#2254)
xgreenx Sep 26, 2024
dcac7d7
Decouple compression, decompression and registry (#2257)
xgreenx Sep 26, 2024
eda9e77
Reduce DB access in evictor by caching the latest key
Dentosal Sep 26, 2024
331531d
Convert panic into an error
Dentosal Sep 26, 2024
ee3e844
Replace the old index values correctly
Dentosal Sep 27, 2024
b5edb0d
Rename EvictorDb methods
Dentosal Sep 27, 2024
9b4cbb0
Minimized the number of the tables for metadata and reverse index (#2…
xgreenx Sep 27, 2024
40a1a3d
Check if the change is already in the current compression batch
Dentosal Sep 27, 2024
1e70c77
Make paste a workspace dependency
Dentosal Sep 27, 2024
4ac18b3
Use same workspace dep "paste" for all crates
Dentosal Sep 30, 2024
051089f
Add retention time parameter, move the feature behind a cli flag
Dentosal Sep 30, 2024
b27d6f4
Remove registrations_root from compressed blocks v0
Dentosal Sep 30, 2024
ba0ca71
Add basic_storage_tests for DaCompressionTemporalRegistryTimestamps
Dentosal Sep 30, 2024
c8ebcb2
Update tests to match config changes
Dentosal Sep 30, 2024
eaf1033
Merge branch 'master' into dento/da-compression
Dentosal Sep 30, 2024
2264fbd
Remove unnecessary changes from Cargo.lock
Dentosal Sep 30, 2024
2c929cc
Fix typo
Dentosal Sep 30, 2024
9437df1
Fix typo
Dentosal Sep 30, 2024
ace7895
Merge branch 'master' into dento/da-compression
Dentosal Sep 30, 2024
9c888f8
Move write_to_registry inside CompressCtx::finalize
Dentosal Oct 1, 2024
2725b45
Merge branch 'master' into dento/da-compression
Dentosal Oct 1, 2024
1764850
Fix Cargo.lock after merge issue
Dentosal Oct 1, 2024
a3d85a0
More Cargo.lock updates
Dentosal Oct 1, 2024
d452659
Remove some unnecessary pub specifiers
Dentosal Oct 1, 2024
dc34257
Merge branch 'master' into dento/da-compression
Dentosal Oct 2, 2024
0967f63
Address review comments
Dentosal Oct 2, 2024
f92b497
Update crates/compression/src/lib.rs
Dentosal Oct 2, 2024
448dcc0
Update crates/compression/src/compress.rs
Dentosal Oct 2, 2024
f01176b
Update crates/compression/src/compress.rs
Dentosal Oct 2, 2024
ed09afe
Merge branch 'master' into dento/da-compression
xgreenx Oct 2, 2024
8787971
Reduce db lookups in PrepareCtx
Dentosal Oct 3, 2024
06b2ad2
Merge branch 'master' into dento/da-compression
Dentosal Oct 3, 2024
4b8fe1e
Merge branch 'master' into dento/da-compression
Dentosal Oct 3, 2024
cf03b7f
Make integration tests sligtly more accurate
Dentosal Oct 3, 2024
4061e8c
Split TemporalRegistryAll to get correct bounds for decompression
Dentosal Oct 3, 2024
aba2bf4
Merge branch 'master' into dento/da-compression
Dentosal Oct 4, 2024
4669046
Wait for the off chain database to process all blocks
xgreenx Oct 4, 2024
997b41a
Avoid active loop
xgreenx Oct 4, 2024
dc98ec6
Merge branch 'master' into dento/da-compression
xgreenx Oct 4, 2024
05d811d
Remove flakiness from `test_peer_info` test
xgreenx Oct 4, 2024
adff59a
Merge branch 'master' into dento/da-compression
xgreenx Oct 4, 2024
e322ca3
Merge branch 'master' into dento/da-compression
xgreenx Oct 5, 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 @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

### Added
- [1609](https://github.com/FuelLabs/fuel-core/pull/1609): Add DA compression support. Compressed blocks are stored in the offchain database when blocks are produced, and can be fetched using the GraphQL API.
- [2290](https://github.com/FuelLabs/fuel-core/pull/2290): Added a new CLI argument `--graphql-max-directives`. The default value is `10`.
- [2195](https://github.com/FuelLabs/fuel-core/pull/2195): Added enforcement of the limit on the size of the L2 transactions per block according to the `block_transaction_size_limit` parameter.
- [2131](https://github.com/FuelLabs/fuel-core/pull/2131): Add flow in TxPool in order to ask to newly connected peers to share their transaction pool
Expand Down
35 changes: 35 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"bin/keygen",
"crates/chain-config",
"crates/client",
"crates/compression",
"crates/database",
"crates/fuel-core",
"crates/fuel-gas-price-algorithm",
Expand Down Expand Up @@ -62,6 +63,7 @@ fuel-core-keygen = { version = "0.36.0", path = "./crates/keygen" }
fuel-core-keygen-bin = { version = "0.36.0", path = "./bin/keygen" }
fuel-core-chain-config = { version = "0.36.0", path = "./crates/chain-config", default-features = false }
fuel-core-client = { version = "0.36.0", path = "./crates/client" }
fuel-core-compression = { version = "0.36.0", path = "./crates/compression" }
fuel-core-database = { version = "0.36.0", path = "./crates/database" }
fuel-core-metrics = { version = "0.36.0", path = "./crates/metrics" }
fuel-core-services = { version = "0.36.0", path = "./crates/services" }
Expand Down Expand Up @@ -131,6 +133,7 @@ test-strategy = "0.3"
parquet = { version = "49.0", default-features = false }
rayon = "1.10.0"
bytes = "1.5.0"
paste = "1.0"
pretty_assertions = "1.4.0"
proptest = "1.1"
pin-project-lite = "0.2"
Expand Down
1 change: 1 addition & 0 deletions bin/fuel-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dirs = "4.0"
dotenvy = { version = "0.15", optional = true }
fuel-core = { workspace = true, features = ["wasm-executor"] }
fuel-core-chain-config = { workspace = true }
fuel-core-compression = { workspace = true }
fuel-core-poa = { workspace = true }
fuel-core-types = { workspace = true, features = ["std"] }
hex = { workspace = true }
Expand Down
21 changes: 20 additions & 1 deletion bin/fuel-core/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ use fuel_core::{
CombinedDatabase,
CombinedDatabaseConfig,
},
fuel_core_graphql_api::ServiceConfig as GraphQLConfig,
fuel_core_graphql_api::{
worker_service::DaCompressionConfig,
ServiceConfig as GraphQLConfig,
},
producer::Config as ProducerConfig,
service::{
config::Trigger,
Expand Down Expand Up @@ -190,6 +193,11 @@ pub struct Command {
#[cfg(feature = "aws-kms")]
pub consensus_aws_kms: Option<String>,

/// If given, the node will produce and store da-compressed blocks
/// with the given retention time.
#[arg(long = "da-compression", env)]
pub da_compression: Option<humantime::Duration>,

/// A new block is produced instantly when transactions are available.
#[clap(flatten)]
pub poa_trigger: PoATriggerArgs,
Expand Down Expand Up @@ -272,6 +280,7 @@ impl Command {
consensus_key,
#[cfg(feature = "aws-kms")]
consensus_aws_kms,
da_compression,
poa_trigger,
predefined_blocks_path,
coinbase_recipient,
Expand Down Expand Up @@ -418,6 +427,15 @@ impl Command {
let block_importer =
fuel_core::service::config::fuel_core_importer::Config::new();

let da_compression = match da_compression {
Some(retention) => {
DaCompressionConfig::Enabled(fuel_core_compression::Config {
temporal_registry_retention: retention.into(),
})
}
None => DaCompressionConfig::Disabled,
};

let TxPoolArgs {
tx_pool_ttl,
tx_max_number,
Expand Down Expand Up @@ -476,6 +494,7 @@ impl Command {
min_gas_price,
gas_price_threshold_percent,
block_importer,
da_compression,
#[cfg(feature = "relayer")]
relayer: relayer_cfg,
#[cfg(feature = "p2p")]
Expand Down
10 changes: 10 additions & 0 deletions crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ enum ContractParametersVersion {
V1
}

type DaCompressedBlock {
bytes: HexString!
}

union DependentCost = LightOperation | HeavyOperation

type DryRunFailureStatus {
Expand Down Expand Up @@ -942,6 +946,12 @@ type Query {
"""
excludedIds: ExcludeInput
): [[CoinType!]!]!
daCompressedBlock(
"""
Height of the block
"""
height: U32!
): DaCompressedBlock
contract(
"""
ID of the Contract
Expand Down
18 changes: 18 additions & 0 deletions crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ use schema::{
block::BlockByIdArgs,
coins::CoinByIdArgs,
contract::ContractByIdArgs,
da_compressed::DaCompressedBlockByHeightArgs,
tx::{
TxArg,
TxIdArgs,
Expand Down Expand Up @@ -880,6 +881,23 @@ impl FuelClient {
Ok(block)
}

pub async fn da_compressed_block(
&self,
height: BlockHeight,
) -> io::Result<Option<Vec<u8>>> {
let query = schema::da_compressed::DaCompressedBlockByHeightQuery::build(
DaCompressedBlockByHeightArgs {
height: U32(height.into()),
},
);

Ok(self
.query(query)
.await?
.da_compressed_block
.map(|b| b.bytes.into()))
}

/// Retrieve a blob by its ID
pub async fn blob(&self, id: BlobId) -> io::Result<Option<types::Blob>> {
let query = schema::blob::BlobByIdQuery::build(BlobByIdArgs { id: id.into() });
Expand Down
1 change: 1 addition & 0 deletions crates/client/src/client/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub mod block;
pub mod chain;
pub mod coins;
pub mod contract;
pub mod da_compressed;
pub mod message;
pub mod node_info;
pub mod upgrades;
Expand Down
44 changes: 44 additions & 0 deletions crates/client/src/client/schema/da_compressed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::client::schema::{
schema,
U32,
};

use super::HexString;

#[derive(cynic::QueryVariables, Debug)]
pub struct DaCompressedBlockByHeightArgs {
pub height: U32,
}

#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(
schema_path = "./assets/schema.sdl",
graphql_type = "Query",
variables = "DaCompressedBlockByHeightArgs"
)]
pub struct DaCompressedBlockByHeightQuery {
#[arguments(height: $height)]
pub da_compressed_block: Option<DaCompressedBlock>,
}

/// Block with transaction ids
#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(schema_path = "./assets/schema.sdl")]
pub struct DaCompressedBlock {
pub bytes: HexString,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn block_by_height_query_gql_output() {
use cynic::QueryBuilder;
let operation =
DaCompressedBlockByHeightQuery::build(DaCompressedBlockByHeightArgs {
height: U32(0),
});
insta::assert_snapshot!(operation.query)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: crates/client/src/client/schema/da_compressed.rs
expression: operation.query
---
query($height: U32!) {
daCompressedBlock(height: $height) {
bytes
}
}
44 changes: 44 additions & 0 deletions crates/compression/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
name = "fuel-core-compression"
version = { workspace = true }
authors = { workspace = true }
categories = ["cryptography::cryptocurrencies"]
edition = { workspace = true }
homepage = { workspace = true }
keywords = [
"blockchain",
"cryptocurrencies",
"fuel-core",
"fuel-client",
"fuel-compression",
]
license = { workspace = true }
repository = { workspace = true }
description = "Compression and decompression of Fuel blocks for DA storage."

[dependencies]
anyhow = { workspace = true }
fuel-core-types = { workspace = true, features = [
"alloc",
"serde",
"da-compression",
] }
paste = { workspace = true }
rand = { workspace = true, optional = true }
serde = { version = "1.0", features = ["derive"] }
strum = { workspace = true }
strum_macros = { workspace = true }

[dev-dependencies]
fuel-core-compression = { path = ".", features = ["test-helpers"] }
postcard = { version = "1.0", features = ["use-std"] }
proptest = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

[features]
test-helpers = [
"dep:rand",
"fuel-core-types/test-helpers",
"fuel-core-types/random",
"fuel-core-types/std",
]
27 changes: 27 additions & 0 deletions crates/compression/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Compression and decompression of transactions for the DA layer

## Compressed block header

Each compressed block begins with a version field, so that it's possible to change the format later.
rafal-ch marked this conversation as resolved.
Show resolved Hide resolved

## Temporal registry

This crate provides offchain registries for different types such as `AssetId`, `ContractId`, scripts, and predicates. Each registry is a key-value store with three-byte key. The registries are essentially compression caches. The three byte key allows cache size of 16 million values before reregistering the older values.

The registries allow replacing repeated objects with their respective keys, so if an object
is used multiple times in a short interval (couple of months, maybe), then the full value
exists on only a single uncompressed block.

### Fraud proofs

Compressed block will contain a merkle root over all compression smts, followed by newly registered values along with their keys. Using an SMT provides flexibility around the algorithm we use to define keys without knowing how exactly values were chosen to be registered.

Each registry also uses an SMT. Since the keys are three bytes long, the depth of the SMT is capped at 24 levels.

## Compression of `UtxoIds`

Since each `UtxoId` only appears once, there's no point in registering them. Instead, they are replaced with `TxPointer` and output index, which are still unique.

### Fraud proofs

During fraud proofs we need to use the `prev_root` to prove that the referenced block height is part of the chain.
Loading
Loading