-
Notifications
You must be signed in to change notification settings - Fork 1.7k
EIP-1702: Generalized Account Versioning Scheme #10771
Conversation
Can you elaborate on this for my education? |
@dvdplm This is fixed in 4e448f1. Let me know if you still need more info. And for spec-related questions, maybe consider putting it under sorpaas/EIPs#2! |
@@ -84,10 +85,14 @@ pub fn to_fat_rlps( | |||
let mut leftover: Option<Vec<u8>> = None; | |||
loop { | |||
account_stream.append(account_hash); | |||
account_stream.begin_list(5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to make one general begin_unbounded_list for all added rlp parameters? It looks weird, when it's first limited 5-6 elements list and unlimited after it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to maintain backward compatibility here. If we change the snapshotting format when use_short_version
is true
, then old clients will break. Or do you have better ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only idea, that I've got, that doesn't break compatibility and doesn't increment the whole packet's length, is to pass the list instead of one of the parameters (for example, push (nonce, code_version) instead of nonce). And to define during decoding, is it list on this place in the packet or not. It will allow to get rid off the most of boolean flags in these two methods but it will be still "hacky" (not obvious). I mean something like this:
Encoding:
....
account_stream.begin_list(5);
account_stream.begin_list(2);
account_stream.append(&acc.nonce);
account_stream.append(&acc.code_version);
account_stream.append(&acc.balance);
...
Decoding:
let account_descr = rlp.val_at(0)?;
let mut nonce = 0;
let mut code_version = U256::zero();
if account_descr.is_list() {
nonce = account_descr.val_at(0)?;
code_version = account_descr.val_at(1)?;
} else {
nonce = account_descr.as_val()?;
}
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't see what's the advantage of this over just checking the RLP list length. That should be reliable and we're already using it in places like transaction decoding: https://github.com/paritytech/parity-ethereum/blob/825c7990f29514d699e22c6e78f73710e53e983d/ethcore/types/src/transaction/transaction.rs#L121-L134
if !use_short_version { | ||
account_stream.append(&acc.code_version); | ||
} | ||
|
||
account_stream.begin_unbounded_list(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unbounded list starts here
@@ -170,6 +179,12 @@ pub fn from_fat_rlp( | |||
return Ok((ACC_EMPTY, None)); | |||
} | |||
|
|||
let use_short_version = match rlp.item_count()? { | |||
5 => true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, that it's a risky logic, to rely on item count in rlp packet. May be to pass this parameter explicitly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get what you mean here. Which parameter do you think we can pass explicitly?
fn rlp_append(&self, stream: &mut rlp::RlpStream) { | ||
let use_short_version = self.code_version == U256::zero(); | ||
|
||
match use_short_version { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also use begin_unbounded_list here.
|
||
impl rlp::Decodable for BasicAccount { | ||
fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> { | ||
let use_short_version = match rlp.item_count()? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same comment about fragile logic based on item count
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using rlp.item_count()
is the only method to know whether we're at version 0
or above version 0
. I don't agree it's fragile -- BasicAccount
is guaranteed to be either have 4 items (version 0
case) or 5 items (version non-0
case). And we handle all errors explicitly.
Err(err) => Err(err), | ||
} | ||
}, | ||
None => Ok(Err(vm::Error::OutOfGas)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is the correct error, is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the correct error -- None
means the validation phrase fails. In that case, according to the spec we should return out of gas.
Co-Authored-By: Andronik Ordian <write@reusable.software>
Co-Authored-By: Andronik Ordian <write@reusable.software>
@@ -246,6 +268,7 @@ mod tests { | |||
balance: 123456789.into(), | |||
storage_root: KECCAK_NULL_RLP, | |||
code_hash: KECCAK_EMPTY, | |||
code_version: 0.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add one more test for encoding accounts with not zero code-version?
I have added a frontend config For testing, it's still not yet done and I think we may want to have a separate PR to do it comprehensively. (And collaborate with aleth, if possible.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
* master: EIP-1702: Generalized Account Versioning Scheme (#10771)
…-state-db * dp/chore/extricate-state-backend: Sort out the merge EIP-1702: Generalized Account Versioning Scheme (#10771)
…cation * dp/chore/extract-state-db: Sort out the merge EIP-1702: Generalized Account Versioning Scheme (#10771)
rel #10770
This is a draft implementation of EIP-1702.
vm::Schedule::versions
, where we supportsPWasm
(which uses the pWasm execution engine) only (because it's the only useful target right now).EVM
real usage, we'll define feature flags inVersionedSchedule
(for example,VersionedSchedule::EVM::eip1283
) that states a particular feature should be enabled in the current version.wasm_version
together withwasm_activation_transition
, so that pWasm is activated using an account version, instead of code prefix.