Commit 03f641b0 authored by clabby's avatar clabby

Add CI for `rethdb-reader`

parent d4275ade
...@@ -1213,6 +1213,63 @@ jobs: ...@@ -1213,6 +1213,63 @@ jobs:
name: "Go mod tidy" name: "Go mod tidy"
command: make mod-tidy && git diff --exit-code command: make mod-tidy && git diff --exit-code
op-service-rethdb-tests:
docker:
- image: us-docker.pkg.dev/oplabs-tools-artifacts/images/ci-builder:latest
resource_class: xlarge
steps:
- checkout
- check-changed:
patterns: op-service,op-node
- restore_cache:
name: Restore Go modules cache
key: gomod-{{ checksum "go.sum" }}
- run:
name: Install Rust toolchain
command: |
curl https://sh.rustup.rs -sSf | bash -s -- -y
echo 'export PATH=$HOME/.cargo/bin:$PATH' >> $BASH_ENV
echo 'source $HOME/.cargo/env' >> $HOME/.bashrc
source $HOME/.bashrc
rustup update nightly
- run:
name: Install deps
command: |
apt-get update
apt-get install -y pkg-config libssl-dev clang libclang-dev
- restore_cache:
name: Restore rust build cache
key: rethdb-reader-cache
- run:
name: Cargo fmt + clippy
command: |
cargo +nightly fmt -- --check
cargo +nightly clippy --all --all-features -- -D warnings
working_directory: op-service/rethdb-reader
- run:
name: Generate testdata db
command: cargo test
working_directory: op-service/rethdb-reader
- run:
name: Build dylib
command: cargo build --release
working_directory: op-service/rethdb-reader
- save_cache:
name: Persist rust build cache
# CircleCI will fall back to the latest key when restoring. We always want to persist the
# most recent cache.
key: rethdb-reader-cache-{{ epoch }}
paths:
- "/root/project/op-service/rethdb-reader/target"
- run:
name: Update LD_LIBRARY_PATH
command: echo 'export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/root/project/op-service/rethdb-reader/target/release"' >> $BASH_ENV
- run:
name: Run op-service RethDB tests
command: |
gotestsum --format=standard-verbose -- -run TestRethDB -tags rethdb -v
working_directory: op-service/sources
bedrock-go-tests: # just a helper, that depends on all the actual test jobs bedrock-go-tests: # just a helper, that depends on all the actual test jobs
docker: docker:
- image: <<pipeline.parameters.ci_builder_image>> - image: <<pipeline.parameters.ci_builder_image>>
...@@ -1428,6 +1485,9 @@ workflows: ...@@ -1428,6 +1485,9 @@ workflows:
name: op-service-tests name: op-service-tests
module: op-service module: op-service
requires: ["op-stack-go-lint"] requires: ["op-stack-go-lint"]
- op-service-rethdb-tests:
requires:
- op-stack-go-lint
- go-e2e-test: - go-e2e-test:
name: op-e2e-WS-tests name: op-e2e-WS-tests
module: op-e2e module: op-e2e
......
...@@ -3,3 +3,6 @@ target/ ...@@ -3,3 +3,6 @@ target/
# Bindings # Bindings
rdb.h rdb.h
# Testdata DB
testdata/
This diff is collapsed.
...@@ -9,7 +9,17 @@ name = "rethdbreader" ...@@ -9,7 +9,17 @@ name = "rethdbreader"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
reth = { git = "https://github.com/paradigmxyz/reth.git" } # reth
reth-primitives = { git = "https://github.com/paradigmxyz/reth.git" }
reth-provider = { git = "https://github.com/paradigmxyz/reth.git" }
reth-db = { git = "https://github.com/paradigmxyz/reth.git" }
reth-rpc-types = { git = "https://github.com/paradigmxyz/reth.git" }
reth-blockchain-tree = { git = "https://github.com/paradigmxyz/reth.git" }
# misc
serde = "1.0.190" serde = "1.0.190"
serde_json = "1.0.107" serde_json = "1.0.107"
anyhow = "1.0.75" anyhow = "1.0.75"
[dev-dependencies]
reth-revm = { git = "https://github.com/paradigmxyz/reth.git" }
...@@ -27,6 +27,14 @@ cargo doc --open ...@@ -27,6 +27,14 @@ cargo doc --open
cargo +nightly fmt -- && cargo +nightly clippy --all --all-features -- -D warnings cargo +nightly fmt -- && cargo +nightly clippy --all --all-features -- -D warnings
``` ```
**Generating `testdata`**
The testdata DB is automatically generated upon running the tests.
```sh
cargo test
```
**Generating the C header** **Generating the C header**
To generate the C header, first install `cbindgen` via `cargo install cbindgen --force`. Then, run the generation script: To generate the C header, first install `cbindgen` via `cargo install cbindgen --force`. Then, run the generation script:
......
...@@ -2,16 +2,14 @@ ...@@ -2,16 +2,14 @@
//! [reth] database. //! [reth] database.
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use reth::{ use reth_blockchain_tree::noop::NoopBlockchainTree;
blockchain_tree::noop::NoopBlockchainTree, use reth_db::open_db_read_only;
primitives::{ use reth_primitives::{
BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, BlockHashOrNumber, Receipt, TransactionKind, TransactionMeta, TransactionSigned, MAINNET, U128,
U128, U256, U64, U256, U64,
},
providers::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider},
rpc::types::{Log, TransactionReceipt},
utils::db::open_db_read_only,
}; };
use reth_provider::{providers::BlockchainProvider, BlockReader, ProviderFactory, ReceiptProvider};
use reth_rpc_types::{Log, TransactionReceipt};
use std::{ffi::c_char, path::Path}; use std::{ffi::c_char, path::Path};
/// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s /// A [ReceiptsResult] is a wrapper around a JSON string containing serialized [TransactionReceipt]s
...@@ -209,3 +207,112 @@ fn build_transaction_receipt_with_block_receipts( ...@@ -209,3 +207,112 @@ fn build_transaction_receipt_with_block_receipts(
Some(res_receipt) Some(res_receipt)
} }
#[cfg(test)]
mod test {
use super::*;
use reth_db::database::Database;
use reth_primitives::{
address, b256, bloom, hex, AccessList, Block, Bytes, Header, Log as RethLog, Receipts,
SealedBlockWithSenders, Signature, Transaction, TxEip1559, TxType, TxValue,
EMPTY_OMMER_ROOT_HASH,
};
use reth_provider::{BlockWriter, BundleStateWithReceipts, DatabaseProvider};
use reth_revm::revm::db::BundleState;
use std::{path::Path, str::FromStr};
#[test]
fn generate_testdata_db() {
let db = reth_db::init_db(Path::new("testdata"), None).unwrap();
let pr = DatabaseProvider::new_rw(db.tx_mut().unwrap(), MAINNET.clone());
let block = Block {
header: Header {
parent_hash: b256!(
"a2feb804b2ec06df67df4851a2ef75524820febc1a140ad5db424b80f9c3114d"
),
ommers_hash: EMPTY_OMMER_ROOT_HASH,
beneficiary: address!("0000000000000000000000000000000000000000"),
state_root: b256!(
"56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
),
transactions_root: b256!(
"78aecefe9a8944f627b6ffef3aad9ab5f5a5031e360bd014a10a50bcf37979c6"
),
receipts_root: b256!(
"99bdc617e7e3781b02ce06c06a77acd45988be16be63d58578a4399f3cc10fed"
),
withdrawals_root: Some(b256!(
"558291986c64e0ef409d79093c5f4306257fa56179f07efe4483eeaa14299a0c"
)),
logs_bloom: bloom!("00b8830810238200002802008031000400a80400054013c04083000a11000082820028c40500100209140a4202018028000a0a344921910c001286001024000010834000ec4004010000002b82108423461b8460020600001404031680200020004010008e4a08500528418800010804100000c809600200008a0098800810c2008220100112250062c044050001404080651013422442da000101400500041002281000031100000300008010104a0800110208800051804ac41a2420000110e0104103102242c0020a2000041042c8040201024004871471018012404065280c30021c202082030800040000020808020104421010c241c80a400408020054"),
difficulty: U256::ZERO,
number: 9942861,
gas_limit: 0x1c9c380,
gas_used: 0xc91a7e,
timestamp: 0x653c5c8c,
mix_hash: b256!("c7bd100be413127b4e4695b29835cb15592c81e98b704b49838d358d13642c56"),
nonce: 0,
base_fee_per_gas: Some(9),
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
extra_data: hex!("d883010b04846765746888676f312e32302e32856c696e7578").into(),
},
body: vec![
TransactionSigned {
hash: b256!("12c0074a4a7916fe6f39de8417fe93f1fa77bcadfd5fc31a317fb6c344f66602"),
signature: Signature {
r: U256::from_str("0x200a045cf9b74dc7eaa71cbbc257c0d8365a11c3dc3f547267f4d93e3863e358").unwrap(),
s: U256::from_str("0x1f9f7a37b2fa471c9212009c1f19daf3f03dbfd1787be7e227b56765daf084a").unwrap(),
odd_y_parity: true
},
transaction: Transaction::Eip1559(TxEip1559 {
chain_id: 5,
nonce: 0x4b4b,
gas_limit: 0x3c03f,
max_fee_per_gas: 0x59682f12,
max_priority_fee_per_gas: 0x59682f00,
to: TransactionKind::Call(address!("4ce63f351597214ef0b9a319124eea9e0f9668bb")),
value: TxValue::from(U256::ZERO),
access_list: AccessList::default(),
input: hex!("70ab1eb60000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000003ed1c85eb0477c9ac0308a4c7022c37e606627b328daa4ab363f44981e287d69bb075d81fcbff15450b978f9b84ca9fd9ca96b1e8faf3ea1f2951e496980b466186ae4a9f759f4d75d4fe28fde9d6ebad99f49cb30f791a2bfc85a8a2a36569f00000000000000000000000000000000000000000000000000000000653c5bf50c07ca9327b541241b9a7d856294622c1b03d4991fdf44537d97173709a7c7f4084a7f906d3e5594377cd9d7c36fc66c53716e69c8114b8fa425ad06e53807302eb1efd7eaf8c72107458873cda1b771bb5bf0154caa2ed63d3073e970cf63da0c1d1e58f31dff4dba615c61b3996a01d41e1f45999ea132e254c8e6129e535817235adea1ec0def8111508cc9b658347db64bdf3904c592f5ad4d9258f57b0c167f59373778385fc2f01ee9539befaaf97a8d540ae926242061d2da5fea4a91152ea7d88c390b356fb780a6f93c57efa6aab34d9409dec4dd23bc0ffa8f3f7825dd47e27434b2e4d9d9730db0ae0c2faa556f0e7440724d2c44c527c4d1ad8e29da7229592b10d727c8a7d633c8a0e6240db2452282ecee26ef3d8d9980b463").into()
}
) }
],
ommers: vec![],
withdrawals: None,
};
pr.append_blocks_with_bundle_state(
vec![SealedBlockWithSenders {
block: block.seal_slow(),
senders: vec![address!("a24efab96523efa6abb2de9b2c16205cfa3c1dc8")],
}],
BundleStateWithReceipts::new(
BundleState::default(),
Receipts::from_block_receipt(vec![Receipt {
tx_type: TxType::EIP1559,
success: true,
cumulative_gas_used: 0x3aefc,
logs: vec![RethLog {
address: address!("4ce63f351597214ef0b9a319124eea9e0f9668bb"),
topics: vec![
b256!(
"0cdbd8bd7813095001c5fe7917bd69d834dc01db7c1dfcf52ca135bd20384413"
),
b256!(
"00000000000000000000000000000000000000000000000000000000000000c2"
),
],
data: Bytes::default(),
}],
}]),
9942861,
),
None,
)
.unwrap();
pr.commit().unwrap();
}
}
//go:build rethdb
package sources
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)
func TestRethDBReceiptsLoad(t *testing.T) {
t.Parallel()
// Goerli block #9942861, with only the first transaction persisted to the DB
//
// https://goerli.etherscan.io/tx/0x12c0074a4a7916fe6f39de8417fe93f1fa77bcadfd5fc31a317fb6c344f66602
blockHash := common.HexToHash("0xbcc3fb97b87bb4b14bacde74255cbfcf52675c0ad5e06fa264c0e5d6c0afd96e")
res, err := FetchRethReceipts("../rethdb-reader/testdata", &blockHash)
require.NoError(t, err)
receipt := (*types.Receipt)(res[0])
require.Equal(t, receipt.Type, uint8(2))
require.Equal(t, receipt.Status, uint64(1))
require.Equal(t, receipt.CumulativeGasUsed, uint64(241_404))
require.Equal(t, receipt.Bloom, types.BytesToBloom(common.Hex2Bytes("00000000000000000000000000000000000000000100008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000004000000000000000010020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000800000000000000000000000000000000000000000000000000000000")))
require.Equal(t, receipt.Logs[0].Address, common.HexToAddress("4ce63f351597214ef0b9a319124eea9e0f9668bb"))
require.Equal(t, receipt.Logs[0].Topics[0], common.HexToHash("0cdbd8bd7813095001c5fe7917bd69d834dc01db7c1dfcf52ca135bd20384413"))
require.Equal(t, receipt.Logs[0].Topics[1], common.HexToHash("00000000000000000000000000000000000000000000000000000000000000c2"))
require.Equal(t, receipt.Logs[0].Data, []byte{})
require.Equal(t, receipt.TxHash, common.HexToHash("0x12c0074a4a7916fe6f39de8417fe93f1fa77bcadfd5fc31a317fb6c344f66602"))
require.Equal(t, receipt.BlockHash, common.HexToHash("0xbcc3fb97b87bb4b14bacde74255cbfcf52675c0ad5e06fa264c0e5d6c0afd96e"))
require.Equal(t, receipt.BlockNumber, big.NewInt(9942861))
require.Equal(t, receipt.TransactionIndex, uint(0))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment