mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-06 07:43:10 +00:00
Add custom opcodes
- `GET_STATE_ROOT` and `SET_STATE_ROOT` deal with the root of the state trie, and will be called from storage routines. Similarly `GET_RECEIPT_ROOT` and `SET_RECEIPT_ROOT` deal with the root of the receipt trie. - `PANIC` enables an unsatisfiable constraint, so no proof can be generated. - `GET_CONTEXT` and `SET_CONTEXT`, used when calling and returning - `CONSUME_GAS` charges the sender gas; useful for cases where gas calculations are nontrivial and best implemented in assembly. - `EXIT_KERNEL` simply clears the CPU flag indicating that we're in kernel mode; it would be used just before a jump to return to the (userspace) caller. - `MLOAD_GENERAL` and `MSTORE_GENERAL` are for reading and writing memory, but they're not limited to the main memory segment of the current context; they can access any context and any segment. I added a couple macros to show how the they would typically be used. There may be more later, but these are the ones I think we need for now. I tried to fill in smaller invalid sections of the decoder's tree, as Jacqui suggested, while keeping related opcodes together. We can fine tune it when the opcode list is more stable. These are all intended to be priviledged, i.e. they will be treated as invalid if used from userspace, for compatibility as well as (in some cases) security reasons.
This commit is contained in:
parent
a9fe08a4a7
commit
925483ed1e
@ -90,6 +90,10 @@ pub struct CpuColumnsView<T> {
|
|||||||
pub is_msize: T,
|
pub is_msize: T,
|
||||||
pub is_gas: T,
|
pub is_gas: T,
|
||||||
pub is_jumpdest: T,
|
pub is_jumpdest: T,
|
||||||
|
pub is_get_state_root: T,
|
||||||
|
pub is_set_state_root: T,
|
||||||
|
pub is_get_receipt_root: T,
|
||||||
|
pub is_set_receipt_root: T,
|
||||||
pub is_push: T,
|
pub is_push: T,
|
||||||
pub is_dup: T,
|
pub is_dup: T,
|
||||||
pub is_swap: T,
|
pub is_swap: T,
|
||||||
@ -98,13 +102,20 @@ pub struct CpuColumnsView<T> {
|
|||||||
pub is_log2: T,
|
pub is_log2: T,
|
||||||
pub is_log3: T,
|
pub is_log3: T,
|
||||||
pub is_log4: T,
|
pub is_log4: T,
|
||||||
|
pub is_panic: T,
|
||||||
pub is_create: T,
|
pub is_create: T,
|
||||||
pub is_call: T,
|
pub is_call: T,
|
||||||
pub is_callcode: T,
|
pub is_callcode: T,
|
||||||
pub is_return: T,
|
pub is_return: T,
|
||||||
pub is_delegatecall: T,
|
pub is_delegatecall: T,
|
||||||
pub is_create2: T,
|
pub is_create2: T,
|
||||||
|
pub is_get_context: T,
|
||||||
|
pub is_set_context: T,
|
||||||
|
pub is_consume_gas: T,
|
||||||
|
pub is_exit_kernel: T,
|
||||||
pub is_staticcall: T,
|
pub is_staticcall: T,
|
||||||
|
pub is_mload_general: T,
|
||||||
|
pub is_mstore_general: T,
|
||||||
pub is_revert: T,
|
pub is_revert: T,
|
||||||
pub is_selfdestruct: T,
|
pub is_selfdestruct: T,
|
||||||
|
|
||||||
@ -124,12 +135,6 @@ pub struct CpuColumnsView<T> {
|
|||||||
pub is_invalid_12: T,
|
pub is_invalid_12: T,
|
||||||
pub is_invalid_13: T,
|
pub is_invalid_13: T,
|
||||||
pub is_invalid_14: T,
|
pub is_invalid_14: T,
|
||||||
pub is_invalid_15: T,
|
|
||||||
pub is_invalid_16: T,
|
|
||||||
pub is_invalid_17: T,
|
|
||||||
pub is_invalid_18: T,
|
|
||||||
pub is_invalid_19: T,
|
|
||||||
pub is_invalid_20: T,
|
|
||||||
|
|
||||||
/// If CPU cycle: the opcode, broken up into bits in **big-endian** order.
|
/// If CPU cycle: the opcode, broken up into bits in **big-endian** order.
|
||||||
pub opcode_bits: [T; 8],
|
pub opcode_bits: [T; 8],
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::cpu::columns::{CpuColumnsView, COL_MAP};
|
|||||||
// - its start index is a multiple of its length (it is aligned)
|
// - its start index is a multiple of its length (it is aligned)
|
||||||
// These properties permit us to check if an opcode belongs to a block of length 2^n by checking its
|
// These properties permit us to check if an opcode belongs to a block of length 2^n by checking its
|
||||||
// top 8-n bits.
|
// top 8-n bits.
|
||||||
const OPCODES: [(u64, usize, usize); 102] = [
|
const OPCODES: [(u64, usize, usize); 107] = [
|
||||||
// (start index of block, number of top bits to check (log2), flag column)
|
// (start index of block, number of top bits to check (log2), flag column)
|
||||||
(0x00, 0, COL_MAP.is_stop),
|
(0x00, 0, COL_MAP.is_stop),
|
||||||
(0x01, 0, COL_MAP.is_add),
|
(0x01, 0, COL_MAP.is_add),
|
||||||
@ -90,34 +90,39 @@ const OPCODES: [(u64, usize, usize); 102] = [
|
|||||||
(0x59, 0, COL_MAP.is_msize),
|
(0x59, 0, COL_MAP.is_msize),
|
||||||
(0x5a, 0, COL_MAP.is_gas),
|
(0x5a, 0, COL_MAP.is_gas),
|
||||||
(0x5b, 0, COL_MAP.is_jumpdest),
|
(0x5b, 0, COL_MAP.is_jumpdest),
|
||||||
(0x5c, 2, COL_MAP.is_invalid_9), // 0x5c-0x5f
|
(0x5c, 0, COL_MAP.is_get_state_root),
|
||||||
(0x60, 5, COL_MAP.is_push), // 0x60-0x7f
|
(0x5d, 0, COL_MAP.is_set_state_root),
|
||||||
(0x80, 4, COL_MAP.is_dup), // 0x80-0x8f
|
(0x5e, 0, COL_MAP.is_get_receipt_root),
|
||||||
(0x90, 4, COL_MAP.is_swap), // 0x90-0x9f
|
(0x5f, 0, COL_MAP.is_set_receipt_root),
|
||||||
|
(0x60, 5, COL_MAP.is_push), // 0x60-0x7f
|
||||||
|
(0x80, 4, COL_MAP.is_dup), // 0x80-0x8f
|
||||||
|
(0x90, 4, COL_MAP.is_swap), // 0x90-0x9f
|
||||||
(0xa0, 0, COL_MAP.is_log0),
|
(0xa0, 0, COL_MAP.is_log0),
|
||||||
(0xa1, 0, COL_MAP.is_log1),
|
(0xa1, 0, COL_MAP.is_log1),
|
||||||
(0xa2, 0, COL_MAP.is_log2),
|
(0xa2, 0, COL_MAP.is_log2),
|
||||||
(0xa3, 0, COL_MAP.is_log3),
|
(0xa3, 0, COL_MAP.is_log3),
|
||||||
(0xa4, 0, COL_MAP.is_log4),
|
(0xa4, 0, COL_MAP.is_log4),
|
||||||
(0xa5, 0, COL_MAP.is_invalid_10),
|
(0xa5, 0, COL_MAP.is_panic),
|
||||||
(0xa6, 1, COL_MAP.is_invalid_11), // 0xa6-0xa7
|
(0xa6, 1, COL_MAP.is_invalid_9), // 0xa6-0xa7
|
||||||
(0xa8, 3, COL_MAP.is_invalid_12), // 0xa8-0xaf
|
(0xa8, 3, COL_MAP.is_invalid_10), // 0xa8-0xaf
|
||||||
(0xb0, 4, COL_MAP.is_invalid_13), // 0xb0-0xbf
|
(0xb0, 4, COL_MAP.is_invalid_11), // 0xb0-0xbf
|
||||||
(0xc0, 5, COL_MAP.is_invalid_14), // 0xc0-0xdf
|
(0xc0, 5, COL_MAP.is_invalid_12), // 0xc0-0xdf
|
||||||
(0xe0, 4, COL_MAP.is_invalid_15), // 0xe0-0xef
|
(0xe0, 4, COL_MAP.is_invalid_13), // 0xe0-0xef
|
||||||
(0xf0, 0, COL_MAP.is_create),
|
(0xf0, 0, COL_MAP.is_create),
|
||||||
(0xf1, 0, COL_MAP.is_call),
|
(0xf1, 0, COL_MAP.is_call),
|
||||||
(0xf2, 0, COL_MAP.is_callcode),
|
(0xf2, 0, COL_MAP.is_callcode),
|
||||||
(0xf3, 0, COL_MAP.is_return),
|
(0xf3, 0, COL_MAP.is_return),
|
||||||
(0xf4, 0, COL_MAP.is_delegatecall),
|
(0xf4, 0, COL_MAP.is_delegatecall),
|
||||||
(0xf5, 0, COL_MAP.is_create2),
|
(0xf5, 0, COL_MAP.is_create2),
|
||||||
(0xf6, 1, COL_MAP.is_invalid_16), // 0xf6-0xf7
|
(0xf6, 0, COL_MAP.is_get_context),
|
||||||
(0xf8, 1, COL_MAP.is_invalid_17), // 0xf8-0xf9
|
(0xf7, 0, COL_MAP.is_set_context),
|
||||||
|
(0xf8, 0, COL_MAP.is_consume_gas),
|
||||||
|
(0xf9, 0, COL_MAP.is_exit_kernel),
|
||||||
(0xfa, 0, COL_MAP.is_staticcall),
|
(0xfa, 0, COL_MAP.is_staticcall),
|
||||||
(0xfb, 0, COL_MAP.is_invalid_18),
|
(0xfb, 0, COL_MAP.is_mload_general),
|
||||||
(0xfc, 0, COL_MAP.is_invalid_19),
|
(0xfc, 0, COL_MAP.is_mstore_general),
|
||||||
(0xfd, 0, COL_MAP.is_revert),
|
(0xfd, 0, COL_MAP.is_revert),
|
||||||
(0xfe, 0, COL_MAP.is_invalid_20),
|
(0xfe, 0, COL_MAP.is_invalid_14),
|
||||||
(0xff, 0, COL_MAP.is_selfdestruct),
|
(0xff, 0, COL_MAP.is_selfdestruct),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
27
evm/src/cpu/kernel/asm/memory.asm
Normal file
27
evm/src/cpu/kernel/asm/memory.asm
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Load a byte from the given segment of the current context's memory space.
|
||||||
|
// Note that main memory values are one byte each, but in general memory values
|
||||||
|
// can be 256 bits. This macro deals with a single address (unlike MSTORE), so
|
||||||
|
// if it is used with main memory, it will load a single byte.
|
||||||
|
%macro mload_current(segment)
|
||||||
|
// stack: offset
|
||||||
|
PUSH $segment
|
||||||
|
// stack: segment, offset
|
||||||
|
CURRENT_CONTEXT
|
||||||
|
// stack: context, segment, offset
|
||||||
|
MLOAD_GENERAL
|
||||||
|
// stack: value
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
// Store a byte to the given segment of the current context's memory space.
|
||||||
|
// Note that main memory values are one byte each, but in general memory values
|
||||||
|
// can be 256 bits. This macro deals with a single address (unlike MSTORE), so
|
||||||
|
// if it is used with main memory, it will store a single byte.
|
||||||
|
%macro mstore_current(segment)
|
||||||
|
// stack: offset, value
|
||||||
|
PUSH $segment
|
||||||
|
// stack: segment, offset, value
|
||||||
|
CURRENT_CONTEXT
|
||||||
|
// stack: context, segment, offset, value
|
||||||
|
MSTORE_GENERAL
|
||||||
|
// stack: (empty)
|
||||||
|
%endmacro
|
||||||
@ -115,6 +115,10 @@ impl<'a> Interpreter<'a> {
|
|||||||
0x59 => todo!(), // "MSIZE",
|
0x59 => todo!(), // "MSIZE",
|
||||||
0x5a => todo!(), // "GAS",
|
0x5a => todo!(), // "GAS",
|
||||||
0x5b => (), // "JUMPDEST",
|
0x5b => (), // "JUMPDEST",
|
||||||
|
0x5c => todo!(), // "GET_STATE_ROOT",
|
||||||
|
0x5d => todo!(), // "SET_STATE_ROOT",
|
||||||
|
0x5e => todo!(), // "GET_RECEIPT_ROOT",
|
||||||
|
0x5f => todo!(), // "SET_RECEIPT_ROOT",
|
||||||
x if (0x60..0x80).contains(&x) => self.run_push(x - 0x5f), // "PUSH"
|
x if (0x60..0x80).contains(&x) => self.run_push(x - 0x5f), // "PUSH"
|
||||||
x if (0x80..0x90).contains(&x) => self.run_dup(x - 0x7f), // "DUP"
|
x if (0x80..0x90).contains(&x) => self.run_dup(x - 0x7f), // "DUP"
|
||||||
x if (0x90..0xa0).contains(&x) => self.run_swap(x - 0x8f), // "SWAP"
|
x if (0x90..0xa0).contains(&x) => self.run_swap(x - 0x8f), // "SWAP"
|
||||||
@ -123,13 +127,20 @@ impl<'a> Interpreter<'a> {
|
|||||||
0xa2 => todo!(), // "LOG2",
|
0xa2 => todo!(), // "LOG2",
|
||||||
0xa3 => todo!(), // "LOG3",
|
0xa3 => todo!(), // "LOG3",
|
||||||
0xa4 => todo!(), // "LOG4",
|
0xa4 => todo!(), // "LOG4",
|
||||||
|
0xa5 => panic!("Executed PANIC"), // "PANIC",
|
||||||
0xf0 => todo!(), // "CREATE",
|
0xf0 => todo!(), // "CREATE",
|
||||||
0xf1 => todo!(), // "CALL",
|
0xf1 => todo!(), // "CALL",
|
||||||
0xf2 => todo!(), // "CALLCODE",
|
0xf2 => todo!(), // "CALLCODE",
|
||||||
0xf3 => todo!(), // "RETURN",
|
0xf3 => todo!(), // "RETURN",
|
||||||
0xf4 => todo!(), // "DELEGATECALL",
|
0xf4 => todo!(), // "DELEGATECALL",
|
||||||
0xf5 => todo!(), // "CREATE2",
|
0xf5 => todo!(), // "CREATE2",
|
||||||
|
0xf6 => todo!(), // "GET_CONTEXT",
|
||||||
|
0xf7 => todo!(), // "SET_CONTEXT",
|
||||||
|
0xf8 => todo!(), // "CONSUME_GAS",
|
||||||
|
0xf9 => todo!(), // "EXIT_KERNEL",
|
||||||
0xfa => todo!(), // "STATICCALL",
|
0xfa => todo!(), // "STATICCALL",
|
||||||
|
0xfb => todo!(), // "MLOAD_GENERAL",
|
||||||
|
0xfc => todo!(), // "MSTORE_GENERAL",
|
||||||
0xfd => todo!(), // "REVERT",
|
0xfd => todo!(), // "REVERT",
|
||||||
0xfe => todo!(), // "INVALID",
|
0xfe => todo!(), // "INVALID",
|
||||||
0xff => todo!(), // "SELFDESTRUCT",
|
0xff => todo!(), // "SELFDESTRUCT",
|
||||||
|
|||||||
@ -71,6 +71,10 @@ pub(crate) fn get_opcode(mnemonic: &str) -> u8 {
|
|||||||
"MSIZE" => 0x59,
|
"MSIZE" => 0x59,
|
||||||
"GAS" => 0x5a,
|
"GAS" => 0x5a,
|
||||||
"JUMPDEST" => 0x5b,
|
"JUMPDEST" => 0x5b,
|
||||||
|
"GET_STATE_ROOT" => 0x5c,
|
||||||
|
"SET_STATE_ROOT" => 0x5d,
|
||||||
|
"GET_RECEIPT_ROOT" => 0x5e,
|
||||||
|
"SET_RECEIPT_ROOT" => 0x5f,
|
||||||
"DUP1" => 0x80,
|
"DUP1" => 0x80,
|
||||||
"DUP2" => 0x81,
|
"DUP2" => 0x81,
|
||||||
"DUP3" => 0x82,
|
"DUP3" => 0x82,
|
||||||
@ -108,13 +112,20 @@ pub(crate) fn get_opcode(mnemonic: &str) -> u8 {
|
|||||||
"LOG2" => 0xa2,
|
"LOG2" => 0xa2,
|
||||||
"LOG3" => 0xa3,
|
"LOG3" => 0xa3,
|
||||||
"LOG4" => 0xa4,
|
"LOG4" => 0xa4,
|
||||||
|
"PANIC" => 0xa5,
|
||||||
"CREATE" => 0xf0,
|
"CREATE" => 0xf0,
|
||||||
"CALL" => 0xf1,
|
"CALL" => 0xf1,
|
||||||
"CALLCODE" => 0xf2,
|
"CALLCODE" => 0xf2,
|
||||||
"RETURN" => 0xf3,
|
"RETURN" => 0xf3,
|
||||||
"DELEGATECALL" => 0xf4,
|
"DELEGATECALL" => 0xf4,
|
||||||
"CREATE2" => 0xf5,
|
"CREATE2" => 0xf5,
|
||||||
|
"GET_CONTEXT" => 0xf6,
|
||||||
|
"SET_CONTEXT" => 0xf7,
|
||||||
|
"CONSUME_GAS" => 0xf8,
|
||||||
|
"EXIT_KERNEL" => 0xf9,
|
||||||
"STATICCALL" => 0xfa,
|
"STATICCALL" => 0xfa,
|
||||||
|
"MLOAD_GENERAL" => 0xfb,
|
||||||
|
"MSTORE_GENERAL" => 0xfc,
|
||||||
"REVERT" => 0xfd,
|
"REVERT" => 0xfd,
|
||||||
"INVALID" => 0xfe,
|
"INVALID" => 0xfe,
|
||||||
"SELFDESTRUCT" => 0xff,
|
"SELFDESTRUCT" => 0xff,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user