mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 16:53:07 +00:00
parent
a4b714e64d
commit
b7e93511e4
@ -159,6 +159,7 @@ after_constructor:
|
|||||||
%stack (size, ctx) -> (ctx, @SEGMENT_RETURNDATA, 0, size) // context, segment, offset, len
|
%stack (size, ctx) -> (ctx, @SEGMENT_RETURNDATA, 0, size) // context, segment, offset, len
|
||||||
KECCAK_GENERAL
|
KECCAK_GENERAL
|
||||||
// stack: codehash, leftover_gas, success, address, kexit_info
|
// stack: codehash, leftover_gas, success, address, kexit_info
|
||||||
|
%observe_new_contract
|
||||||
DUP4
|
DUP4
|
||||||
// stack: address, codehash, leftover_gas, success, address, kexit_info
|
// stack: address, codehash, leftover_gas, success, address, kexit_info
|
||||||
%set_codehash
|
%set_codehash
|
||||||
@ -189,7 +190,7 @@ after_constructor:
|
|||||||
// Pre stack: addr, codehash, redest
|
// Pre stack: addr, codehash, redest
|
||||||
// Post stack: (empty)
|
// Post stack: (empty)
|
||||||
// TODO: Should it be copy-on-write (with make_account_copy) instead of mutating the trie?
|
// TODO: Should it be copy-on-write (with make_account_copy) instead of mutating the trie?
|
||||||
set_codehash:
|
global set_codehash:
|
||||||
// stack: addr, codehash, retdest
|
// stack: addr, codehash, retdest
|
||||||
%mpt_read_state_trie
|
%mpt_read_state_trie
|
||||||
// stack: account_ptr, codehash, retdest
|
// stack: account_ptr, codehash, retdest
|
||||||
@ -208,3 +209,20 @@ set_codehash:
|
|||||||
%num_bytes_to_num_words %mul_const(@INITCODE_WORD_COST)
|
%num_bytes_to_num_words %mul_const(@INITCODE_WORD_COST)
|
||||||
%charge_gas
|
%charge_gas
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
|
||||||
|
// This should be called whenever a new contract is created.
|
||||||
|
// It does nothing, but just provides a single hook where code can react to newly created contracts.
|
||||||
|
// When called, the code corresponding to `codehash` should be stored in the return data.
|
||||||
|
// Pre stack: codehash, retdest
|
||||||
|
// Post stack: codehash
|
||||||
|
global observe_new_contract:
|
||||||
|
// stack codehash, retdest
|
||||||
|
SWAP1 JUMP
|
||||||
|
|
||||||
|
%macro observe_new_contract
|
||||||
|
%stack (codehash) -> (codehash, %%after)
|
||||||
|
%jump(observe_new_contract)
|
||||||
|
%%after:
|
||||||
|
// stack: codehash
|
||||||
|
%endmacro
|
||||||
|
|||||||
@ -158,6 +158,19 @@ global process_contract_creation_txn_after_constructor:
|
|||||||
DUP2 DUP2 LT %jumpi(panic) // TODO: need to revert changes here.
|
DUP2 DUP2 LT %jumpi(panic) // TODO: need to revert changes here.
|
||||||
// stack: leftover_gas, codedeposit_cost, new_ctx, address, retdest
|
// stack: leftover_gas, codedeposit_cost, new_ctx, address, retdest
|
||||||
SUB
|
SUB
|
||||||
|
|
||||||
|
// Store the code hash of the new contract.
|
||||||
|
// stack: leftover_gas, new_ctx, address, retdest
|
||||||
|
GET_CONTEXT
|
||||||
|
%returndatasize
|
||||||
|
%stack (size, ctx) -> (ctx, @SEGMENT_RETURNDATA, 0, size) // context, segment, offset, len
|
||||||
|
KECCAK_GENERAL
|
||||||
|
// stack: codehash, leftover_gas, new_ctx, address, retdest
|
||||||
|
%observe_new_contract
|
||||||
|
DUP4
|
||||||
|
// stack: address, codehash, leftover_gas, new_ctx, address, retdest
|
||||||
|
%set_codehash
|
||||||
|
|
||||||
// stack: leftover_gas, new_ctx, address, retdest
|
// stack: leftover_gas, new_ctx, address, retdest
|
||||||
%pay_coinbase_and_refund_sender
|
%pay_coinbase_and_refund_sender
|
||||||
// TODO: Delete accounts in self-destruct list and empty touched addresses.
|
// TODO: Delete accounts in self-destruct list and empty touched addresses.
|
||||||
|
|||||||
@ -5,10 +5,12 @@ use keccak_hash::keccak;
|
|||||||
use plonky2::field::types::Field;
|
use plonky2::field::types::Field;
|
||||||
|
|
||||||
use crate::cpu::kernel::aggregator::KERNEL;
|
use crate::cpu::kernel::aggregator::KERNEL;
|
||||||
|
use crate::cpu::kernel::constants::context_metadata::ContextMetadata;
|
||||||
use crate::generation::mpt::all_mpt_prover_inputs_reversed;
|
use crate::generation::mpt::all_mpt_prover_inputs_reversed;
|
||||||
use crate::generation::rlp::all_rlp_prover_inputs_reversed;
|
use crate::generation::rlp::all_rlp_prover_inputs_reversed;
|
||||||
use crate::generation::GenerationInputs;
|
use crate::generation::GenerationInputs;
|
||||||
use crate::witness::memory::MemoryState;
|
use crate::memory::segments::Segment;
|
||||||
|
use crate::witness::memory::{MemoryAddress, MemoryState};
|
||||||
use crate::witness::state::RegistersState;
|
use crate::witness::state::RegistersState;
|
||||||
use crate::witness::traces::{TraceCheckpoint, Traces};
|
use crate::witness::traces::{TraceCheckpoint, Traces};
|
||||||
use crate::witness::util::stack_peek;
|
use crate::witness::util::stack_peek;
|
||||||
@ -83,6 +85,10 @@ impl<F: Field> GenerationState<F> {
|
|||||||
let tip_h256 = H256::from_uint(&tip_u256);
|
let tip_h256 = H256::from_uint(&tip_u256);
|
||||||
let tip_h160 = H160::from(tip_h256);
|
let tip_h160 = H160::from(tip_h256);
|
||||||
self.observe_address(tip_h160);
|
self.observe_address(tip_h160);
|
||||||
|
} else if dst == KERNEL.global_labels["observe_new_contract"] {
|
||||||
|
let tip_u256 = stack_peek(self, 0).expect("Empty stack");
|
||||||
|
let tip_h256 = H256::from_uint(&tip_u256);
|
||||||
|
self.observe_contract(tip_h256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +99,30 @@ impl<F: Field> GenerationState<F> {
|
|||||||
self.state_key_to_address.insert(state_key, address);
|
self.state_key_to_address.insert(state_key, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Observe the given code hash and store the associated code.
|
||||||
|
/// When called, the code corresponding to `codehash` should be stored in the return data.
|
||||||
|
pub fn observe_contract(&mut self, codehash: H256) {
|
||||||
|
if self.inputs.contract_code.contains_key(&codehash) {
|
||||||
|
return; // Return early if the code hash has already been observed.
|
||||||
|
}
|
||||||
|
|
||||||
|
let ctx = self.registers.context;
|
||||||
|
let returndata_size_addr = MemoryAddress::new(
|
||||||
|
ctx,
|
||||||
|
Segment::ContextMetadata,
|
||||||
|
ContextMetadata::ReturndataSize as usize,
|
||||||
|
);
|
||||||
|
let returndata_size = self.memory.get(returndata_size_addr).as_usize();
|
||||||
|
let code = self.memory.contexts[ctx].segments[Segment::Returndata as usize].content
|
||||||
|
[..returndata_size]
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.as_u32() as u8)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
debug_assert_eq!(keccak(&code), codehash);
|
||||||
|
|
||||||
|
self.inputs.contract_code.insert(codehash, code);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn checkpoint(&self) -> GenerationStateCheckpoint {
|
pub fn checkpoint(&self) -> GenerationStateCheckpoint {
|
||||||
GenerationStateCheckpoint {
|
GenerationStateCheckpoint {
|
||||||
registers: self.registers,
|
registers: self.registers,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user