Add transaction info to the `Block` struct
Closed this issue · 2 comments
To support 0xPolygonMiden/miden-node#371, we need to modify the Block struct. Specifically, we need to make sure that information about which transactions updated a specific account is contained within the block.
One way to do it is to add something like transactions
field to the BlockAccountUpdate struct. Specifically, this struct could look like so:
pub struct BlockAccountUpdate {
account_id: AccountId,
new_state_hash: Digest,
details: AccountUpdateDetails,
transactions: Vec<TransactionId>,
}
The reason for using Vec
to keep track of transactions is that an account could be updated multiple times within a block and we need to keep track of all relevant transactions.
Another approach is to refactor the Block
struct more radically so that it looks something like this:
pub struct Block {
header: BlockHeader,
batches: Vec<TransactionBatch>,
proof: ExecutionProof,
}
pub type TransactionBatch = Vec<VerifiedTransaction>;
pub struct VerifiedTransaction {
id: TransactionId,
account_update: TxAccountUpdate,
input_notes: InputNotes<Nullifier>,
output_notes: OutputNotes,
}
Here, VerifiedTransaction
is basically the same as the ProvenTransaction but without the proof
and block_ref
fields.
The benefit of this approach is that we retain all publicly available info about the transactions which went into the block. The downside is that the block becomes "heavier" because we keep info about "ephemeral" transactions. I am not yet sure which approach is better.
Effect on the BlockHeader
Regardless of the approach taken, we need to make sure that the BlockHeader structs contains a commitment to the transaction info. Specifically, given a block we need to make sure that a set of transactions mentioned in the block is consistent with the information in the block header.
For the first approach, this could be accomplished by changing batch_root
to tx_hash
which would be computed as a sequential hash of (transaction_id, account_id)
tuples:
tx_hash = hash(transaction_id_0, account_id_0, ..., transaction_id_n, account_id_n)
This way, we'd be able to confirm that:
- No extra transactions were added added to
BlockAccountUpdate
s and no transactions were omitted from them. - Transactions were mapped to the accounts correctly.
For the second approach, we'd also rename batch_root
into tx_hash
, but now we'd only need to hash transaction IDs:
tx_hash = hash(transaction_id_0, ..., transaction_id_n)
This is sufficient because the VerifiedTransaction
struct contains enough info to re-compute transaction_id
based on other account update info and note commitments.
One potentially tricky aspect here would be to derive the note tree from the set of verified transactions. But I think if we assume that the output notes are inserted into the note tree in the order in which they appear in the list of transactions, and account for notes which were both created and consumed in the same batch, it should be doable.
@hackaugusto @igamigo any thoughts on the two approaches?