-
Notifications
You must be signed in to change notification settings - Fork 2.6k
State Machine: Abstract function execution #19
Conversation
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.
Couple of style nitpicks and two questions:
- Arbitrary size storage
- Distinction between contract panic and backend error.
state_machine/Cargo.toml
Outdated
|
||
[dependencies] | ||
polkadot-primitives = { path = "../primitives", version = "0.1" } | ||
polkadot-primitives = { path = "../primitives" } |
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.
Why ditch 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.
merge issue
state_machine/src/backend.rs
Outdated
use primitives::Address; | ||
use primitives::hash::H256; | ||
|
||
use triehash::sec_trie_root; |
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.
Would keep it together with primitives
. We might try to organize imports into 3 blocks:
<std imports>
<external libraries>
<internal>
discussed it some time ago with @debris and he likes it as well.
state_machine/src/ext.rs
Outdated
impl<'a, B: 'a, E: 'a> Externalities<E> for Ext<'a, B, E> | ||
where B: Backend, E: Executor | ||
{ | ||
|
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.
Unnecessary line.
} | ||
|
||
impl<'a, B: 'a, E: 'a> StaticExternalities<E> for Ext<'a, B, E> | ||
where B: Backend, E: Executor |
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.
nitpick: I'd prefer
impl ... for Ext<..> where
B: Backend,
E: Executor,
{
extern crate hashdb; | ||
extern crate memorydb; | ||
extern crate keccak_hash; | ||
|
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.
Redundant line
fn set_storage(&mut self, key: H256, value: Vec<u8>); | ||
|
||
/// Make a sub-call to another contract. | ||
fn call(&mut self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error>; |
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.
Blank line after method missing.
type Error = Error; | ||
|
||
fn storage(&self, _key: &H256) -> Result<&[u8]> { |
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.
You sure we want to allow storage of data of arbitrary size?
call_data: &CallData, | ||
) -> Result<OutData, Box<Error>> { | ||
let code = match overlay.code(address) { | ||
Some(x) => x.to_owned(), |
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.
We could use bytes
here to avoid allocation and copying.
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.
Will log it as a separate issue.
address: &Address, | ||
method: &str, | ||
call_data: &CallData, | ||
) -> Result<OutData, Box<Error>> { |
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.
Shouldn't we be able to distinguish between a backend failure (user's machine fault) and actual execution error (contract panic)?
The first should most likely kill the entire process and the latter should just indicate transaction failure.
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.
yeah, so I guess what needs returning is this same ext::Error<B, E>
type.
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.
but the executor error may still be a backend error (having wrapped it internally): https://github.com/paritytech/polkadot/pull/19/files#diff-e5f6b2fc846df5e06dad05931f099408L43
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.
Let's merge it for now and figure out better error handling for that (we might need to add some bounds on Error type for both Executor and Externalities)
cli/Cargo.toml
Outdated
@@ -8,3 +8,4 @@ description = "Polkadot node implementation in Rust." | |||
clap = { version = "2.27", features = ["yaml"] } | |||
env_logger = "0.4" | |||
log = "0.3" | |||
polkadot-state-machine = { path = "../state_machine" } |
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.
Not needed?
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.
just to get it in the workspace :)
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.
You should put it to top-level Cargo.toml
Arbitrary size storage only seems to complicate things for the paritydb (which will store a flattened version of the balances contract storage trie). Since we're not at the stage of integrating paritydb we might want to consider our strategy for integration before imposing restrictions on the storage formats. |
cli/Cargo.toml
Outdated
@@ -8,3 +8,4 @@ description = "Polkadot node implementation in Rust." | |||
clap = { version = "2.27", features = ["yaml"] } | |||
env_logger = "0.4" | |||
log = "0.3" | |||
polkadot-state-machine = { path = "../state_machine" } |
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.
You should put it to top-level Cargo.toml
address: &Address, | ||
method: &str, | ||
call_data: &CallData, | ||
) -> Result<OutData, Box<Error>> { |
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.
Let's merge it for now and figure out better error handling for that (we might need to add some bounds on Error type for both Executor and Externalities)
call_data: &CallData, | ||
) -> Result<OutData, Box<Error>> { | ||
let code = match overlay.code(address) { | ||
Some(x) => x.to_owned(), |
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.
Will log it as a separate issue.
Sub-calls all share the same prospective state. An error in any sub-call reverts all changes.
An in-memory storage backend is provided. This could also be implemented for disk or network-backed data.
Committing to a backend yields two updated trie roots:
address => code_hash
.address => storage_root
, where storage_root is the root of a storage tree for that account.The motivation for separating these parts of the account record is that it will allow better light-client caching of contract code, although it also might become reasonable to combine them.
We might want an
execute_static
function at the root as well.