Merge pull request #749 from mir-protocol/storage_misc

Finish some misc storage logic
This commit is contained in:
Daniel Lubarov 2022-10-02 12:00:21 -07:00 committed by GitHub
commit 1978c2adb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 162 additions and 76 deletions

View File

@ -43,6 +43,7 @@ pub(crate) fn combined_kernel() -> Kernel {
include_str!("asm/rlp/decode.asm"),
include_str!("asm/rlp/read_to_memory.asm"),
include_str!("asm/mpt/hash.asm"),
include_str!("asm/mpt/hash_trie_specific.asm"),
include_str!("asm/mpt/hex_prefix.asm"),
include_str!("asm/mpt/load.asm"),
include_str!("asm/mpt/read.asm"),

View File

@ -1,11 +1,15 @@
// Transfers some ETH from one address to another. The amount is given in wei.
// Pre stack: from, to, amount, retdest
// Post stack: (empty)
global transfer_eth:
// stack: from, to, amount, retdest
// TODO: Replace with actual implementation.
%pop3
%stack (from, to, amount, retdest)
-> (from, amount, to, amount)
%deduct_eth
// TODO: Handle exception from %deduct_eth?
// stack: to, amount, retdest
%add_eth
// stack: retdest
JUMP
// Convenience macro to call transfer_eth and return where we left off.
@ -26,3 +30,26 @@ global transfer_eth:
%transfer_eth
%%after:
%endmacro
global deduct_eth:
// stack: addr, amount, retdest
%jump(mpt_read_state_trie)
deduct_eth_after_read:
PANIC // TODO
// Convenience macro to call deduct_eth and return where we left off.
%macro deduct_eth
%stack (addr, amount) -> (addr, amount, %%after)
%jump(deduct_eth)
%%after:
%endmacro
global add_eth:
PANIC // TODO
// Convenience macro to call add_eth and return where we left off.
%macro add_eth
%stack (addr, amount) -> (addr, amount, %%after)
%jump(add_eth)
%%after:
%endmacro

View File

@ -4,7 +4,9 @@ global main:
%jump(load_all_mpts)
hash_initial_tries:
// TODO: Hash each trie and set @GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE, etc.
%mpt_hash_state_trie %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE)
%mpt_hash_txn_trie %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE)
%mpt_hash_receipt_trie %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE)
txn_loop:
// If the prover has no more txns for us to process, halt.
@ -16,5 +18,7 @@ txn_loop:
%jump(route_txn)
hash_final_tries:
// TODO: Hash each trie and set @GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER, etc.
%mpt_hash_state_trie %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER)
%mpt_hash_txn_trie %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER)
%mpt_hash_receipt_trie %mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER)
%jump(halt)

View File

@ -1,46 +1,3 @@
global mpt_hash_state_trie:
// stack: retdest
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
// stack: node_ptr, retdest
%mpt_hash(encode_account)
encode_account:
// stack: rlp_pos, value_ptr, retdest
// First, we compute the length of the RLP data we're about to write.
// The nonce and balance fields are variable-length, so we need to load them
// to determine their contribution, while the other two fields are fixed
// 32-bytes integers.
DUP2 %mload_trie_data // nonce = value[0]
%scalar_rlp_len
// stack: nonce_rlp_len, rlp_pos, value_ptr, retdest
DUP3 %add_const(1) %mload_trie_data // balance = value[1]
%scalar_rlp_len
// stack: balance_rlp_lenm, nonce_rlp_len, rlp_pos, value_ptr, retdest
PUSH 66 // storage_root and code_hash fields each take 1 + 32 bytes
ADD ADD
// stack: payload_len, rlp_pos, value_ptr, retdest
SWAP1
%encode_rlp_list_prefix
// stack: rlp_pos', value_ptr, retdest
DUP2 %mload_trie_data // nonce = value[0]
// stack: nonce, rlp_pos', value_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos'', value_ptr, retdest
DUP2 %add_const(1) %mload_trie_data // balance = value[1]
// stack: balance, rlp_pos'', value_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos''', value_ptr, retdest
DUP2 %add_const(2) %mload_trie_data // storage_root = value[2]
// stack: storage_root, rlp_pos''', value_ptr, retdest
SWAP1 %encode_rlp_256
// stack: rlp_pos'''', value_ptr, retdest
SWAP1 %add_const(3) %mload_trie_data // code_hash = value[3]
// stack: code_hash, rlp_pos'''', retdest
SWAP1 %encode_rlp_256
// stack: rlp_pos''''', retdest
SWAP1
JUMP
// Computes the Merkle root of the given trie node.
//
// The encode_value function should take as input
@ -111,11 +68,11 @@ encode_account:
JUMP
%endmacro
mpt_hash_empty:
global mpt_hash_empty:
%stack (node_type, node_payload_ptr, retdest) -> (retdest, @EMPTY_NODE_HASH)
JUMP
mpt_hash_hash:
global mpt_hash_hash:
// stack: node_type, node_payload_ptr, retdest
POP
// stack: node_payload_ptr, retdest

View File

@ -0,0 +1,80 @@
// Hashing logic specific to a particular trie.
global mpt_hash_state_trie:
// stack: retdest
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
// stack: node_ptr, retdest
%mpt_hash(encode_account)
%macro mpt_hash_state_trie
PUSH %%after
%jump(mpt_hash_state_trie)
%%after:
%endmacro
global mpt_hash_txn_trie:
// stack: retdest
%mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT)
// stack: node_ptr, retdest
%mpt_hash(encode_txn)
%macro mpt_hash_txn_trie
PUSH %%after
%jump(mpt_hash_txn_trie)
%%after:
%endmacro
global mpt_hash_receipt_trie:
// stack: retdest
%mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT)
// stack: node_ptr, retdest
%mpt_hash(encode_receipt)
%macro mpt_hash_receipt_trie
PUSH %%after
%jump(mpt_hash_receipt_trie)
%%after:
%endmacro
encode_account:
// stack: rlp_pos, value_ptr, retdest
// First, we compute the length of the RLP data we're about to write.
// The nonce and balance fields are variable-length, so we need to load them
// to determine their contribution, while the other two fields are fixed
// 32-bytes integers.
DUP2 %mload_trie_data // nonce = value[0]
%scalar_rlp_len
// stack: nonce_rlp_len, rlp_pos, value_ptr, retdest
DUP3 %add_const(1) %mload_trie_data // balance = value[1]
%scalar_rlp_len
// stack: balance_rlp_lenm, nonce_rlp_len, rlp_pos, value_ptr, retdest
PUSH 66 // storage_root and code_hash fields each take 1 + 32 bytes
ADD ADD
// stack: payload_len, rlp_pos, value_ptr, retdest
SWAP1
%encode_rlp_list_prefix
// stack: rlp_pos', value_ptr, retdest
DUP2 %mload_trie_data // nonce = value[0]
// stack: nonce, rlp_pos', value_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos'', value_ptr, retdest
DUP2 %add_const(1) %mload_trie_data // balance = value[1]
// stack: balance, rlp_pos'', value_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos''', value_ptr, retdest
DUP2 %add_const(2) %mload_trie_data // storage_root = value[2]
// stack: storage_root, rlp_pos''', value_ptr, retdest
SWAP1 %encode_rlp_256
// stack: rlp_pos'''', value_ptr, retdest
SWAP1 %add_const(3) %mload_trie_data // code_hash = value[3]
// stack: code_hash, rlp_pos'''', retdest
SWAP1 %encode_rlp_256
// stack: rlp_pos''''', retdest
SWAP1
JUMP
encode_txn:
PANIC // TODO
encode_receipt:
PANIC // TODO

View File

@ -1,3 +1,22 @@
// Given an address, return a pointer to the associated account data, which
// consists of four words (nonce, balance, storage_root, code_hash), in the
// state trie. Returns 0 if the address is not found.
global mpt_read_state_trie:
// stack: addr, retdest
// The key is the hash of the address. Since KECCAK_GENERAL takes input from
// memory, we will write addr bytes to SEGMENT_KERNEL_GENERAL[0..20] first.
%stack (addr) -> (0, @SEGMENT_KERNEL_GENERAL, 0, addr, 20, mpt_read_state_trie_after_mstore)
%jump(mstore_unpacking)
mpt_read_state_trie_after_mstore:
// stack: retdest
%stack () -> (0, @SEGMENT_KERNEL_GENERAL, 0, 20) // context, segment, offset, len
KECCAK_GENERAL
// stack: key, retdest
PUSH 64 // num_nibbles
%mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // node_ptr
// stack: node_ptr, num_nibbles, key, retdest
%jump(mpt_read)
// Read a value from a MPT.
//
// Arguments:
@ -6,7 +25,6 @@
// - the number of nibbles in the key (should start at 64)
//
// This function returns a pointer to the leaf, or 0 if the key is not found.
global mpt_read:
// stack: node_ptr, num_nibbles, key, retdest
DUP1

View File

@ -1,2 +1,3 @@
global mpt_write:
// stack: node_ptr, num_nibbles, key, retdest
// TODO

View File

@ -24,13 +24,13 @@ pub(crate) enum GlobalMetadata {
// The root digests of each Merkle trie before these transactions.
StateTrieRootDigestBefore = 8,
TransactionsTrieRootDigestBefore = 9,
ReceiptsTrieRootDigestBefore = 10,
TransactionTrieRootDigestBefore = 9,
ReceiptTrieRootDigestBefore = 10,
// The root digests of each Merkle trie after these transactions.
StateTrieRootDigestAfter = 11,
TransactionsTrieRootDigestAfter = 12,
ReceiptsTrieRootDigestAfter = 13,
TransactionTrieRootDigestAfter = 12,
ReceiptTrieRootDigestAfter = 13,
}
impl GlobalMetadata {
@ -47,11 +47,11 @@ impl GlobalMetadata {
Self::ReceiptTrieRoot,
Self::NumStorageTries,
Self::StateTrieRootDigestBefore,
Self::TransactionsTrieRootDigestBefore,
Self::ReceiptsTrieRootDigestBefore,
Self::TransactionTrieRootDigestBefore,
Self::ReceiptTrieRootDigestBefore,
Self::StateTrieRootDigestAfter,
Self::TransactionsTrieRootDigestAfter,
Self::ReceiptsTrieRootDigestAfter,
Self::TransactionTrieRootDigestAfter,
Self::ReceiptTrieRootDigestAfter,
]
}
@ -67,18 +67,18 @@ impl GlobalMetadata {
GlobalMetadata::ReceiptTrieRoot => "GLOBAL_METADATA_RECEIPT_TRIE_ROOT",
GlobalMetadata::NumStorageTries => "GLOBAL_METADATA_NUM_STORAGE_TRIES",
GlobalMetadata::StateTrieRootDigestBefore => "GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE",
GlobalMetadata::TransactionsTrieRootDigestBefore => {
"GLOBAL_METADATA_TXNS_TRIE_DIGEST_BEFORE"
GlobalMetadata::TransactionTrieRootDigestBefore => {
"GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE"
}
GlobalMetadata::ReceiptsTrieRootDigestBefore => {
"GLOBAL_METADATA_RECEIPTS_TRIE_DIGEST_BEFORE"
GlobalMetadata::ReceiptTrieRootDigestBefore => {
"GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE"
}
GlobalMetadata::StateTrieRootDigestAfter => "GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER",
GlobalMetadata::TransactionsTrieRootDigestAfter => {
"GLOBAL_METADATA_TXNS_TRIE_DIGEST_AFTER"
GlobalMetadata::TransactionTrieRootDigestAfter => {
"GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER"
}
GlobalMetadata::ReceiptsTrieRootDigestAfter => {
"GLOBAL_METADATA_RECEIPTS_TRIE_DIGEST_AFTER"
GlobalMetadata::ReceiptTrieRootDigestAfter => {
"GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER"
}
}
}

View File

@ -80,9 +80,9 @@ fn no_op_jumps(code: &mut Vec<Item>) {
replace_windows(code, |window| {
if let [Push(Label(l)), StandardOp(jump), decl] = window
&& &jump == "JUMP"
&& (decl == LocalLabelDeclaration(l.clone()) || decl == GlobalLabelDeclaration(l.clone()))
&& (decl == LocalLabelDeclaration(l.clone()) || decl == GlobalLabelDeclaration(l))
{
Some(vec![LocalLabelDeclaration(l)])
Some(vec![decl])
} else {
None
}

View File

@ -89,18 +89,16 @@ pub(crate) fn generate_traces<F: RichField + Extendable<D>, const D: usize>(
let trie_roots_before = TrieRoots {
state_root: H256::from_uint(&read_metadata(GlobalMetadata::StateTrieRootDigestBefore)),
transactions_root: H256::from_uint(&read_metadata(
GlobalMetadata::TransactionsTrieRootDigestBefore,
)),
receipts_root: H256::from_uint(&read_metadata(
GlobalMetadata::ReceiptsTrieRootDigestBefore,
GlobalMetadata::TransactionTrieRootDigestBefore,
)),
receipts_root: H256::from_uint(&read_metadata(GlobalMetadata::ReceiptTrieRootDigestBefore)),
};
let trie_roots_after = TrieRoots {
state_root: H256::from_uint(&read_metadata(GlobalMetadata::StateTrieRootDigestAfter)),
transactions_root: H256::from_uint(&read_metadata(
GlobalMetadata::TransactionsTrieRootDigestAfter,
GlobalMetadata::TransactionTrieRootDigestAfter,
)),
receipts_root: H256::from_uint(&read_metadata(GlobalMetadata::ReceiptsTrieRootDigestAfter)),
receipts_root: H256::from_uint(&read_metadata(GlobalMetadata::ReceiptTrieRootDigestAfter)),
};
let GenerationState {

View File

@ -17,7 +17,7 @@ type C = PoseidonGoldilocksConfig;
/// Execute the empty list of transactions, i.e. a no-op.
#[test]
#[ignore] // TODO: Won't work until storage, etc. are implemented.
#[ignore] // TODO: Won't work until witness generation logic is finished.
fn test_empty_txn_list() -> anyhow::Result<()> {
let all_stark = AllStark::<F, D>::default();
let config = StarkConfig::standard_fast_config();