Revert "Make gas fit in 2 limbs (#1261)" (#1361)

* Revert "Make gas fit in 2 limbs (#1261)"

This reverts commit 0f19cd0dbc25f9f1aa8fc325ae4dd1b95ca933b3.

* Comment
This commit is contained in:
Robin Salen 2023-11-17 10:01:26 -05:00 committed by GitHub
parent 40d3c6dd0d
commit 24aa9668f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 185 deletions

View File

@ -75,8 +75,8 @@ pub(crate) struct CpuColumnsView<T: Copy> {
/// If CPU cycle: We're in kernel (privileged) mode.
pub is_kernel_mode: T,
/// If CPU cycle: Gas counter, split in two 32-bit limbs in little-endian order.
pub gas: [T; 2],
/// If CPU cycle: Gas counter.
pub gas: T,
/// If CPU cycle: flags for EVM instructions (a few cannot be shared; see the comments in
/// `OpsColumnsView`).

View File

@ -66,15 +66,11 @@ fn eval_packed_accumulate<P: PackedField>(
})
.sum();
// TODO: This may cause soundness issue if the recomputed gas (as u64) overflows the field size.
// This is fine as we are only using two-limbs for testing purposes (to support all cases from
// the Ethereum test suite).
// This should be changed back to a single 32-bit limb before going into production!
let gas_diff = nv.gas[1] * P::Scalar::from_canonical_u64(1 << 32) + nv.gas[0]
- (lv.gas[1] * P::Scalar::from_canonical_u64(1 << 32) + lv.gas[0]);
let constr = gas_diff - gas_used;
let constr = nv.gas - (lv.gas + gas_used);
yield_constr.constraint_transition(filter * constr);
let gas_diff = nv.gas - lv.gas;
for (maybe_cost, op_flag) in izip!(SIMPLE_OPCODES.into_iter(), lv.op.into_iter()) {
if let Some(cost) = maybe_cost {
let cost = P::Scalar::from_canonical_u32(cost);
@ -129,8 +125,7 @@ fn eval_packed_init<P: PackedField>(
// `nv` is the first row that executes an instruction.
let filter = (is_cpu_cycle - P::ONES) * is_cpu_cycle_next;
// Set initial gas to zero.
yield_constr.constraint_transition(filter * nv.gas[0]);
yield_constr.constraint_transition(filter * nv.gas[1]);
yield_constr.constraint_transition(filter * nv.gas);
}
/// Evaluate the gas constraints for the opcodes that cost a constant gas.
@ -174,22 +169,16 @@ fn eval_ext_circuit_accumulate<F: RichField + Extendable<D>, const D: usize>(
},
);
// TODO: This may cause soundness issue if the recomputed gas (as u64) overflows the field size.
// This is fine as we are only using two-limbs for testing purposes (to support all cases from
// the Ethereum test suite).
// This should be changed back to a single 32-bit limb before going into production!
let nv_gas =
builder.mul_const_add_extension(F::from_canonical_u64(1 << 32), nv.gas[1], nv.gas[0]);
let lv_gas =
builder.mul_const_add_extension(F::from_canonical_u64(1 << 32), lv.gas[1], lv.gas[0]);
let nv_lv_diff = builder.sub_extension(nv_gas, lv_gas);
let constr = builder.sub_extension(nv_lv_diff, gas_used);
let constr = {
let t = builder.add_extension(lv.gas, gas_used);
builder.sub_extension(nv.gas, t)
};
let filtered_constr = builder.mul_extension(filter, constr);
yield_constr.constraint_transition(builder, filtered_constr);
for (maybe_cost, op_flag) in izip!(SIMPLE_OPCODES.into_iter(), lv.op.into_iter()) {
if let Some(cost) = maybe_cost {
let nv_lv_diff = builder.sub_extension(nv.gas, lv.gas);
let constr = builder.arithmetic_extension(
F::ONE,
-F::from_canonical_u32(cost),
@ -210,6 +199,7 @@ fn eval_ext_circuit_accumulate<F: RichField + Extendable<D>, const D: usize>(
let jump_gas_cost =
builder.add_const_extension(jump_gas_cost, F::from_canonical_u32(G_MID.unwrap()));
let nv_lv_diff = builder.sub_extension(nv.gas, lv.gas);
let gas_diff = builder.sub_extension(nv_lv_diff, jump_gas_cost);
let constr = builder.mul_extension(filter, gas_diff);
yield_constr.constraint_transition(builder, constr);
@ -229,6 +219,7 @@ fn eval_ext_circuit_accumulate<F: RichField + Extendable<D>, const D: usize>(
let binary_op_cost =
builder.add_const_extension(binary_op_cost, F::from_canonical_u32(G_LOW.unwrap()));
let nv_lv_diff = builder.sub_extension(nv.gas, lv.gas);
let gas_diff = builder.sub_extension(nv_lv_diff, binary_op_cost);
let constr = builder.mul_extension(filter, gas_diff);
yield_constr.constraint_transition(builder, constr);
@ -243,6 +234,7 @@ fn eval_ext_circuit_accumulate<F: RichField + Extendable<D>, const D: usize>(
let ternary_op_cost =
builder.add_const_extension(ternary_op_cost, F::from_canonical_u32(G_MID.unwrap()));
let nv_lv_diff = builder.sub_extension(nv.gas, lv.gas);
let gas_diff = builder.sub_extension(nv_lv_diff, ternary_op_cost);
let constr = builder.mul_extension(filter, gas_diff);
yield_constr.constraint_transition(builder, constr);
@ -292,9 +284,7 @@ fn eval_ext_circuit_init<F: RichField + Extendable<D>, const D: usize>(
let is_cpu_cycle_next = builder.add_many_extension(COL_MAP.op.iter().map(|&col_i| nv[col_i]));
let filter = builder.mul_sub_extension(is_cpu_cycle, is_cpu_cycle_next, is_cpu_cycle_next);
// Set initial gas to zero.
let constr = builder.mul_extension(filter, nv.gas[0]);
yield_constr.constraint_transition(builder, constr);
let constr = builder.mul_extension(filter, nv.gas[1]);
let constr = builder.mul_extension(filter, nv.gas);
yield_constr.constraint_transition(builder, constr);
}

View File

@ -23,8 +23,9 @@ pub(crate) fn eval_packed_exit_kernel<P: PackedField>(
// but we trust the kernel to set them to zero).
yield_constr.constraint_transition(filter * (input[0] - nv.program_counter));
yield_constr.constraint_transition(filter * (input[1] - nv.is_kernel_mode));
yield_constr.constraint_transition(filter * (input[6] - nv.gas[0]));
yield_constr.constraint_transition(filter * (input[7] - nv.gas[1]));
yield_constr.constraint_transition(filter * (input[6] - nv.gas));
// High limb of gas must be 0 for convenient detection of overflow.
yield_constr.constraint(filter * input[7]);
}
/// Circuit version of `eval_packed_exit_kernel`.
@ -51,14 +52,14 @@ pub(crate) fn eval_ext_circuit_exit_kernel<F: RichField + Extendable<D>, const D
yield_constr.constraint_transition(builder, kernel_constr);
{
let diff = builder.sub_extension(input[6], nv.gas[0]);
let diff = builder.sub_extension(input[6], nv.gas);
let constr = builder.mul_extension(filter, diff);
yield_constr.constraint_transition(builder, constr);
}
{
let diff = builder.sub_extension(input[7], nv.gas[1]);
let constr = builder.mul_extension(filter, diff);
yield_constr.constraint_transition(builder, constr);
// High limb of gas must be 0 for convenient detection of overflow.
let constr = builder.mul_extension(filter, input[7]);
yield_constr.constraint(builder, constr);
}
}

View File

@ -101,8 +101,7 @@ pub(crate) fn eval_packed<P: PackedField>(
// Maintain current context
yield_constr.constraint_transition(total_filter * (nv.context - lv.context));
// Reset gas counter to zero.
yield_constr.constraint_transition(total_filter * nv.gas[0]);
yield_constr.constraint_transition(total_filter * nv.gas[1]);
yield_constr.constraint_transition(total_filter * nv.gas);
let output = nv.mem_channels[0].value;
// New top of the stack: current PC + 1 (limb 0), kernel flag (limb 1), gas counter (limbs 6 and 7).
@ -110,9 +109,8 @@ pub(crate) fn eval_packed<P: PackedField>(
yield_constr.constraint(filter_exception * (output[0] - lv.program_counter));
// Check the kernel mode, for syscalls only
yield_constr.constraint(filter_syscall * (output[1] - lv.is_kernel_mode));
// TODO: Range check `output[6] and output[7]`.
yield_constr.constraint(total_filter * (output[6] - lv.gas[0]));
yield_constr.constraint(total_filter * (output[7] - lv.gas[1]));
yield_constr.constraint(total_filter * (output[6] - lv.gas));
yield_constr.constraint(total_filter * output[7]); // High limb of gas is zero.
// Zero the rest of that register
// output[1] is 0 for exceptions, but not for syscalls
@ -270,9 +268,7 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
}
// Reset gas counter to zero.
{
let constr = builder.mul_extension(total_filter, nv.gas[0]);
yield_constr.constraint_transition(builder, constr);
let constr = builder.mul_extension(total_filter, nv.gas[1]);
let constr = builder.mul_extension(total_filter, nv.gas);
yield_constr.constraint_transition(builder, constr);
}
@ -297,15 +293,14 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
let constr = builder.mul_extension(filter_syscall, diff);
yield_constr.constraint(builder, constr);
}
// TODO: Range check `output[6]` and `output[7].
{
let diff = builder.sub_extension(output[6], lv.gas[0]);
let diff = builder.sub_extension(output[6], lv.gas);
let constr = builder.mul_extension(total_filter, diff);
yield_constr.constraint(builder, constr);
}
{
let diff = builder.sub_extension(output[7], lv.gas[1]);
let constr = builder.mul_extension(total_filter, diff);
// High limb of gas is zero.
let constr = builder.mul_extension(total_filter, output[7]);
yield_constr.constraint(builder, constr);
}

View File

@ -663,18 +663,15 @@ where
builder.connect(pvs.txn_number_before, lhs.txn_number_before);
builder.connect(pvs.txn_number_after, rhs.txn_number_after);
// Connect lhs `txn_number_after` with rhs `txn_number_before`.
// Connect lhs `txn_number_after`with rhs `txn_number_before`.
builder.connect(lhs.txn_number_after, rhs.txn_number_before);
// Connect the gas used in public values to the lhs and rhs values correctly.
builder.connect(pvs.gas_used_before[0], lhs.gas_used_before[0]);
builder.connect(pvs.gas_used_before[1], lhs.gas_used_before[1]);
builder.connect(pvs.gas_used_after[0], rhs.gas_used_after[0]);
builder.connect(pvs.gas_used_after[1], rhs.gas_used_after[1]);
builder.connect(pvs.gas_used_before, lhs.gas_used_before);
builder.connect(pvs.gas_used_after, rhs.gas_used_after);
// Connect lhs `gas_used_after` with rhs `gas_used_before`.
builder.connect(lhs.gas_used_after[0], rhs.gas_used_before[0]);
builder.connect(lhs.gas_used_after[1], rhs.gas_used_before[1]);
// Connect lhs `gas_used_after`with rhs `gas_used_before`.
builder.connect(lhs.gas_used_after, rhs.gas_used_before);
// Connect the `block_bloom` in public values to the lhs and rhs values correctly.
for (&limb0, &limb1) in pvs.block_bloom_after.iter().zip(&rhs.block_bloom_after) {
@ -683,7 +680,7 @@ where
for (&limb0, &limb1) in pvs.block_bloom_before.iter().zip(&lhs.block_bloom_before) {
builder.connect(limb0, limb1);
}
// Connect lhs `block_bloom_after` with rhs `block_bloom_before`.
// Connect lhs `block_bloom_after`with rhs `block_bloom_before`.
for (&limb0, &limb1) in lhs.block_bloom_after.iter().zip(&rhs.block_bloom_before) {
builder.connect(limb0, limb1);
}
@ -855,12 +852,8 @@ where
F: RichField + Extendable<D>,
{
builder.connect(
x.block_metadata.block_gas_used[0],
x.extra_block_data.gas_used_after[0],
);
builder.connect(
x.block_metadata.block_gas_used[1],
x.extra_block_data.gas_used_after[1],
x.block_metadata.block_gas_used,
x.extra_block_data.gas_used_after,
);
for (&limb0, &limb1) in x
@ -880,8 +873,7 @@ where
// The initial number of transactions is 0.
builder.assert_zero(x.extra_block_data.txn_number_before);
// The initial gas used is 0.
builder.assert_zero(x.extra_block_data.gas_used_before[0]);
builder.assert_zero(x.extra_block_data.gas_used_before[1]);
builder.assert_zero(x.extra_block_data.gas_used_before);
// The initial bloom filter is all zeroes.
for t in x.extra_block_data.block_bloom_before {

View File

@ -307,10 +307,7 @@ fn simulate_cpu<F: RichField + Extendable<D>, const D: usize>(
row.context = F::from_canonical_usize(state.registers.context);
row.program_counter = F::from_canonical_usize(pc);
row.is_kernel_mode = F::ONE;
row.gas = [
F::from_canonical_u32(state.registers.gas_used as u32),
F::from_canonical_u32((state.registers.gas_used >> 32) as u32),
];
row.gas = F::from_canonical_u64(state.registers.gas_used);
row.stack_len = F::from_canonical_usize(state.registers.stack_len);
loop {

View File

@ -61,16 +61,12 @@ fn observe_block_metadata<
challenger.observe_element(u256_to_u32(block_metadata.block_number)?);
challenger.observe_element(u256_to_u32(block_metadata.block_difficulty)?);
challenger.observe_elements(&h256_limbs::<F>(block_metadata.block_random));
let gaslimit = u256_to_u64(block_metadata.block_gaslimit)?;
challenger.observe_element(gaslimit.0);
challenger.observe_element(gaslimit.1);
challenger.observe_element(u256_to_u32(block_metadata.block_gaslimit)?);
challenger.observe_element(u256_to_u32(block_metadata.block_chain_id)?);
let basefee = u256_to_u64(block_metadata.block_base_fee)?;
challenger.observe_element(basefee.0);
challenger.observe_element(basefee.1);
let gas_used = u256_to_u64(block_metadata.block_gas_used)?;
challenger.observe_element(gas_used.0);
challenger.observe_element(gas_used.1);
challenger.observe_element(u256_to_u32(block_metadata.block_gas_used)?);
for i in 0..8 {
challenger.observe_elements(&u256_limbs(block_metadata.block_bloom[i]));
}
@ -93,10 +89,10 @@ fn observe_block_metadata_target<
challenger.observe_element(block_metadata.block_number);
challenger.observe_element(block_metadata.block_difficulty);
challenger.observe_elements(&block_metadata.block_random);
challenger.observe_elements(&block_metadata.block_gaslimit);
challenger.observe_element(block_metadata.block_gaslimit);
challenger.observe_element(block_metadata.block_chain_id);
challenger.observe_elements(&block_metadata.block_base_fee);
challenger.observe_elements(&block_metadata.block_gas_used);
challenger.observe_element(block_metadata.block_gas_used);
challenger.observe_elements(&block_metadata.block_bloom);
}
@ -111,12 +107,8 @@ fn observe_extra_block_data<
challenger.observe_elements(&h256_limbs(extra_data.genesis_state_trie_root));
challenger.observe_element(u256_to_u32(extra_data.txn_number_before)?);
challenger.observe_element(u256_to_u32(extra_data.txn_number_after)?);
let gas_used_before = u256_to_u64(extra_data.gas_used_before)?;
challenger.observe_element(gas_used_before.0);
challenger.observe_element(gas_used_before.1);
let gas_used_after = u256_to_u64(extra_data.gas_used_after)?;
challenger.observe_element(gas_used_after.0);
challenger.observe_element(gas_used_after.1);
challenger.observe_element(u256_to_u32(extra_data.gas_used_before)?);
challenger.observe_element(u256_to_u32(extra_data.gas_used_after)?);
for i in 0..8 {
challenger.observe_elements(&u256_limbs(extra_data.block_bloom_before[i]));
}
@ -140,8 +132,8 @@ fn observe_extra_block_data_target<
challenger.observe_elements(&extra_data.genesis_state_trie_root);
challenger.observe_element(extra_data.txn_number_before);
challenger.observe_element(extra_data.txn_number_after);
challenger.observe_elements(&extra_data.gas_used_before);
challenger.observe_elements(&extra_data.gas_used_after);
challenger.observe_element(extra_data.gas_used_before);
challenger.observe_element(extra_data.gas_used_after);
challenger.observe_elements(&extra_data.block_bloom_before);
challenger.observe_elements(&extra_data.block_bloom_after);
}

View File

@ -97,31 +97,26 @@ pub struct BlockHashes {
pub cur_hash: H256,
}
// TODO: Before going into production, `block_gas_used` and `block_gaslimit` here
// as well as `gas_used_before` / `gas_used_after` in `ExtraBlockData` should be
// updated to fit in a single 32-bit limb, as supporting 64-bit values for those
// fields is only necessary for testing purposes.
/// Metadata contained in a block header. Those are identical between
/// all state transition proofs within the same block.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BlockMetadata {
/// The address of this block's producer.
pub block_beneficiary: Address,
/// The timestamp of this block. It must fit in a `u32`.
/// The timestamp of this block.
pub block_timestamp: U256,
/// The index of this block. It must fit in a `u32`.
/// The index of this block.
pub block_number: U256,
/// The difficulty (before PoS transition) of this block.
pub block_difficulty: U256,
/// The `mix_hash` value of this block.
pub block_random: H256,
/// The gas limit of this block. It must fit in a `u64`.
/// The gas limit of this block. It must fit in a `u32`.
pub block_gaslimit: U256,
/// The chain id of this block. It must fit in a `u32`.
/// The chain id of this block.
pub block_chain_id: U256,
/// The base fee of this block. It must fit in a `u64`.
/// The base fee of this block.
pub block_base_fee: U256,
/// The total gas used in this block. It must fit in a `u64`.
/// The total gas used in this block. It must fit in a `u32`.
pub block_gas_used: U256,
/// The block bloom of this block, represented as the consecutive
/// 32-byte chunks of a block's final bloom filter string.
@ -210,10 +205,10 @@ impl PublicValuesTarget {
buffer.write_target(block_number)?;
buffer.write_target(block_difficulty)?;
buffer.write_target_array(&block_random)?;
buffer.write_target_array(&block_gaslimit)?;
buffer.write_target(block_gaslimit)?;
buffer.write_target(block_chain_id)?;
buffer.write_target_array(&block_base_fee)?;
buffer.write_target_array(&block_gas_used)?;
buffer.write_target(block_gas_used)?;
buffer.write_target_array(&block_bloom)?;
let BlockHashesTarget {
@ -235,8 +230,8 @@ impl PublicValuesTarget {
buffer.write_target_array(&genesis_state_root)?;
buffer.write_target(txn_number_before)?;
buffer.write_target(txn_number_after)?;
buffer.write_target_array(&gas_used_before)?;
buffer.write_target_array(&gas_used_after)?;
buffer.write_target(gas_used_before)?;
buffer.write_target(gas_used_after)?;
buffer.write_target_array(&block_bloom_before)?;
buffer.write_target_array(&block_bloom_after)?;
@ -263,10 +258,10 @@ impl PublicValuesTarget {
block_number: buffer.read_target()?,
block_difficulty: buffer.read_target()?,
block_random: buffer.read_target_array()?,
block_gaslimit: buffer.read_target_array()?,
block_gaslimit: buffer.read_target()?,
block_chain_id: buffer.read_target()?,
block_base_fee: buffer.read_target_array()?,
block_gas_used: buffer.read_target_array()?,
block_gas_used: buffer.read_target()?,
block_bloom: buffer.read_target_array()?,
};
@ -279,8 +274,8 @@ impl PublicValuesTarget {
genesis_state_trie_root: buffer.read_target_array()?,
txn_number_before: buffer.read_target()?,
txn_number_after: buffer.read_target()?,
gas_used_before: buffer.read_target_array()?,
gas_used_after: buffer.read_target_array()?,
gas_used_before: buffer.read_target()?,
gas_used_after: buffer.read_target()?,
block_bloom_before: buffer.read_target_array()?,
block_bloom_after: buffer.read_target_array()?,
};
@ -461,20 +456,20 @@ pub(crate) struct BlockMetadataTarget {
/// `Target`s for the `mix_hash` value of this block.
pub(crate) block_random: [Target; 8],
/// `Target`s for the gas limit of this block.
pub(crate) block_gaslimit: [Target; 2],
pub(crate) block_gaslimit: Target,
/// `Target` for the chain id of this block.
pub(crate) block_chain_id: Target,
/// `Target`s for the base fee of this block.
pub(crate) block_base_fee: [Target; 2],
/// `Target`s for the gas used of this block.
pub(crate) block_gas_used: [Target; 2],
pub(crate) block_gas_used: Target,
/// `Target`s for the block bloom of this block.
pub(crate) block_bloom: [Target; 64],
}
impl BlockMetadataTarget {
/// Number of `Target`s required for the block metadata.
pub const SIZE: usize = 87;
pub const SIZE: usize = 85;
/// Extracts block metadata `Target`s from the provided public input `Target`s.
/// The provided `pis` should start with the block metadata.
@ -484,11 +479,11 @@ impl BlockMetadataTarget {
let block_number = pis[6];
let block_difficulty = pis[7];
let block_random = pis[8..16].try_into().unwrap();
let block_gaslimit = pis[16..18].try_into().unwrap();
let block_chain_id = pis[18];
let block_base_fee = pis[19..21].try_into().unwrap();
let block_gas_used = pis[21..23].try_into().unwrap();
let block_bloom = pis[23..87].try_into().unwrap();
let block_gaslimit = pis[16];
let block_chain_id = pis[17];
let block_base_fee = pis[18..20].try_into().unwrap();
let block_gas_used = pis[20];
let block_bloom = pis[21..85].try_into().unwrap();
Self {
block_beneficiary,
@ -526,16 +521,12 @@ impl BlockMetadataTarget {
block_random: core::array::from_fn(|i| {
builder.select(condition, bm0.block_random[i], bm1.block_random[i])
}),
block_gaslimit: core::array::from_fn(|i| {
builder.select(condition, bm0.block_gaslimit[i], bm1.block_gaslimit[i])
}),
block_gaslimit: builder.select(condition, bm0.block_gaslimit, bm1.block_gaslimit),
block_chain_id: builder.select(condition, bm0.block_chain_id, bm1.block_chain_id),
block_base_fee: core::array::from_fn(|i| {
builder.select(condition, bm0.block_base_fee[i], bm1.block_base_fee[i])
}),
block_gas_used: core::array::from_fn(|i| {
builder.select(condition, bm0.block_gas_used[i], bm1.block_gas_used[i])
}),
block_gas_used: builder.select(condition, bm0.block_gas_used, bm1.block_gas_used),
block_bloom: core::array::from_fn(|i| {
builder.select(condition, bm0.block_bloom[i], bm1.block_bloom[i])
}),
@ -557,16 +548,12 @@ impl BlockMetadataTarget {
for i in 0..8 {
builder.connect(bm0.block_random[i], bm1.block_random[i]);
}
for i in 0..2 {
builder.connect(bm0.block_gaslimit[i], bm1.block_gaslimit[i])
}
builder.connect(bm0.block_gaslimit, bm1.block_gaslimit);
builder.connect(bm0.block_chain_id, bm1.block_chain_id);
for i in 0..2 {
builder.connect(bm0.block_base_fee[i], bm1.block_base_fee[i])
}
for i in 0..2 {
builder.connect(bm0.block_gas_used[i], bm1.block_gas_used[i])
}
builder.connect(bm0.block_gas_used, bm1.block_gas_used);
for i in 0..64 {
builder.connect(bm0.block_bloom[i], bm1.block_bloom[i])
}
@ -650,10 +637,10 @@ pub(crate) struct ExtraBlockDataTarget {
pub txn_number_after: Target,
/// `Target` for the accumulated gas used prior execution of the local state transition, starting
/// at 0 for the initial transaction of a block.
pub gas_used_before: [Target; 2],
pub gas_used_before: Target,
/// `Target` for the accumulated gas used after execution of the local state transition. It should
/// match the `block_gas_used` value after execution of the last transaction in a block.
pub gas_used_after: [Target; 2],
pub gas_used_after: Target,
/// `Target`s for the accumulated bloom filter of this block prior execution of the local state transition,
/// starting with all zeros for the initial transaction of a block.
pub block_bloom_before: [Target; 64],
@ -664,7 +651,7 @@ pub(crate) struct ExtraBlockDataTarget {
impl ExtraBlockDataTarget {
/// Number of `Target`s required for the extra block data.
const SIZE: usize = 142;
const SIZE: usize = 140;
/// Extracts the extra block data `Target`s from the public input `Target`s.
/// The provided `pis` should start with the extra vblock data.
@ -672,10 +659,10 @@ impl ExtraBlockDataTarget {
let genesis_state_trie_root = pis[0..8].try_into().unwrap();
let txn_number_before = pis[8];
let txn_number_after = pis[9];
let gas_used_before = pis[10..12].try_into().unwrap();
let gas_used_after = pis[12..14].try_into().unwrap();
let block_bloom_before = pis[14..78].try_into().unwrap();
let block_bloom_after = pis[78..142].try_into().unwrap();
let gas_used_before = pis[10];
let gas_used_after = pis[11];
let block_bloom_before = pis[12..76].try_into().unwrap();
let block_bloom_after = pis[76..140].try_into().unwrap();
Self {
genesis_state_trie_root,
@ -710,12 +697,8 @@ impl ExtraBlockDataTarget {
ed1.txn_number_before,
),
txn_number_after: builder.select(condition, ed0.txn_number_after, ed1.txn_number_after),
gas_used_before: core::array::from_fn(|i| {
builder.select(condition, ed0.gas_used_before[i], ed1.gas_used_before[i])
}),
gas_used_after: core::array::from_fn(|i| {
builder.select(condition, ed0.gas_used_after[i], ed1.gas_used_after[i])
}),
gas_used_before: builder.select(condition, ed0.gas_used_before, ed1.gas_used_before),
gas_used_after: builder.select(condition, ed0.gas_used_after, ed1.gas_used_after),
block_bloom_before: core::array::from_fn(|i| {
builder.select(
condition,
@ -747,12 +730,8 @@ impl ExtraBlockDataTarget {
}
builder.connect(ed0.txn_number_before, ed1.txn_number_before);
builder.connect(ed0.txn_number_after, ed1.txn_number_after);
for i in 0..2 {
builder.connect(ed0.gas_used_before[i], ed1.gas_used_before[i]);
}
for i in 0..2 {
builder.connect(ed1.gas_used_after[i], ed1.gas_used_after[i]);
}
builder.connect(ed0.gas_used_before, ed1.gas_used_before);
builder.connect(ed1.gas_used_after, ed1.gas_used_after);
for i in 0..64 {
builder.connect(ed0.block_bloom_before[i], ed1.block_bloom_before[i]);
}

View File

@ -443,10 +443,26 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
GlobalMetadata::BlockDifficulty as usize,
public_values.block_metadata.block_difficulty,
),
(
GlobalMetadata::BlockGasLimit as usize,
public_values.block_metadata.block_gaslimit,
),
(
GlobalMetadata::BlockChainId as usize,
public_values.block_metadata.block_chain_id,
),
(
GlobalMetadata::BlockGasUsed as usize,
public_values.block_metadata.block_gas_used,
),
(
GlobalMetadata::BlockGasUsedBefore as usize,
public_values.extra_block_data.gas_used_before,
),
(
GlobalMetadata::BlockGasUsedAfter as usize,
public_values.extra_block_data.gas_used_after,
),
(
GlobalMetadata::TxnNumberBefore as usize,
public_values.extra_block_data.txn_number_before,
@ -457,10 +473,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
),
];
// This contains the `block_beneficiary`, `block_random`, `block_base_fee`,
// `block_gaslimit`, `block_gas_used` as well as `cur_hash`, `gas_used_before`
// and `gas_used_after`.
let block_fields_arrays: [(usize, &[Target]); 8] = [
let beneficiary_random_base_fee_cur_hash_fields: [(usize, &[Target]); 4] = [
(
GlobalMetadata::BlockBeneficiary as usize,
&public_values.block_metadata.block_beneficiary,
@ -473,26 +486,10 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
GlobalMetadata::BlockBaseFee as usize,
&public_values.block_metadata.block_base_fee,
),
(
GlobalMetadata::BlockGasLimit as usize,
&public_values.block_metadata.block_gaslimit,
),
(
GlobalMetadata::BlockGasUsed as usize,
&public_values.block_metadata.block_gas_used,
),
(
GlobalMetadata::BlockCurrentHash as usize,
&public_values.block_hashes.cur_hash,
),
(
GlobalMetadata::BlockGasUsedBefore as usize,
&public_values.extra_block_data.gas_used_before,
),
(
GlobalMetadata::BlockGasUsedAfter as usize,
&public_values.extra_block_data.gas_used_after,
),
];
let metadata_segment = builder.constant(F::from_canonical_u32(Segment::GlobalMetadata as u32));
@ -508,7 +505,7 @@ pub(crate) fn get_memory_extra_looking_products_circuit<
);
});
block_fields_arrays.map(|(field, targets)| {
beneficiary_random_base_fee_cur_hash_fields.map(|(field, targets)| {
product = add_data_write(
builder,
challenge,
@ -704,10 +701,10 @@ pub(crate) fn add_virtual_block_metadata<F: RichField + Extendable<D>, const D:
let block_number = builder.add_virtual_public_input();
let block_difficulty = builder.add_virtual_public_input();
let block_random = builder.add_virtual_public_input_arr();
let block_gaslimit = builder.add_virtual_public_input_arr();
let block_gaslimit = builder.add_virtual_public_input();
let block_chain_id = builder.add_virtual_public_input();
let block_base_fee = builder.add_virtual_public_input_arr();
let block_gas_used = builder.add_virtual_public_input_arr();
let block_gas_used = builder.add_virtual_public_input();
let block_bloom = builder.add_virtual_public_input_arr();
BlockMetadataTarget {
block_beneficiary,
@ -739,8 +736,8 @@ pub(crate) fn add_virtual_extra_block_data<F: RichField + Extendable<D>, const D
let genesis_state_trie_root = builder.add_virtual_public_input_arr();
let txn_number_before = builder.add_virtual_public_input();
let txn_number_after = builder.add_virtual_public_input();
let gas_used_before = builder.add_virtual_public_input_arr();
let gas_used_after = builder.add_virtual_public_input_arr();
let gas_used_before = builder.add_virtual_public_input();
let gas_used_after = builder.add_virtual_public_input();
let block_bloom_before: [Target; 64] = builder.add_virtual_public_input_arr();
let block_bloom_after: [Target; 64] = builder.add_virtual_public_input_arr();
ExtraBlockDataTarget {
@ -953,10 +950,10 @@ where
&block_metadata_target.block_random,
&h256_limbs(block_metadata.block_random),
);
// Gaslimit fits in 2 limbs
let gaslimit = u256_to_u64(block_metadata.block_gaslimit)?;
witness.set_target(block_metadata_target.block_gaslimit[0], gaslimit.0);
witness.set_target(block_metadata_target.block_gaslimit[1], gaslimit.1);
witness.set_target(
block_metadata_target.block_gaslimit,
u256_to_u32(block_metadata.block_gaslimit)?,
);
witness.set_target(
block_metadata_target.block_chain_id,
u256_to_u32(block_metadata.block_chain_id)?,
@ -965,10 +962,10 @@ where
let basefee = u256_to_u64(block_metadata.block_base_fee)?;
witness.set_target(block_metadata_target.block_base_fee[0], basefee.0);
witness.set_target(block_metadata_target.block_base_fee[1], basefee.1);
// Gas used fits in 2 limbs
let gas_used = u256_to_u64(block_metadata.block_gas_used)?;
witness.set_target(block_metadata_target.block_gas_used[0], gas_used.0);
witness.set_target(block_metadata_target.block_gas_used[1], gas_used.1);
witness.set_target(
block_metadata_target.block_gas_used,
u256_to_u32(block_metadata.block_gas_used)?,
);
let mut block_bloom_limbs = [F::ZERO; 64];
for (i, limbs) in block_bloom_limbs.chunks_exact_mut(8).enumerate() {
limbs.copy_from_slice(&u256_limbs(block_metadata.block_bloom[i]));
@ -1018,13 +1015,8 @@ where
ed_target.txn_number_after,
u256_to_u32(ed.txn_number_after)?,
);
// Gas used before/after fit in 2 limbs
let gas_used_before = u256_to_u64(ed.gas_used_before)?;
witness.set_target(ed_target.gas_used_before[0], gas_used_before.0);
witness.set_target(ed_target.gas_used_before[1], gas_used_before.1);
let gas_used_after = u256_to_u64(ed.gas_used_after)?;
witness.set_target(ed_target.gas_used_after[0], gas_used_after.0);
witness.set_target(ed_target.gas_used_after[1], gas_used_after.1);
witness.set_target(ed_target.gas_used_before, u256_to_u32(ed.gas_used_before)?);
witness.set_target(ed_target.gas_used_after, u256_to_u32(ed.gas_used_after)?);
let block_bloom_before = ed.block_bloom_before;
let mut block_bloom_limbs = [F::ZERO; 64];

View File

@ -681,7 +681,7 @@ pub(crate) fn generate_syscall<F: Field>(
state: &mut GenerationState<F>,
mut row: CpuColumnsView<F>,
) -> Result<(), ProgramError> {
if TryInto::<u64>::try_into(state.registers.gas_used).is_err() {
if TryInto::<u32>::try_into(state.registers.gas_used).is_err() {
return Err(ProgramError::GasLimitError);
}
@ -786,7 +786,7 @@ pub(crate) fn generate_exit_kernel<F: Field>(
assert!(is_kernel_mode_val == 0 || is_kernel_mode_val == 1);
let is_kernel_mode = is_kernel_mode_val != 0;
let gas_used_val = kexit_info.0[3];
if TryInto::<u64>::try_into(gas_used_val).is_err() {
if TryInto::<u32>::try_into(gas_used_val).is_err() {
return Err(ProgramError::GasLimitError);
}
@ -944,7 +944,7 @@ pub(crate) fn generate_exception<F: Field>(
state: &mut GenerationState<F>,
mut row: CpuColumnsView<F>,
) -> Result<(), ProgramError> {
if TryInto::<u64>::try_into(state.registers.gas_used).is_err() {
if TryInto::<u32>::try_into(state.registers.gas_used).is_err() {
return Err(ProgramError::GasLimitError);
}

View File

@ -303,10 +303,7 @@ fn base_row<F: Field>(state: &mut GenerationState<F>) -> (CpuColumnsView<F>, u8)
row.context = F::from_canonical_usize(state.registers.context);
row.program_counter = F::from_canonical_usize(state.registers.program_counter);
row.is_kernel_mode = F::from_bool(state.registers.is_kernel);
row.gas = [
F::from_canonical_u32(state.registers.gas_used as u32),
F::from_canonical_u32((state.registers.gas_used >> 32) as u32),
];
row.gas = F::from_canonical_u64(state.registers.gas_used);
row.stack_len = F::from_canonical_usize(state.registers.stack_len);
fill_channel_with_value(&mut row, 0, state.registers.stack_top);