mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 23:31:07 +00:00
State Machine: Abstract function execution (#19)
* initial primitives * add block primitives * state machine: backend * in-memory backend * tests for overlayed storage * blanked impl for state machine error * abstract call execution * squash warnings temporarily * fix contracts crate * address grumbles * remove redundant state-machine dependency
This commit is contained in:
committed by
GitHub
parent
2fa0239dab
commit
3dfafb5ec3
Generated
+250
@@ -21,6 +21,15 @@ name = "ansi_term"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_matches"
|
||||
version = "1.1.0"
|
||||
@@ -60,6 +69,18 @@ dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bigint"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
@@ -124,6 +145,14 @@ name = "dtoa"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "elastic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.4.3"
|
||||
@@ -141,6 +170,40 @@ dependencies = [
|
||||
"backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-bigint"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-bytes"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ethcore-logger"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixed-hash"
|
||||
version = "0.1.0"
|
||||
@@ -167,11 +230,48 @@ dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashdb"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapsize"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "isatty"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "keccak-hash"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
@@ -204,11 +304,90 @@ dependencies = [
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memorydb"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "odds"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "patricia-trie"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plain_hasher"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkadot"
|
||||
version = "0.1.0"
|
||||
@@ -265,7 +444,12 @@ dependencies = [
|
||||
name = "polkadot-state-machine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"polkadot-primitives 0.1.0",
|
||||
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -321,6 +505,18 @@ name = "regex-syntax"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rlp"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.5"
|
||||
@@ -387,6 +583,16 @@ dependencies = [
|
||||
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.6.0"
|
||||
@@ -437,11 +643,32 @@ dependencies = [
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "triehash"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uint"
|
||||
version = "0.1.0"
|
||||
@@ -503,10 +730,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum arrayvec 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e003cbf6e0e1c43a0fc8df2ea8ea24174514d35cbcf60c35ca6112e0139f65e2"
|
||||
"checksum assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e772942dccdf11b368c31e044e4fca9189f80a773d2f0808379de65894cbf57"
|
||||
"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860"
|
||||
"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd"
|
||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
|
||||
@@ -517,18 +746,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
|
||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
||||
"checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85"
|
||||
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
|
||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||
"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
|
||||
"checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5"
|
||||
"checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b"
|
||||
"checksum fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
|
||||
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
|
||||
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
|
||||
"checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5"
|
||||
"checksum heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54fab2624374e5137ae4df13bf32b0b269cb804df42d13a51221bbd431d1a237"
|
||||
"checksum isatty 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "00c9301a947a2eaee7ce2556b80285dcc89558d07088962e6e8b9c25730f9dc6"
|
||||
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
|
||||
"checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5"
|
||||
"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
|
||||
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
|
||||
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
|
||||
"checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
|
||||
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
|
||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
||||
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
|
||||
"checksum parking_lot_core 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f610cb9664da38e417ea3225f23051f589851999535290e077939838ab7a595"
|
||||
"checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae"
|
||||
"checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995"
|
||||
"checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495"
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
|
||||
@@ -536,6 +781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
||||
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
|
||||
"checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9"
|
||||
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
|
||||
@@ -545,13 +791,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3bdafe3e71710131a919735916caa5b18c2754ad0d33d8ae5d586ccc804a403e"
|
||||
"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab"
|
||||
"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e"
|
||||
"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c"
|
||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520"
|
||||
"checksum tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52d12ad79e4063e0cb0ca5efa202ed7244b6ce4d25f4d3abe410b2a66128292"
|
||||
"checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7"
|
||||
"checksum uint 0.1.0 (git+https://github.com/paritytech/primitives.git)" = "<none>"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use primitives::Address;
|
||||
use state_machine::Externalities;
|
||||
use state_machine::StaticExternalities;
|
||||
|
||||
use error::Result;
|
||||
use executor::RustExecutor;
|
||||
@@ -32,7 +32,7 @@ impl Contract {
|
||||
/// Given Message and Authentication Data verifies it and returns:
|
||||
/// 1. None in case it doesn't match (i.e. signature is invalid)
|
||||
/// 2. A address who signed that Message.
|
||||
pub fn check_auth<E: Externalities<RustExecutor>>(&self, _ext: &E, _data: DataAndAuth) -> Result<Option<Address>> {
|
||||
pub fn check_auth<E: StaticExternalities<RustExecutor>>(&self, _ext: &E, _data: DataAndAuth) -> Result<Option<Address>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
use primitives::Address;
|
||||
use primitives::uint::U256;
|
||||
use state_machine::Externalities;
|
||||
use state_machine::{Externalities, StaticExternalities};
|
||||
|
||||
use error::Result;
|
||||
use executor::RustExecutor;
|
||||
@@ -38,12 +38,12 @@ pub struct Transfer {
|
||||
pub struct Contract;
|
||||
impl Contract {
|
||||
/// Returns a balance of given address.
|
||||
pub fn balance_of<E: Externalities<RustExecutor>>(&self, _ext: &E, _data: Address) -> Result<U256> {
|
||||
pub fn balance_of<E: StaticExternalities<RustExecutor>>(&self, _ext: &E, _data: Address) -> Result<U256> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Returns the next nonce to authorize the transfer from given address.
|
||||
pub fn next_nonce<E: Externalities<RustExecutor>>(&self, _ext: &E, _data: Address) -> Result<U256> {
|
||||
pub fn next_nonce<E: StaticExternalities<RustExecutor>>(&self, _ext: &E, _data: Address) -> Result<U256> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ impl Contract {
|
||||
/// - signature
|
||||
/// - replay protection
|
||||
/// - enough balance
|
||||
pub fn transfer_preconditions<E: Externalities<RustExecutor>>(&self, _db: &E, _data: Transfer) -> Result<bool> {
|
||||
pub fn transfer_preconditions<E: StaticExternalities<RustExecutor>>(&self, _db: &E, _data: Transfer) -> Result<bool> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
||||
@@ -46,5 +46,3 @@ error_chain! {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl state_machine::Error for Error {}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use primitives::contract::{CallData, OutData};
|
||||
use serializer::{from_slice as de, to_vec as ser};
|
||||
use state_machine::{Externalities, Executor};
|
||||
use state_machine::{StaticExternalities, Externalities, Executor};
|
||||
|
||||
use error::{Error, ErrorKind, Result};
|
||||
use auth;
|
||||
@@ -45,7 +45,7 @@ impl RustExecutor {
|
||||
impl Executor for RustExecutor {
|
||||
type Error = Error;
|
||||
|
||||
fn static_call<E: Externalities<Self>>(
|
||||
fn call_static<E: StaticExternalities<Self>>(
|
||||
&self,
|
||||
ext: &E,
|
||||
code: &[u8],
|
||||
@@ -95,11 +95,31 @@ impl Executor for RustExecutor {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use primitives::Address;
|
||||
use primitives::hash::H256;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct TestExternalities;
|
||||
impl Externalities<RustExecutor> for TestExternalities {
|
||||
fn set_storage(&mut self, _key: H256, _value: Vec<u8>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn call(&mut self, _address: &Address, _method: &str, _data: &CallData) -> Result<OutData> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticExternalities<RustExecutor> for TestExternalities {
|
||||
type Error = Error;
|
||||
|
||||
fn storage(&self, _key: &H256) -> Result<&[u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn call_static(&self, _address: &Address, _method: &str, _data: &CallData) -> Result<OutData> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use primitives::Address;
|
||||
use state_machine::Externalities;
|
||||
use state_machine::StaticExternalities;
|
||||
|
||||
use error::Result;
|
||||
use executor::RustExecutor;
|
||||
@@ -25,7 +25,7 @@ use executor::RustExecutor;
|
||||
pub struct Contract;
|
||||
impl Contract {
|
||||
/// Returns current validator set.
|
||||
pub fn validator_set<E: Externalities<RustExecutor>>(&self, _db: &E, _data: ()) -> Result<Vec<Address>> {
|
||||
pub fn validator_set<E: StaticExternalities<RustExecutor>>(&self, _db: &E, _data: ()) -> Result<Vec<Address>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
[package]
|
||||
name = "polkadot-state-machine"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Team <admin@parity.io>"]
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
description = "Polkadot State Machine"
|
||||
|
||||
[dependencies]
|
||||
polkadot-primitives = { path = "../primitives", version = "0.1" }
|
||||
polkadot-primitives = { path = "../primitives", version = "0.1.0" }
|
||||
hashdb = "0.1.1"
|
||||
keccak-hash = "0.1.0"
|
||||
patricia-trie = "0.1.0"
|
||||
memorydb = "0.1.1"
|
||||
triehash = "0.1"
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! State machine backends. These manage the code and storage of contracts.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use primitives::Address;
|
||||
use primitives::hash::H256;
|
||||
use triehash::sec_trie_root;
|
||||
|
||||
use super::{Update, MemoryState};
|
||||
|
||||
/// Output of a commit.
|
||||
pub struct Committed {
|
||||
/// Root of the code tree after changes committed.
|
||||
pub code_tree_root: H256,
|
||||
/// Root of the storage tree after changes committed.
|
||||
pub storage_tree_root: H256,
|
||||
}
|
||||
|
||||
/// A state backend is used to read state data and can have changes committed
|
||||
/// to it.
|
||||
pub trait Backend {
|
||||
/// An error type when fetching data is not possible.
|
||||
type Error: super::Error;
|
||||
|
||||
/// Get code associated with specific address.
|
||||
fn code(&self, address: &Address) -> Result<&[u8], Self::Error>;
|
||||
|
||||
/// Get keyed storage associated with specific address.
|
||||
fn storage(&self, address: &Address, key: &H256) -> Result<&[u8], Self::Error>;
|
||||
|
||||
/// Commit updates to the backend and get new state.
|
||||
fn commit<I>(&mut self, changes: I) -> Committed
|
||||
where I: IntoIterator<Item=Update>;
|
||||
}
|
||||
|
||||
/// Error impossible.
|
||||
// TODO: use `!` type when stabilized.
|
||||
#[derive(Debug)]
|
||||
pub enum Void {}
|
||||
|
||||
impl fmt::Display for Void {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {}
|
||||
}
|
||||
}
|
||||
|
||||
/// In-memory backend. Fully recomputes tries on each commit but useful for
|
||||
/// tests.
|
||||
#[derive(Default)]
|
||||
pub struct InMemory {
|
||||
inner: MemoryState, // keeps all the state in memory.
|
||||
}
|
||||
|
||||
impl Backend for InMemory {
|
||||
type Error = Void;
|
||||
|
||||
fn code(&self, address: &Address) -> Result<&[u8], Void> {
|
||||
Ok(self.inner.code(address).unwrap_or(&[]))
|
||||
}
|
||||
|
||||
fn storage(&self, address: &Address, key: &H256) -> Result<&[u8], Void> {
|
||||
Ok(self.inner.storage(address, key).unwrap_or(&[]))
|
||||
}
|
||||
|
||||
fn commit<I>(&mut self, changes: I) -> Committed
|
||||
where I: IntoIterator<Item=Update>
|
||||
{
|
||||
self.inner.update(changes);
|
||||
|
||||
// fully recalculate trie roots.
|
||||
|
||||
let storage_roots = self.inner.storage.iter().map(|(addr, storage)| {
|
||||
let flat_trie = storage.iter().map(|(k, v)| (k.to_vec(), v.clone())).collect();
|
||||
(addr.to_vec(), sec_trie_root(flat_trie).to_vec())
|
||||
}).collect();
|
||||
|
||||
let storage_tree_root = H256(sec_trie_root(storage_roots).0);
|
||||
|
||||
let code_tree_root = sec_trie_root(
|
||||
self.inner.code.iter().map(|(k, v)| (k.to_vec(), v.clone())).collect()
|
||||
);
|
||||
|
||||
let code_tree_root = H256(code_tree_root.0);
|
||||
|
||||
Committed {
|
||||
code_tree_root,
|
||||
storage_tree_root,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: DB-based backend
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Conrete externalities implementation.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use backend::Backend;
|
||||
use primitives::Address;
|
||||
use primitives::contract::{CallData, OutData};
|
||||
use primitives::hash::H256;
|
||||
use {Externalities, Executor, StaticExternalities, OverlayedChanges};
|
||||
|
||||
/// Errors that can occur when interacting with the externalities.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Error<B, E> {
|
||||
/// Failure to load state data from the backend.
|
||||
Backend(B),
|
||||
/// Failure to execute a function.
|
||||
Executor(E),
|
||||
}
|
||||
|
||||
impl<B: fmt::Display, E: fmt::Display> fmt::Display for Error<B, E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Backend(ref e) => write!(f, "Storage backend error: {}", e),
|
||||
Error::Executor(ref e) => write!(f, "Sub-call execution error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps a read-only backend, call executor, and current overlayed changes.
|
||||
pub struct Ext<'a, B: 'a, E: 'a> {
|
||||
/// The overlayed changes to write to.
|
||||
pub overlay: &'a mut OverlayedChanges,
|
||||
/// The storage backend to read from.
|
||||
pub backend: &'a B,
|
||||
/// Contract code executor.
|
||||
pub exec: &'a E,
|
||||
/// Contract address.
|
||||
pub local: Address,
|
||||
}
|
||||
|
||||
impl<'a, B: 'a, E: 'a> StaticExternalities<E> for Ext<'a, B, E>
|
||||
where B: Backend, E: Executor
|
||||
{
|
||||
type Error = Error<B::Error, E::Error>;
|
||||
|
||||
fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> {
|
||||
match self.overlay.storage(&self.local, key) {
|
||||
Some(x) => Ok(x),
|
||||
None => self.backend.storage(&self.local, key).map_err(Error::Backend)
|
||||
}
|
||||
}
|
||||
|
||||
fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error> {
|
||||
let inner_ext = StaticExt {
|
||||
backend: self.backend,
|
||||
exec: self.exec,
|
||||
local: address.clone(),
|
||||
overlay: self.overlay,
|
||||
};
|
||||
|
||||
let code = match self.overlay.code(address) {
|
||||
Some(x) => x,
|
||||
None => self.backend.code(address).map_err(Error::Backend)?,
|
||||
};
|
||||
|
||||
self.exec.call_static(
|
||||
&inner_ext,
|
||||
code,
|
||||
method,
|
||||
data,
|
||||
).map_err(Error::Executor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, B: 'a, E: 'a> Externalities<E> for Ext<'a, B, E>
|
||||
where B: Backend, E: Executor
|
||||
{
|
||||
fn set_storage(&mut self, key: H256, value: Vec<u8>) {
|
||||
self.overlay.set_storage(self.local, key, value);
|
||||
}
|
||||
|
||||
fn call(&mut self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error> {
|
||||
let code = {
|
||||
let code = match self.overlay.code(address) {
|
||||
Some(x) => x,
|
||||
None => self.backend.code(address).map_err(Error::Backend)?,
|
||||
};
|
||||
|
||||
code.to_owned()
|
||||
};
|
||||
|
||||
let mut inner_ext = Ext {
|
||||
backend: self.backend,
|
||||
exec: self.exec,
|
||||
local: address.clone(),
|
||||
overlay: &mut *self.overlay,
|
||||
};
|
||||
|
||||
self.exec.call(
|
||||
&mut inner_ext,
|
||||
&code[..],
|
||||
method,
|
||||
data,
|
||||
).map_err(Error::Executor)
|
||||
}
|
||||
}
|
||||
|
||||
// Static externalities
|
||||
struct StaticExt<'a, B: 'a, E: 'a> {
|
||||
overlay: &'a OverlayedChanges,
|
||||
backend: &'a B,
|
||||
exec: &'a E,
|
||||
local: Address,
|
||||
}
|
||||
|
||||
impl<'a, B: 'a, E: 'a> StaticExternalities<E> for StaticExt<'a, B, E>
|
||||
where B: Backend, E: Executor
|
||||
{
|
||||
type Error = Error<B::Error, E::Error>;
|
||||
|
||||
fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> {
|
||||
match self.overlay.storage(&self.local, key) {
|
||||
Some(x) => Ok(x),
|
||||
None => self.backend.storage(&self.local, key).map_err(Error::Backend)
|
||||
}
|
||||
}
|
||||
|
||||
fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error> {
|
||||
let inner_ext = StaticExt {
|
||||
backend: self.backend,
|
||||
exec: self.exec,
|
||||
local: address.clone(),
|
||||
overlay: self.overlay,
|
||||
};
|
||||
|
||||
let code = match self.overlay.code(address) {
|
||||
Some(x) => x,
|
||||
None => self.backend.code(address).map_err(Error::Backend)?,
|
||||
};
|
||||
|
||||
self.exec.call_static(
|
||||
&inner_ext,
|
||||
code,
|
||||
method,
|
||||
data,
|
||||
).map_err(Error::Executor)
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,182 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot state machine
|
||||
//! Polkadot state machine implementation.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
extern crate polkadot_primitives as primitives;
|
||||
|
||||
extern crate hashdb;
|
||||
extern crate memorydb;
|
||||
extern crate keccak_hash;
|
||||
|
||||
extern crate patricia_trie;
|
||||
extern crate triehash;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
use primitives::Address;
|
||||
use primitives::contract::{CallData, OutData};
|
||||
use primitives::hash::H256;
|
||||
|
||||
pub mod backend;
|
||||
mod ext;
|
||||
|
||||
/// Updates to be committed to the state.
|
||||
pub enum Update {
|
||||
/// Set storage of address at given key -- empty is deletion.
|
||||
Storage(Address, H256, Vec<u8>),
|
||||
/// Set code of address -- empty is deletion.
|
||||
Code(Address, Vec<u8>),
|
||||
}
|
||||
|
||||
// in-memory section of the state.
|
||||
#[derive(Default)]
|
||||
struct MemoryState {
|
||||
code: HashMap<Address, Vec<u8>>,
|
||||
storage: HashMap<Address, HashMap<H256, Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl MemoryState {
|
||||
fn code(&self, address: &Address) -> Option<&[u8]> {
|
||||
self.code.get(address).map(|v| &v[..])
|
||||
}
|
||||
|
||||
fn storage(&self, address: &Address, key: &H256) -> Option<&[u8]> {
|
||||
self.storage.get(address)
|
||||
.and_then(|m| m.get(key))
|
||||
.map(|v| &v[..])
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn set_code(&mut self, address: Address, code: Vec<u8>) {
|
||||
self.code.insert(address, code);
|
||||
}
|
||||
|
||||
fn set_storage(&mut self, address: Address, key: H256, val: Vec<u8>) {
|
||||
self.storage.entry(address)
|
||||
.or_insert_with(HashMap::new)
|
||||
.insert(key, val);
|
||||
}
|
||||
|
||||
fn update<I>(&mut self, changes: I) where I: IntoIterator<Item=Update> {
|
||||
for update in changes {
|
||||
match update {
|
||||
Update::Storage(addr, key, val) => {
|
||||
if val.is_empty() {
|
||||
let mut empty = false;
|
||||
if let Some(s) = self.storage.get_mut(&addr) {
|
||||
s.remove(&key);
|
||||
empty = s.is_empty();
|
||||
};
|
||||
|
||||
if empty { self.storage.remove(&addr); }
|
||||
} else {
|
||||
self.storage.entry(addr)
|
||||
.or_insert_with(HashMap::new)
|
||||
.insert(key, val);
|
||||
}
|
||||
}
|
||||
Update::Code(addr, code) => {
|
||||
if code.is_empty() {
|
||||
self.code.remove(&addr);
|
||||
} else {
|
||||
self.code.insert(addr, code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The overlayed changes to state to be queried on top of the backend.
|
||||
///
|
||||
/// A transaction shares all prospective changes within an inner overlay
|
||||
/// that can be cleared.
|
||||
#[derive(Default)]
|
||||
pub struct OverlayedChanges {
|
||||
prospective: MemoryState,
|
||||
committed: MemoryState,
|
||||
}
|
||||
|
||||
impl OverlayedChanges {
|
||||
fn code(&self, address: &Address) -> Option<&[u8]> {
|
||||
self.prospective.code(address)
|
||||
.or_else(|| self.committed.code(address))
|
||||
.and_then(|v| if v.is_empty() { None } else { Some(v) })
|
||||
}
|
||||
|
||||
fn storage(&self, address: &Address, key: &H256) -> Option<&[u8]> {
|
||||
self.prospective.storage(address, key)
|
||||
.or_else(|| self.committed.storage(address, key))
|
||||
.and_then(|v| if v.is_empty() { None } else { Some(v) })
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn set_code(&mut self, address: Address, code: Vec<u8>) {
|
||||
self.prospective.set_code(address, code);
|
||||
}
|
||||
|
||||
fn set_storage(&mut self, address: Address, key: H256, val: Vec<u8>) {
|
||||
self.prospective.set_storage(address, key, val);
|
||||
}
|
||||
|
||||
/// Discard prospective changes to state.
|
||||
pub fn discard_prospective(&mut self) {
|
||||
self.prospective.code.clear();
|
||||
self.prospective.storage.clear();
|
||||
}
|
||||
|
||||
/// Commit prospective changes to state.
|
||||
pub fn commit_prospective(&mut self) {
|
||||
let code_updates = self.prospective.code.drain()
|
||||
.map(|(addr, code)| Update::Code(addr, code));
|
||||
|
||||
let storage_updates = self.prospective.storage.drain()
|
||||
.flat_map(|(addr, storages)| storages.into_iter().map(move |(k, v)| (addr, k, v)))
|
||||
.map(|(addr, key, value)| Update::Storage(addr, key, value));
|
||||
|
||||
self.committed.update(code_updates.chain(storage_updates));
|
||||
}
|
||||
}
|
||||
|
||||
/// State Machine Error bound.
|
||||
///
|
||||
/// This should reflect WASM error type bound for future compatibility.
|
||||
pub trait Error: 'static + fmt::Debug + fmt::Display + Send {}
|
||||
impl<E> Error for E where E: 'static + fmt::Debug + fmt::Display + Send {}
|
||||
|
||||
/// Externalities
|
||||
pub trait Externalities<Executor> {
|
||||
/// Externalities: pinned to specific active address.
|
||||
pub trait Externalities<Executor>: StaticExternalities<Executor> {
|
||||
/// Read storage of current contract being called.
|
||||
fn storage(&self, key: &H256) -> Result<&[u8], Self::Error> {
|
||||
StaticExternalities::storage(self, key)
|
||||
}
|
||||
|
||||
/// Set storage of current contract being called.
|
||||
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>;
|
||||
|
||||
/// Make a static (read-only) call to another contract.
|
||||
fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error> {
|
||||
StaticExternalities::call_static(self, address, method, data)
|
||||
}
|
||||
}
|
||||
|
||||
/// Static externalities: used only for read-only requests.
|
||||
pub trait StaticExternalities<Executor> {
|
||||
/// Externalities error type.
|
||||
type Error: Error;
|
||||
|
||||
/// Read storage of current contract being called.
|
||||
fn storage(&self, key: &H256) -> Result<&[u8], Self::Error>;
|
||||
|
||||
/// Make a static (read-only) call to another contract.
|
||||
fn call_static(&self, address: &Address, method: &str, data: &CallData) -> Result<OutData, Self::Error>;
|
||||
}
|
||||
|
||||
/// Contract code executor.
|
||||
@@ -42,7 +199,7 @@ pub trait Executor: Sized {
|
||||
|
||||
/// Execute a contract in read-only mode.
|
||||
/// The execution is not allowed to modify the state.
|
||||
fn static_call<E: Externalities<Self>>(
|
||||
fn call_static<E: StaticExternalities<Self>>(
|
||||
&self,
|
||||
ext: &E,
|
||||
code: &[u8],
|
||||
@@ -59,3 +216,106 @@ pub trait Executor: Sized {
|
||||
data: &CallData,
|
||||
) -> Result<OutData, Self::Error>;
|
||||
}
|
||||
|
||||
/// Execute a call using the given state backend, overlayed changes, and call executor.
|
||||
///
|
||||
/// On an error, no prospective changes are written to the overlay.
|
||||
pub fn execute<B: backend::Backend, Exec: Executor>(
|
||||
backend: &B,
|
||||
overlay: &mut OverlayedChanges,
|
||||
exec: &Exec,
|
||||
address: &Address,
|
||||
method: &str,
|
||||
call_data: &CallData,
|
||||
) -> Result<OutData, Box<Error>> {
|
||||
let code = match overlay.code(address) {
|
||||
Some(x) => x.to_owned(),
|
||||
None => backend.code(address).map_err(|e| Box::new(e) as _)?.to_owned(),
|
||||
};
|
||||
|
||||
let result = {
|
||||
let mut externalities = ext::Ext {
|
||||
backend,
|
||||
exec,
|
||||
overlay: &mut *overlay,
|
||||
local: *address,
|
||||
};
|
||||
|
||||
exec.call(
|
||||
&mut externalities,
|
||||
&code[..],
|
||||
method,
|
||||
call_data,
|
||||
)
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(out) => {
|
||||
overlay.commit_prospective();
|
||||
Ok(out)
|
||||
}
|
||||
Err(e) => {
|
||||
overlay.discard_prospective();
|
||||
Err(Box::new(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::OverlayedChanges;
|
||||
|
||||
use primitives::hash::H256;
|
||||
use primitives::Address;
|
||||
|
||||
#[test]
|
||||
fn overlayed_storage_works() {
|
||||
let mut overlayed = OverlayedChanges::default();
|
||||
|
||||
let key = H256::random();
|
||||
let addr = Address::random();
|
||||
|
||||
assert!(overlayed.storage(&addr, &key).is_none());
|
||||
|
||||
overlayed.set_storage(addr, key, vec![1, 2, 3]);
|
||||
assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.commit_prospective();
|
||||
assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.set_storage(addr, key, vec![]);
|
||||
assert!(overlayed.storage(&addr, &key).is_none());
|
||||
|
||||
overlayed.discard_prospective();
|
||||
assert_eq!(overlayed.storage(&addr, &key).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.set_storage(addr, key, vec![]);
|
||||
overlayed.commit_prospective();
|
||||
assert!(overlayed.storage(&addr, &key).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlayed_code_works() {
|
||||
let mut overlayed = OverlayedChanges::default();
|
||||
|
||||
let addr = Address::random();
|
||||
|
||||
assert!(overlayed.code(&addr).is_none());
|
||||
|
||||
overlayed.set_code(addr, vec![1, 2, 3]);
|
||||
assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.commit_prospective();
|
||||
assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.set_code(addr, vec![]);
|
||||
assert!(overlayed.code(&addr).is_none());
|
||||
|
||||
overlayed.discard_prospective();
|
||||
assert_eq!(overlayed.code(&addr).unwrap(), &[1, 2, 3]);
|
||||
|
||||
overlayed.set_code(addr, vec![]);
|
||||
overlayed.commit_prospective();
|
||||
assert!(overlayed.code(&addr).is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user