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

Commit

Permalink
Revert "Make gas fit in 2 limbs (0xPolygonZero#1261)"
Browse files Browse the repository at this point in the history
This reverts commit 0f19cd0.
  • Loading branch information
Nashtare committed Nov 16, 2023
1 parent 40d3c6d commit d468da3
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 185 deletions.
4 changes: 2 additions & 2 deletions evm/src/cpu/columns/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
Expand Down
36 changes: 13 additions & 23 deletions evm/src/cpu/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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),
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
13 changes: 7 additions & 6 deletions evm/src/cpu/jumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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);
}
}

Expand Down
21 changes: 9 additions & 12 deletions evm/src/cpu/syscalls_exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,17 @@ 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).
yield_constr.constraint(filter_syscall * (output[0] - (lv.program_counter + P::ONES)));
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));
// TODO: Range check `output[6]`.
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
Expand Down Expand Up @@ -270,9 +269,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);
}

Expand All @@ -297,15 +294,15 @@ 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);
}
// TODO: Range check `output[6]`.
{
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);
}

Expand Down
26 changes: 9 additions & 17 deletions evm/src/fixed_recursive_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand Down
5 changes: 1 addition & 4 deletions evm/src/generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
24 changes: 8 additions & 16 deletions evm/src/get_challenges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]));
}
Expand All @@ -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);
}

Expand All @@ -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]));
}
Expand All @@ -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);
}
Expand Down
Loading

0 comments on commit d468da3

Please sign in to comment.