Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Circuit for opcode COINBASE #259

Merged
merged 27 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
febbe07
add block table &lookup
DreamWuGit Dec 22, 2021
d68d6f2
integrate block table into configure evm circuit
DreamWuGit Dec 23, 2021
77159e4
fix coinbase test
DreamWuGit Dec 27, 2021
7d6d27f
fix formation
DreamWuGit Dec 27, 2021
b3b87ed
fix benchmark test circuit with block table
DreamWuGit Dec 28, 2021
f995701
make clippy change
DreamWuGit Dec 28, 2021
9757cbc
fix comments
DreamWuGit Dec 29, 2021
5724032
remove comment
DreamWuGit Dec 29, 2021
be68402
change block number for F
DreamWuGit Dec 29, 2021
6976328
try change block lookup parameter
DreamWuGit Dec 30, 2021
9adad99
Apply suggestions from code review
DreamWuGit Dec 31, 2021
0eab8b1
fix one clippy
DreamWuGit Dec 31, 2021
32fbbff
restore comments
icemelon Jan 3, 2022
610c122
Update comment to push
DreamWuGit Jan 4, 2022
5c65288
enable address to word with little endian
DreamWuGit Jan 6, 2022
78f38b1
add missing file
DreamWuGit Jan 6, 2022
11ee0e3
correct block hash assignment
DreamWuGit Jan 6, 2022
8eae067
revert additinal to word change
DreamWuGit Jan 6, 2022
3565fa1
add coinbsae bus mapping
DreamWuGit Jan 6, 2022
d0dcd32
fix clippy
0xmountaintop Jan 6, 2022
ec9fbf2
fix typos
0xmountaintop Jan 6, 2022
aed10ab
remove comment
DreamWuGit Jan 7, 2022
49bdfab
change coinbase test with block from trace of bussmapping
DreamWuGit Jan 11, 2022
b853fda
refactor removing coinbase from ChainConstants
DreamWuGit Jan 12, 2022
515b084
remove unsed comments
DreamWuGit Jan 12, 2022
723912d
rebase latest main and fix
DreamWuGit Jan 14, 2022
776bc42
fix ci doc error
DreamWuGit Jan 14, 2022
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 .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
*.png
.DS_Store
23 changes: 16 additions & 7 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::evm::{
StackAddress,
};
use crate::exec_trace::OperationRef;
use crate::external_tracer::BlockConstants;
use crate::geth_errors::*;
use crate::operation::container::OperationContainer;
use crate::operation::{MemoryOp, Op, Operation, StackOp, RW};
Expand Down Expand Up @@ -175,8 +176,10 @@ impl BlockContext {
/// Circuit Input related to a block.
#[derive(Debug)]
pub struct Block {
/// Constants associated to this block and the chain.
pub constants: ChainConstants,
/// Constants associated to the chain.
pub chain_const: ChainConstants,
/// Constants associated to the block.
pub block_const: BlockConstants,
/// Container of operations done in this block.
pub container: OperationContainer,
txs: Vec<Transaction>,
Expand All @@ -187,10 +190,12 @@ impl Block {
/// Create a new block.
pub fn new<TX>(
_eth_block: &eth_types::Block<TX>,
constants: ChainConstants,
chain_const: ChainConstants,
block_const: BlockConstants,
) -> Self {
Self {
constants,
chain_const,
block_const,
container: OperationContainer::new(),
txs: Vec::new(),
code: HashMap::new(),
Expand Down Expand Up @@ -821,12 +826,13 @@ impl<'a> CircuitInputBuilder {
sdb: StateDB,
code_db: CodeDB,
eth_block: &eth_types::Block<TX>,
constants: ChainConstants,
chain_const: ChainConstants,
block_const: BlockConstants,
) -> Self {
Self {
sdb,
code_db,
block: Block::new(eth_block, constants),
block: Block::new(eth_block, chain_const, block_const),
block_ctx: BlockContext::new(),
}
}
Expand Down Expand Up @@ -1210,7 +1216,6 @@ impl<P: JsonRpcClient> BuilderClient<P> {
/// Create a new BuilderClient
pub async fn new(client: GethClient<P>) -> Result<Self, Error> {
let constants = ChainConstants {
coinbase: client.get_coinbase().await?,
chain_id: client.get_chain_id().await?,
};
Ok(Self {
Expand Down Expand Up @@ -1327,6 +1332,10 @@ impl<P: JsonRpcClient> BuilderClient<P> {
code_db,
eth_block,
self.constants.clone(),
BlockConstants::from_eth_block(
eth_block,
&Word::from(self.constants.chain_id),
),
);
for (tx_index, tx) in eth_block.transactions.iter().enumerate() {
let geth_trace = &geth_traces[tx_index];
Expand Down
2 changes: 0 additions & 2 deletions bus-mapping/src/eth_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ impl<F: FieldExt> ToScalar<F> for Address {
/// Chain specific constants
#[derive(Debug, Clone)]
pub struct ChainConstants {
/// Coinbase
pub coinbase: Address,
/// Chain ID
pub chain_id: u64,
}
Expand Down
4 changes: 3 additions & 1 deletion bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Definition of each opcode of the EVM.
mod coinbase;
mod dup;
pub mod ids;
mod jump;
Expand All @@ -22,6 +23,7 @@ use ids::OpcodeId;
use log::warn;

use self::push::Push;
use coinbase::Coinbase;
use dup::Dup;
use jump::Jump;
use jumpdest::Jumpdest;
Expand Down Expand Up @@ -110,7 +112,7 @@ impl OpcodeId {
// OpcodeId::RETURNDATACOPY => {},
// OpcodeId::EXTCODEHASH => {},
// OpcodeId::BLOCKHASH => {},
// OpcodeId::COINBASE => {},
OpcodeId::COINBASE => Coinbase::gen_associated_ops,
// OpcodeId::TIMESTAMP => {},
// OpcodeId::NUMBER => {},
// OpcodeId::DIFFICULTY => {},
Expand Down
91 changes: 91 additions & 0 deletions bus-mapping/src/evm/opcodes/coinbase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use super::Opcode;
use crate::circuit_input_builder::CircuitInputStateRef;
use crate::eth_types::GethExecStep;
use crate::{operation::RW, Error};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the [`OpcodeId::PC`](crate::evm::OpcodeId::PC) `OpcodeId`.
#[derive(Debug, Copy, Clone)]
pub(crate) struct Coinbase;

impl Opcode for Coinbase {
fn gen_associated_ops(
state: &mut CircuitInputStateRef,
steps: &[GethExecStep],
) -> Result<(), Error> {
let step = &steps[0];
// Get value result from next step and do stack write
let value = steps[1].stack.last()?;
state.push_stack_op(
RW::WRITE,
step.stack.last_filled().map(|a| a - 1),
value,
);

Ok(())
}
}

#[cfg(test)]
mod coinbase_tests {
use super::*;
use crate::{
bytecode,
circuit_input_builder::{ExecStep, TransactionContext},
eth_types::ToWord,
evm::StackAddress,
mock,
};
use pretty_assertions::assert_eq;

#[test]
fn coinbase_opcode_impl() -> Result<(), Error> {
let code = bytecode! {
#[start]
COINBASE
STOP
};

// Get the execution steps from the external tracer
let block =
mock::BlockData::new_single_tx_trace_code_at_start(&code).unwrap();

let mut builder = block.new_circuit_input_builder();
builder.handle_tx(&block.eth_tx, &block.geth_trace).unwrap();

let mut test_builder = block.new_circuit_input_builder();
let mut tx = test_builder.new_tx(&block.eth_tx).unwrap();
let mut tx_ctx = TransactionContext::new(&block.eth_tx);

// Generate step corresponding to COINBASE
let mut step = ExecStep::new(
&block.geth_trace.struct_logs[0],
0,
test_builder.block_ctx.rwc,
0,
);
let mut state_ref =
test_builder.state_ref(&mut tx, &mut tx_ctx, &mut step);

// Add the last Stack write
state_ref.push_stack_op(
RW::WRITE,
StackAddress::from(1024 - 1),
block.b_constant.coinbase.to_word(),
);

tx.steps_mut().push(step);
test_builder.block.txs_mut().push(tx);

// Compare first step bus mapping instance
assert_eq!(
builder.block.txs()[0].steps()[0].bus_mapping_instance,
test_builder.block.txs()[0].steps()[0].bus_mapping_instance,
);

// Compare containers
assert_eq!(builder.block.container, test_builder.block.container);

Ok(())
}
}
32 changes: 18 additions & 14 deletions bus-mapping/src/external_tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,30 @@ use serde::Serialize;
/// chain to be used as setup for the external tracer.
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct BlockConstants {
hash: Hash,
coinbase: Address,
timestamp: Word,
number: U64,
difficulty: Word,
gas_limit: Word,
chain_id: Word,
base_fee: Word,
/// hash
pub hash: Hash,
/// coinbase
pub coinbase: Address,
/// time
pub timestamp: Word,
/// number
pub number: U64,
/// difficulty
pub difficulty: Word,
/// gas limit
pub gas_limit: Word,
/// chain id
pub chain_id: Word,
/// base fee
pub base_fee: Word,
}

impl BlockConstants {
/// Generate a BlockConstants from an ethereum block, useful for testing.
pub fn from_eth_block<TX>(
block: &Block<TX>,
chain_id: &Word,
&coinbase: &Address,
) -> Self {
pub fn from_eth_block<TX>(block: &Block<TX>, chain_id: &Word) -> Self {
Self {
hash: block.hash.unwrap(),
coinbase,
coinbase: block.author,
timestamp: block.timestamp,
number: block.number.unwrap(),
difficulty: block.difficulty,
Expand Down
14 changes: 11 additions & 3 deletions bus-mapping/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
//! self, Address, Word, Hash, U64, GethExecTrace, GethExecStep, ChainConstants
//! };
//! use bus_mapping::circuit_input_builder::CircuitInputBuilder;
//! use bus_mapping::external_tracer::BlockConstants;
//! use pairing::arithmetic::FieldExt;
//!
//! let input_trace = r#"
Expand Down Expand Up @@ -107,7 +108,6 @@
//! "#;
//!
//! let ctants = ChainConstants{
//! coinbase: Address::zero(),
//! chain_id: 0,
//! };
//!
Expand All @@ -117,8 +117,16 @@
//! let mut sdb = StateDB::new();
//! sdb.set_account(&Address::zero(), state_db::Account::zero());
//!
//! let mut builder =
//! CircuitInputBuilder::new(sdb, CodeDB::new(), &eth_block, ctants);
//! let mut builder = CircuitInputBuilder::new(
//! sdb,
//! CodeDB::new(),
//! &eth_block,
//! ctants.clone(),
//! BlockConstants::from_eth_block(
//! &eth_block,
//! &Word::from(ctants.chain_id),
//! ),
//! );
//!
//! let geth_steps: Vec<GethExecStep> = serde_json::from_str(input_trace).unwrap();
//! let geth_trace = GethExecTrace {
Expand Down
33 changes: 19 additions & 14 deletions bus-mapping/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ lazy_static! {

/// Generate a new mock chain constants, useful for tests.
pub fn new_chain_constants() -> eth_types::ChainConstants {
ChainConstants {
chain_id: CHAIN_ID,
coinbase: *COINBASE,
}
ChainConstants { chain_id: CHAIN_ID }
}

/// Generate a new mock block with preloaded data, useful for tests.
Expand Down Expand Up @@ -94,7 +91,9 @@ pub struct BlockData {
/// Transaction from geth
pub eth_tx: eth_types::Transaction,
/// Constants
pub ctants: ChainConstants,
pub c_constant: ChainConstants,
/// Constants
pub b_constant: BlockConstants,
/// Execution Trace from geth
pub geth_trace: eth_types::GethExecTrace,
}
Expand All @@ -112,18 +111,17 @@ impl BlockData {
let eth_block = new_block();
let mut eth_tx = new_tx(&eth_block);
eth_tx.gas = Word::from(gas.0);
let ctants = new_chain_constants();
let block_ctants = BlockConstants::from_eth_block(
let c_constant = new_chain_constants();
let b_constant = BlockConstants::from_eth_block(
&eth_block,
&Word::from(ctants.chain_id),
&ctants.coinbase,
&Word::from(c_constant.chain_id),
);
let tracer_tx = external_tracer::Transaction::from_eth_tx(&eth_tx);
let geth_trace = eth_types::GethExecTrace {
gas: Gas(eth_tx.gas.as_u64()),
failed: false,
struct_logs: external_tracer::trace(
&block_ctants,
&b_constant,
&tracer_tx,
accounts,
)?
Expand All @@ -148,7 +146,8 @@ impl BlockData {
code_db,
eth_block,
eth_tx,
ctants,
c_constant,
b_constant,
geth_trace,
})
}
Expand Down Expand Up @@ -220,7 +219,11 @@ impl BlockData {
) -> Self {
let eth_block = new_block();
let eth_tx = new_tx(&eth_block);
let ctants = new_chain_constants();
let c_constant = new_chain_constants();
let b_constant = BlockConstants::from_eth_block(
&eth_block,
&Word::from(c_constant.chain_id),
);
let geth_trace = eth_types::GethExecTrace {
gas: Gas(eth_tx.gas.as_u64()),
failed: false,
Expand All @@ -233,7 +236,8 @@ impl BlockData {
code_db,
eth_block,
eth_tx,
ctants,
c_constant,
b_constant,
geth_trace,
}
}
Expand All @@ -245,7 +249,8 @@ impl BlockData {
self.sdb.clone(),
self.code_db.clone(),
&self.eth_block,
self.ctants.clone(),
self.c_constant.clone(),
self.b_constant.clone(),
)
}
}
Expand Down
2 changes: 2 additions & 0 deletions circuit-benchmarks/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl<F: FieldExt> Circuit<F> for TestCircuit<F> {
let tx_table = [(); 4].map(|_| meta.advice_column());
let rw_table = [(); 8].map(|_| meta.advice_column());
let bytecode_table = [(); 4].map(|_| meta.advice_column());
let block_table = [(); 3].map(|_| meta.advice_column());
let randomness = meta.instance_column();

EvmCircuit::configure(
Expand All @@ -32,6 +33,7 @@ impl<F: FieldExt> Circuit<F> for TestCircuit<F> {
tx_table,
rw_table,
bytecode_table,
block_table,
)
}

Expand Down
1 change: 0 additions & 1 deletion integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pub fn get_provider() -> Provider<Http> {
pub async fn get_chain_constants() -> ChainConstants {
let client = get_client();
ChainConstants {
coinbase: client.get_coinbase().await.unwrap(),
chain_id: client.get_chain_id().await.unwrap(),
}
}
Expand Down
Loading