mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 15:20:16 +00:00
feat(aquavm-air,air-interpreter-signature,air-interpreter-data)!: Peer signatures (#598)
A peer signs the multiset of call results and canon results it has produced. New field signatures, a map from peer public key to signature, is added to the interpreter data. Signatures verification is yet to be done.
This commit is contained in:
parent
5e7423bd06
commit
f8b734abde
552
Cargo.lock
generated
552
Cargo.lock
generated
@ -17,7 +17,7 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.8",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
@ -76,7 +76,7 @@ name = "air-interpreter-cid"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"cid",
|
||||
"multihash",
|
||||
"multihash 0.18.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@ -87,6 +87,7 @@ version = "0.7.0"
|
||||
dependencies = [
|
||||
"air-interpreter-cid",
|
||||
"air-interpreter-interface",
|
||||
"air-interpreter-signatures",
|
||||
"air-utils",
|
||||
"aquavm-air-parser",
|
||||
"newtype_derive",
|
||||
@ -109,6 +110,22 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "air-interpreter-signatures"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"air-interpreter-cid",
|
||||
"base64ct",
|
||||
"bs58",
|
||||
"ed25519-dalek",
|
||||
"fluence-keypair",
|
||||
"rand_chacha 0.2.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "air-lambda-ast"
|
||||
version = "0.1.0"
|
||||
@ -290,6 +307,7 @@ dependencies = [
|
||||
"air-interpreter-cid",
|
||||
"air-interpreter-data",
|
||||
"air-interpreter-interface",
|
||||
"air-interpreter-signatures",
|
||||
"air-lambda-ast",
|
||||
"air-lambda-parser",
|
||||
"air-log-targets",
|
||||
@ -304,6 +322,7 @@ dependencies = [
|
||||
"csv",
|
||||
"env_logger 0.7.1",
|
||||
"fluence-app-service",
|
||||
"fluence-keypair",
|
||||
"fstrings",
|
||||
"log",
|
||||
"maplit",
|
||||
@ -363,6 +382,12 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.2"
|
||||
@ -378,6 +403,31 @@ dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1_der"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638"
|
||||
dependencies = [
|
||||
"asn1_der_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1_der"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247"
|
||||
|
||||
[[package]]
|
||||
name = "asn1_der_derive"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.66"
|
||||
@ -463,6 +513,12 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bimap"
|
||||
version = "0.6.3"
|
||||
@ -499,6 +555,50 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake2s_simd"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
@ -514,6 +614,12 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9"
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
@ -532,6 +638,12 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "bytesize"
|
||||
version = "1.1.0"
|
||||
@ -577,7 +689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "103e94d97d73504c5fa6ffb47135d5627ce5ff84a4ad37e8219103ddc291de24"
|
||||
dependencies = [
|
||||
"ambient-authority",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -677,7 +789,7 @@ checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3"
|
||||
dependencies = [
|
||||
"core2",
|
||||
"multibase",
|
||||
"multihash",
|
||||
"multihash 0.18.1",
|
||||
"serde",
|
||||
"unsigned-varint",
|
||||
]
|
||||
@ -791,6 +903,12 @@ dependencies = [
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
@ -1063,6 +1181,16 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.2.0"
|
||||
@ -1094,6 +1222,19 @@ dependencies = [
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.91"
|
||||
@ -1211,13 +1352,22 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"block-buffer 0.10.3",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
@ -1272,6 +1422,31 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-dalek"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"ed25519",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"sha2 0.9.9",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.1"
|
||||
@ -1419,6 +1594,29 @@ dependencies = [
|
||||
"wast 8.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluence-keypair"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ed0ab3b8a69317a0452fdb52e35613a8ac5e4a638b21c774ed1ae9195662b"
|
||||
dependencies = [
|
||||
"asn1_der 0.6.3",
|
||||
"bs58",
|
||||
"ed25519-dalek",
|
||||
"eyre",
|
||||
"lazy_static",
|
||||
"libp2p-identity",
|
||||
"libsecp256k1",
|
||||
"multihash 0.18.1",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"sha2 0.10.6",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@ -1486,6 +1684,17 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
@ -1568,6 +1777,27 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
|
||||
dependencies = [
|
||||
"crypto-mac",
|
||||
"digest 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac-drbg"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
|
||||
dependencies = [
|
||||
"digest 0.9.0",
|
||||
"generic-array",
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "1.3.0"
|
||||
@ -1787,6 +2017,15 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940"
|
||||
dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.19.12"
|
||||
@ -1836,6 +2075,76 @@ version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "libp2p-identity"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a8ea433ae0cea7e3315354305237b9897afe45278b2118a7a57ca744e70fd27"
|
||||
dependencies = [
|
||||
"asn1_der 0.7.6",
|
||||
"bs58",
|
||||
"ed25519-dalek",
|
||||
"libsecp256k1",
|
||||
"log",
|
||||
"multiaddr",
|
||||
"multihash 0.17.0",
|
||||
"prost",
|
||||
"quick-protobuf",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"sha2 0.10.6",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsecp256k1"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"base64",
|
||||
"digest 0.9.0",
|
||||
"hmac-drbg",
|
||||
"libsecp256k1-core",
|
||||
"libsecp256k1-gen-ecmult",
|
||||
"libsecp256k1-gen-genmult",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"sha2 0.9.9",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsecp256k1-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
"digest 0.9.0",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsecp256k1-gen-ecmult"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809"
|
||||
dependencies = [
|
||||
"libsecp256k1-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsecp256k1-gen-genmult"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c"
|
||||
dependencies = [
|
||||
"libsecp256k1-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
@ -2186,6 +2495,25 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "multiaddr"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"byteorder",
|
||||
"data-encoding",
|
||||
"log",
|
||||
"multibase",
|
||||
"multihash 0.17.0",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"unsigned-varint",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multibase"
|
||||
version = "0.9.1"
|
||||
@ -2197,16 +2525,33 @@ dependencies = [
|
||||
"data-encoding-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multihash"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40"
|
||||
dependencies = [
|
||||
"core2",
|
||||
"digest 0.10.6",
|
||||
"multihash-derive",
|
||||
"sha2 0.10.6",
|
||||
"unsigned-varint",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multihash"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"blake2s_simd",
|
||||
"blake3",
|
||||
"core2",
|
||||
"digest",
|
||||
"digest 0.10.6",
|
||||
"multihash-derive",
|
||||
"sha2",
|
||||
"sha2 0.10.6",
|
||||
"sha3",
|
||||
"unsigned-varint",
|
||||
]
|
||||
|
||||
@ -2349,6 +2694,12 @@ version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
@ -2577,6 +2928,29 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psm"
|
||||
version = "0.1.21"
|
||||
@ -2592,6 +2966,15 @@ version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quick-protobuf"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
@ -2601,6 +2984,19 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -2608,8 +3004,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2619,7 +3025,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2628,7 +3043,16 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2668,7 +3092,7 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.8",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
@ -2717,6 +3141,21 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.21"
|
||||
@ -2857,9 +3296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.95"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -2894,6 +3333,19 @@ dependencies = [
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
@ -2902,7 +3354,17 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"digest 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
"keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2923,6 +3385,12 @@ dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "1.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.10"
|
||||
@ -2941,12 +3409,24 @@ version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.4"
|
||||
@ -2988,6 +3468,12 @@ dependencies = [
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
@ -3305,6 +3791,12 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
@ -3381,6 +3873,12 @@ dependencies = [
|
||||
"syn 1.0.107",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
@ -3600,7 +4098,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustix 0.36.8",
|
||||
"serde",
|
||||
"sha2",
|
||||
"sha2 0.10.6",
|
||||
"toml",
|
||||
"windows-sys 0.42.0",
|
||||
"zstd",
|
||||
@ -3709,7 +4207,7 @@ dependencies = [
|
||||
"memfd",
|
||||
"memoffset 0.6.5",
|
||||
"paste",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"rustix 0.36.8",
|
||||
"wasmtime-asm-macros",
|
||||
"wasmtime-environ",
|
||||
@ -4040,6 +4538,26 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
|
@ -9,6 +9,7 @@ members = [
|
||||
"crates/air-lib/interpreter-cid",
|
||||
"crates/air-lib/interpreter-data",
|
||||
"crates/air-lib/interpreter-interface",
|
||||
"crates/air-lib/interpreter-signatures",
|
||||
"crates/air-lib/lambda/ast",
|
||||
"crates/air-lib/lambda/parser",
|
||||
"crates/air-lib/log-targets",
|
||||
|
@ -20,6 +20,7 @@ aquavm-air-parser = { version = "0.7.4", path = "../crates/air-lib/air-parser" }
|
||||
air-execution-info-collector = { version = "0.7.4", path = "../crates/air-lib/execution-info-collector" }
|
||||
air-interpreter-cid = { version = "0.2.0", path = "../crates/air-lib/interpreter-cid" }
|
||||
air-interpreter-data = { version = "0.7.0", path = "../crates/air-lib/interpreter-data" }
|
||||
air-interpreter-signatures = { version = "0.1.0", path = "../crates/air-lib/interpreter-signatures" }
|
||||
air-interpreter-interface = { version = "0.13.0", path = "../crates/air-lib/interpreter-interface", default-features = false }
|
||||
air-log-targets = { version = "0.1.0", path = "../crates/air-lib/log-targets" }
|
||||
air-lambda-ast = { version = "0.1.0", path = "../crates/air-lib/lambda/ast" }
|
||||
@ -27,6 +28,7 @@ air-lambda-parser = { version = "0.1.0", path = "../crates/air-lib/lambda/parser
|
||||
air-trace-handler = { version = "0.2.0", path = "../crates/air-lib/trace-handler" }
|
||||
air-utils = { version = "0.1.0", path = "../crates/air-lib/utils" }
|
||||
polyplets = { version = "0.3.2", path = "../crates/air-lib/polyplets" }
|
||||
fluence-keypair = { version = "0.10.1" }
|
||||
|
||||
serde = { version = "1.0.159", features = [ "derive", "rc" ] }
|
||||
serde_json = "1.0.95"
|
||||
|
@ -21,10 +21,15 @@ use super::Scalars;
|
||||
use super::Streams;
|
||||
|
||||
use air_execution_info_collector::InstructionTracker;
|
||||
use air_interpreter_cid::CID;
|
||||
use air_interpreter_data::CanonResultCidAggregate;
|
||||
use air_interpreter_data::CidInfo;
|
||||
use air_interpreter_data::GlobalStreamGens;
|
||||
use air_interpreter_data::RestrictedStreamGens;
|
||||
use air_interpreter_data::ServiceResultCidAggregate;
|
||||
use air_interpreter_interface::*;
|
||||
use air_interpreter_signatures::SignatureStore;
|
||||
use air_interpreter_signatures::SignatureTracker;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -69,6 +74,17 @@ pub(crate) struct ExecutionCtx<'i> {
|
||||
|
||||
/// CID-to-something trackers.
|
||||
pub(crate) cid_state: ExecutionCidState,
|
||||
|
||||
/// Signatures' store.
|
||||
///
|
||||
/// It contains peers' signatures for verification.
|
||||
pub(crate) signature_store: SignatureStore,
|
||||
|
||||
/// Local signatures tracker.
|
||||
///
|
||||
/// It gathers peers' CIDs (call results and canon results) stored in the trace either for signing (current peer's
|
||||
/// CIDs) or sign verification (other peers).
|
||||
pub(crate) signature_tracker: SignatureTracker,
|
||||
}
|
||||
|
||||
impl<'i> ExecutionCtx<'i> {
|
||||
@ -87,6 +103,9 @@ impl<'i> ExecutionCtx<'i> {
|
||||
);
|
||||
|
||||
let cid_state = ExecutionCidState::from_cid_info(prev_ingredients.cid_info, current_ingredients.cid_info);
|
||||
// TODO we might keep both stores and merge them only with signature info collected into SignatureTracker
|
||||
let signature_store =
|
||||
SignatureStore::merge(prev_ingredients.signature_store, current_ingredients.signature_store);
|
||||
|
||||
Self {
|
||||
run_parameters,
|
||||
@ -95,6 +114,7 @@ impl<'i> ExecutionCtx<'i> {
|
||||
call_results,
|
||||
streams,
|
||||
cid_state,
|
||||
signature_store,
|
||||
..<_>::default()
|
||||
}
|
||||
}
|
||||
@ -107,6 +127,14 @@ impl<'i> ExecutionCtx<'i> {
|
||||
self.last_call_request_id += 1;
|
||||
self.last_call_request_id
|
||||
}
|
||||
|
||||
pub(crate) fn record_call_cid(&mut self, peer_id: impl Into<Box<str>>, cid: &CID<ServiceResultCidAggregate>) {
|
||||
self.signature_tracker.register(peer_id, cid);
|
||||
}
|
||||
|
||||
pub(crate) fn record_canon_cid(&mut self, peer_id: impl Into<Box<str>>, cid: &CID<CanonResultCidAggregate>) {
|
||||
self.signature_tracker.register(peer_id, cid);
|
||||
}
|
||||
}
|
||||
|
||||
impl ExecutionCtx<'_> {
|
||||
@ -134,6 +162,7 @@ pub(crate) struct ExecCtxIngredients {
|
||||
pub(crate) last_call_request_id: u32,
|
||||
pub(crate) restricted_streams: RestrictedStreamGens,
|
||||
pub(crate) cid_info: CidInfo,
|
||||
pub(crate) signature_store: SignatureStore,
|
||||
}
|
||||
|
||||
use serde::Deserialize;
|
||||
|
@ -38,6 +38,7 @@ pub(crate) fn populate_context_from_peer_service_result<'i>(
|
||||
) -> ExecutionResult<CallResult> {
|
||||
match output {
|
||||
CallOutputValue::Scalar(scalar) => {
|
||||
let peer_id: Box<str> = tetraplet.peer_pk.as_str().into();
|
||||
let service_result_agg_cid = exec_ctx
|
||||
.cid_state
|
||||
.insert_value(executed_result.result.clone(), tetraplet, argument_hash)
|
||||
@ -45,9 +46,11 @@ pub(crate) fn populate_context_from_peer_service_result<'i>(
|
||||
let executed_result = ValueAggregate::from_service_result(executed_result, service_result_agg_cid.clone());
|
||||
|
||||
exec_ctx.scalars.set_scalar_value(scalar.name, executed_result)?;
|
||||
exec_ctx.record_call_cid(peer_id, &service_result_agg_cid);
|
||||
Ok(CallResult::executed_scalar(service_result_agg_cid))
|
||||
}
|
||||
CallOutputValue::Stream(stream) => {
|
||||
let peer_id: Box<str> = tetraplet.peer_pk.as_str().into();
|
||||
let service_result_agg_cid = exec_ctx
|
||||
.cid_state
|
||||
.insert_value(executed_result.result.clone(), tetraplet, argument_hash)
|
||||
@ -63,6 +66,7 @@ pub(crate) fn populate_context_from_peer_service_result<'i>(
|
||||
stream.position,
|
||||
);
|
||||
let generation = exec_ctx.streams.add_stream_value(value_descriptor)?;
|
||||
exec_ctx.record_call_cid(&*peer_id, &service_result_agg_cid);
|
||||
Ok(CallResult::executed_stream(service_result_agg_cid, generation))
|
||||
}
|
||||
CallOutputValue::None => {
|
||||
|
@ -61,6 +61,7 @@ pub(super) fn handle_prev_state<'i>(
|
||||
serde_json::from_value((*err_value).clone()).map_err(UncatchableError::MalformedCallServiceFailed)?;
|
||||
|
||||
exec_ctx.make_subgraph_incomplete();
|
||||
exec_ctx.record_call_cid(&*tetraplet.peer_pk, failed_cid);
|
||||
trace_ctx.meet_call_end(met_result.result);
|
||||
|
||||
let err_msg = call_service_failed.message;
|
||||
@ -101,6 +102,8 @@ pub(super) fn handle_prev_state<'i>(
|
||||
}
|
||||
// this instruction's been already executed
|
||||
Executed(value) => {
|
||||
use air_interpreter_data::ValueRef;
|
||||
|
||||
let resulted_value = populate_context_from_data(
|
||||
value,
|
||||
tetraplet.clone(),
|
||||
@ -109,6 +112,14 @@ pub(super) fn handle_prev_state<'i>(
|
||||
output,
|
||||
exec_ctx,
|
||||
)?;
|
||||
|
||||
match &resulted_value {
|
||||
ValueRef::Scalar(ref cid) | ValueRef::Stream { ref cid, .. } => {
|
||||
exec_ctx.record_call_cid(&*tetraplet.peer_pk, cid);
|
||||
}
|
||||
ValueRef::Unused(_) => {}
|
||||
}
|
||||
|
||||
let call_result = CallResult::Executed(resulted_value);
|
||||
trace_ctx.meet_call_end(call_result);
|
||||
|
||||
@ -170,11 +181,13 @@ fn handle_service_error(
|
||||
|
||||
let failed_value = CallServiceFailed::new(service_result.ret_code, error_message).to_value();
|
||||
|
||||
let peer_id: Box<str> = tetraplet.peer_pk.as_str().into();
|
||||
let service_result_agg_cid = exec_ctx
|
||||
.cid_state
|
||||
.insert_value(failed_value.into(), tetraplet, argument_hash)
|
||||
.map_err(UncatchableError::from)?;
|
||||
|
||||
exec_ctx.record_call_cid(peer_id, &service_result_agg_cid);
|
||||
trace_ctx.meet_call_end(Failed(service_result_agg_cid));
|
||||
|
||||
Err(error.into())
|
||||
|
@ -59,6 +59,8 @@ fn handle_seen_canon(
|
||||
let tetraplet_cid = canon_result_agg.tetraplet.clone();
|
||||
let tetraplet = exec_ctx.cid_state.get_tetraplet_by_cid(&tetraplet_cid)?;
|
||||
|
||||
exec_ctx.record_canon_cid(&*tetraplet.peer_pk, &canon_result_cid);
|
||||
|
||||
let value_cids = canon_result_agg.values.clone();
|
||||
let values = value_cids
|
||||
.iter()
|
||||
@ -149,10 +151,11 @@ fn create_canon_stream_from_name(
|
||||
.record_value(canon_value_aggregate)?)
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
let tetraplet = canon_stream.tetraplet();
|
||||
let tetraplet_cid = exec_ctx
|
||||
.cid_state
|
||||
.tetraplet_tracker
|
||||
.record_value(canon_stream.tetraplet().clone())
|
||||
.record_value(tetraplet.clone())
|
||||
.map_err(UncatchableError::from)?;
|
||||
|
||||
let canon_result = CanonResultCidAggregate::new(tetraplet_cid, value_cids);
|
||||
@ -162,6 +165,8 @@ fn create_canon_stream_from_name(
|
||||
.record_value(canon_result)
|
||||
.map_err(UncatchableError::from)?;
|
||||
|
||||
exec_ctx.record_canon_cid(&*tetraplet.peer_pk, &canon_result_cid);
|
||||
|
||||
let result = StreamWithSerializedView {
|
||||
canon_stream,
|
||||
canon_result_cid,
|
||||
|
@ -25,6 +25,7 @@ use crate::INTERPRETER_SUCCESS;
|
||||
use air_interpreter_data::InterpreterData;
|
||||
use air_interpreter_interface::CallRequests;
|
||||
use air_utils::measure;
|
||||
use fluence_keypair::KeyPair;
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
@ -36,6 +37,7 @@ use std::rc::Rc;
|
||||
pub(crate) fn from_success_result(
|
||||
exec_ctx: ExecutionCtx<'_>,
|
||||
trace_handler: TraceHandler,
|
||||
keypair: &KeyPair,
|
||||
) -> Result<InterpreterOutcome, InterpreterOutcome> {
|
||||
let (ret_code, error_message) = if exec_ctx.call_results.is_empty() {
|
||||
(INTERPRETER_SUCCESS, String::new())
|
||||
@ -44,7 +46,7 @@ pub(crate) fn from_success_result(
|
||||
(farewell_error.to_error_code(), farewell_error.to_string())
|
||||
};
|
||||
|
||||
let outcome = populate_outcome_from_contexts(exec_ctx, trace_handler, ret_code, error_message);
|
||||
let outcome = populate_outcome_from_contexts(exec_ctx, trace_handler, ret_code, error_message, keypair);
|
||||
Ok(outcome)
|
||||
}
|
||||
|
||||
@ -64,21 +66,29 @@ pub(crate) fn from_uncatchable_error(
|
||||
|
||||
/// Create InterpreterOutcome from supplied execution context, trace handler, and error,
|
||||
/// set ret_code based on the error.
|
||||
#[tracing::instrument(skip(exec_ctx, trace_handler))]
|
||||
#[tracing::instrument(skip(exec_ctx, trace_handler, keypair))]
|
||||
pub(crate) fn from_execution_error(
|
||||
exec_ctx: ExecutionCtx<'_>,
|
||||
trace_handler: TraceHandler,
|
||||
error: impl ToErrorCode + ToString + Debug,
|
||||
keypair: &KeyPair,
|
||||
) -> InterpreterOutcome {
|
||||
populate_outcome_from_contexts(exec_ctx, trace_handler, error.to_error_code(), error.to_string())
|
||||
populate_outcome_from_contexts(
|
||||
exec_ctx,
|
||||
trace_handler,
|
||||
error.to_error_code(),
|
||||
error.to_string(),
|
||||
keypair,
|
||||
)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(exec_ctx, trace_handler), level = "info")]
|
||||
#[tracing::instrument(skip(exec_ctx, trace_handler, keypair), level = "info")]
|
||||
fn populate_outcome_from_contexts(
|
||||
exec_ctx: ExecutionCtx<'_>,
|
||||
mut exec_ctx: ExecutionCtx<'_>,
|
||||
mut trace_handler: TraceHandler,
|
||||
ret_code: i64,
|
||||
error_message: String,
|
||||
keypair: &KeyPair,
|
||||
) -> InterpreterOutcome {
|
||||
let maybe_gens = exec_ctx
|
||||
.streams
|
||||
@ -89,11 +99,19 @@ fn populate_outcome_from_contexts(
|
||||
Err(outcome) => return outcome,
|
||||
};
|
||||
|
||||
let current_signature = exec_ctx
|
||||
.signature_tracker
|
||||
.into_signature(&exec_ctx.run_parameters.current_peer_id, keypair)
|
||||
.expect("siging shouldn't fail");
|
||||
let current_pubkey = keypair.public();
|
||||
exec_ctx.signature_store.put(current_pubkey.into(), current_signature);
|
||||
|
||||
let data = InterpreterData::from_execution_result(
|
||||
trace_handler.into_result_trace(),
|
||||
global_streams,
|
||||
restricted_streams,
|
||||
exec_ctx.cid_state.into(),
|
||||
exec_ctx.signature_store,
|
||||
exec_ctx.last_call_request_id,
|
||||
semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("cargo version is valid"),
|
||||
);
|
||||
|
@ -53,6 +53,7 @@ pub(crate) fn prepare<'i>(
|
||||
last_call_request_id: prev_data.last_call_request_id,
|
||||
restricted_streams: prev_data.restricted_streams,
|
||||
cid_info: prev_data.cid_info,
|
||||
signature_store: prev_data.signatures,
|
||||
};
|
||||
|
||||
let current_ingredients = ExecCtxIngredients {
|
||||
@ -60,6 +61,7 @@ pub(crate) fn prepare<'i>(
|
||||
last_call_request_id: current_data.last_call_request_id,
|
||||
restricted_streams: current_data.restricted_streams,
|
||||
cid_info: current_data.cid_info,
|
||||
signature_store: current_data.signatures,
|
||||
};
|
||||
|
||||
let exec_ctx = make_exec_ctx(prev_ingredients, current_ingredients, call_results, run_parameters)?;
|
||||
|
@ -21,6 +21,7 @@ use crate::preparation_step::PreparationDescriptor;
|
||||
|
||||
use air_interpreter_interface::InterpreterOutcome;
|
||||
use air_interpreter_interface::RunParameters;
|
||||
use air_interpreter_signatures::derive_dummy_keypair;
|
||||
use air_log_targets::RUN_PARAMS;
|
||||
use air_utils::measure;
|
||||
|
||||
@ -55,6 +56,9 @@ fn execute_air_impl(
|
||||
params: RunParameters,
|
||||
call_results: Vec<u8>,
|
||||
) -> Result<InterpreterOutcome, InterpreterOutcome> {
|
||||
// TODO STUB this is a stub key that is to be replaced by external one in other PR
|
||||
let (keypair, _) = derive_dummy_keypair(¶ms.current_peer_id);
|
||||
|
||||
let PreparationDescriptor {
|
||||
mut exec_ctx,
|
||||
mut trace_handler,
|
||||
@ -72,11 +76,17 @@ fn execute_air_impl(
|
||||
tracing::Level::INFO,
|
||||
"execute",
|
||||
);
|
||||
match exec_result {
|
||||
Ok(_) => farewell::from_success_result(exec_ctx, trace_handler),
|
||||
// return new collected trace in case of errors
|
||||
Err(error) if error.is_catchable() => Err(farewell::from_execution_error(exec_ctx, trace_handler, error)),
|
||||
// return the prev data in case of any trace errors
|
||||
Err(error) => Err(farewell::from_uncatchable_error(prev_data, error)),
|
||||
}
|
||||
measure!(
|
||||
match exec_result {
|
||||
Ok(_) => farewell::from_success_result(exec_ctx, trace_handler, &keypair),
|
||||
// return new collected trace in case of errors
|
||||
Err(error) if error.is_catchable() => {
|
||||
Err(farewell::from_execution_error(exec_ctx, trace_handler, error, &keypair))
|
||||
}
|
||||
// return the prev data in case of any trace errors
|
||||
Err(error) => Err(farewell::from_uncatchable_error(prev_data, error)),
|
||||
},
|
||||
tracing::Level::INFO,
|
||||
"farewell",
|
||||
)
|
||||
}
|
||||
|
@ -21,5 +21,6 @@ mod join_behaviour;
|
||||
mod lambda;
|
||||
mod misc;
|
||||
mod scopes;
|
||||
mod signatures;
|
||||
mod streams;
|
||||
mod tetraplets;
|
||||
|
444
air/tests/test_module/features/signatures.rs
Normal file
444
air/tests/test_module/features/signatures.rs
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright 2023 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use air_interpreter_signatures::{derive_dummy_keypair, SignatureTracker};
|
||||
use air_test_framework::{ephemeral::PeerId, AirScriptExecutor};
|
||||
use air_test_utils::prelude::*;
|
||||
use air_test_utils::test_runner::TestRunParameters;
|
||||
|
||||
#[test]
|
||||
fn test_signature_empty() {
|
||||
let script = "(null)";
|
||||
let init_peer_id = "init_peer_id";
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let exec = AirScriptExecutor::new(
|
||||
TestRunParameters::from_init_peer_id(init_peer_id),
|
||||
vec![],
|
||||
vec![PeerId::from(init_peer_id)].into_iter(),
|
||||
script,
|
||||
)
|
||||
.unwrap();
|
||||
let res = exec.execute_one(init_peer_id).unwrap();
|
||||
assert_eq!(res.ret_code, 0, "{:?}", res);
|
||||
|
||||
let expected_signature: air_interpreter_signatures::Signature = keypair.sign(b"[]").unwrap().into();
|
||||
|
||||
let data = data_from_result(&res);
|
||||
let signature = data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_call_var() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(call "{init_peer_id}" ("" "") [] var) ; ok = "ok"
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let res = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
assert_eq!(res.ret_code, 0, "{:?}", res);
|
||||
let data = data_from_result(&res);
|
||||
|
||||
let expected_call_state = scalar!("ok", peer = init_peer_id, service = "..0");
|
||||
let expected_cid = extract_service_result_cid(&expected_call_state);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_call_stream() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(call "{init_peer_id}" ("" "") [] $var) ; ok = "ok"
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let res = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
assert_eq!(res.ret_code, 0, "{:?}", res);
|
||||
let data = data_from_result(&res);
|
||||
|
||||
let expected_call_state = stream!("ok", 0, peer = init_peer_id, service = "..0");
|
||||
let expected_cid = extract_service_result_cid(&expected_call_state);
|
||||
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_call_ununsed() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(call "{init_peer_id}" ("" "") []) ; ok = "ok"
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let res = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
assert_eq!(res.ret_code, 0, "{:?}", res);
|
||||
let data = data_from_result(&res);
|
||||
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_call_merged() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let other_peer_id = "other_peer_id";
|
||||
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{init_peer_id}" ("" "") [] x) ; ok = "res0"
|
||||
(seq
|
||||
(call "{other_peer_id}" ("" "") [] y) ; ok = "res1"
|
||||
(call "{init_peer_id}" ("" "") [] z) ; ok = "res2"
|
||||
))
|
||||
"#
|
||||
);
|
||||
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
let _ = exec.execute_one(init_peer_id).unwrap();
|
||||
let _ = exec.execute_one(other_peer_id).unwrap();
|
||||
let res2 = exec.execute_one(init_peer_id).unwrap();
|
||||
let data2 = data_from_result(&res2);
|
||||
|
||||
let expected_call_state0 = scalar!("res0", peer = init_peer_id, service = "..0");
|
||||
let expected_cid0 = extract_service_result_cid(&expected_call_state0);
|
||||
let expected_call_state2 = scalar!("res2", peer = init_peer_id, service = "..2");
|
||||
let expected_cid2 = extract_service_result_cid(&expected_call_state2);
|
||||
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_cid0);
|
||||
expected_tracker.register(init_peer_id, &expected_cid2);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = data2.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data2.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_call_double() {
|
||||
// Test that if some CID appears twice in the call result, it is accounted twice.
|
||||
let init_peer_id = "init_peer_id";
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq (ap 1 $s) (ap 2 $s))
|
||||
(fold $s i
|
||||
(seq
|
||||
(call "{init_peer_id}" ("" "") [] var) ; ok = "ok"
|
||||
(next i))))
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let res = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
assert_eq!(res.ret_code, 0, "{:?}", res);
|
||||
let data = data_from_result(&res);
|
||||
|
||||
let expected_call_state = scalar!("ok", peer = init_peer_id, service = "..0");
|
||||
let expected_cid = extract_service_result_cid(&expected_call_state);
|
||||
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let mut unexpected_tracker = SignatureTracker::new();
|
||||
unexpected_tracker.register(init_peer_id, &expected_cid);
|
||||
let unexpected_signature = unexpected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_cid);
|
||||
expected_tracker.register(init_peer_id, &expected_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
assert_ne!(expected_signature, unexpected_signature, "test is incorrect");
|
||||
|
||||
let signature = data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", data.signatures);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_canon_basic() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(call "{init_peer_id}" ("serv" "func") [] items) ; ok = [1, 2, 3]
|
||||
(seq
|
||||
(fold items i
|
||||
(seq
|
||||
(ap i $stream)
|
||||
(next i)))
|
||||
(canon "{init_peer_id}" $stream #canon)))
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let last_result = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
let last_data = data_from_result(&last_result);
|
||||
|
||||
let expected_call_result = scalar!(
|
||||
json!([1, 2, 3]),
|
||||
peer = init_peer_id,
|
||||
service = "serv..0",
|
||||
function = "func"
|
||||
);
|
||||
let expected_call_result_cid = extract_service_result_cid(&expected_call_result);
|
||||
|
||||
let expected_canon_state = canon(json!({
|
||||
"tetraplet": {"peer_pk": init_peer_id, "service_id": "", "function_name": "", "json_path": ""},
|
||||
"values": [{
|
||||
"result": 1,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[0]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}, {
|
||||
"result": 2,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[1]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}, {
|
||||
"result": 3,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[2]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}]
|
||||
}));
|
||||
let expected_canon_cid = extract_canon_result_cid(&expected_canon_state);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_canon_cid);
|
||||
expected_tracker.register(init_peer_id.to_owned(), &expected_call_result_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = last_data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", last_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_canon_merge() {
|
||||
let init_peer_id = "init_peer_id";
|
||||
let other_peer_id = "other_peer_id";
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{init_peer_id}" ("serv" "func") [] items) ; ok = [1, 2, 3]
|
||||
(seq
|
||||
(fold items i
|
||||
(seq
|
||||
(ap i $stream)
|
||||
(next i)))
|
||||
(canon "{init_peer_id}" $stream #canon)))
|
||||
(seq
|
||||
(call "{other_peer_id}" ("" "") []) ; ok = "ok"
|
||||
(call "{init_peer_id}" ("" "") []))) ; ok = "ok"
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
exec.execute_all(init_peer_id);
|
||||
exec.execute_one(other_peer_id);
|
||||
|
||||
let last_result = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
let last_data = data_from_result(&last_result);
|
||||
|
||||
let expected_call_result = scalar!(
|
||||
json!([1, 2, 3]),
|
||||
peer = init_peer_id,
|
||||
service = "serv..0",
|
||||
function = "func"
|
||||
);
|
||||
let expected_call_result_cid = extract_service_result_cid(&expected_call_result);
|
||||
|
||||
let expected_canon_state = canon(json!({
|
||||
"tetraplet": {"peer_pk": init_peer_id, "service_id": "", "function_name": "", "json_path": ""},
|
||||
"values": [{
|
||||
"result": 1,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[0]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}, {
|
||||
"result": 2,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[1]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}, {
|
||||
"result": 3,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[2]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid.clone()),
|
||||
}]
|
||||
}));
|
||||
let expected_canon_cid = extract_canon_result_cid(&expected_canon_state);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_canon_cid);
|
||||
expected_tracker.register(init_peer_id, &expected_call_result_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = last_data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", last_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signature_canon_result() {
|
||||
// this test checks that call result in canon doesn't lead to repeadted accounting of the call result
|
||||
let init_peer_id = "init_peer_id";
|
||||
let (keypair, _) = derive_dummy_keypair(init_peer_id);
|
||||
|
||||
let air_script = format!(
|
||||
r#"
|
||||
(seq
|
||||
(seq
|
||||
(call "{init_peer_id}" ("serv" "func") [] items) ; ok = [1, 2, 3]
|
||||
(fold items i
|
||||
(seq
|
||||
(ap i $stream)
|
||||
(next i))))
|
||||
(seq
|
||||
(call "{init_peer_id}" ("serv" "func2") [] $stream) ; ok = 42
|
||||
(canon "{init_peer_id}" $stream #canon)))
|
||||
"#
|
||||
);
|
||||
let exec = AirScriptExecutor::simple(TestRunParameters::from_init_peer_id(init_peer_id), &air_script).unwrap();
|
||||
|
||||
let last_result = exec.execution_iter(init_peer_id).unwrap().last().unwrap();
|
||||
let last_data = data_from_result(&last_result);
|
||||
|
||||
let expected_call_result1 = scalar!(
|
||||
json!([1, 2, 3]),
|
||||
peer = init_peer_id,
|
||||
service = "serv..0",
|
||||
function = "func"
|
||||
);
|
||||
let expected_call_result_cid1 = extract_service_result_cid(&expected_call_result1);
|
||||
|
||||
let expected_call_result2 = stream!(
|
||||
json!(42),
|
||||
1,
|
||||
peer = init_peer_id,
|
||||
service = "serv..1",
|
||||
function = "func2"
|
||||
);
|
||||
let expected_call_result_cid2 = extract_service_result_cid(&expected_call_result2);
|
||||
|
||||
let expected_canon_state = canon(json!({
|
||||
"tetraplet": {"peer_pk": init_peer_id, "service_id": "", "function_name": "", "json_path": ""},
|
||||
"values": [{
|
||||
"result": 1,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[0]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid1.clone()),
|
||||
}, {
|
||||
"result": 2,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[1]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid1.clone()),
|
||||
}, {
|
||||
"result": 3,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..0",
|
||||
"function_name": "func",
|
||||
"json_path": ".$.[2]",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid1.clone()),
|
||||
}, {
|
||||
"result": 42,
|
||||
"tetraplet": {
|
||||
"peer_pk": init_peer_id,
|
||||
"service_id": "serv..1",
|
||||
"function_name": "func2",
|
||||
"json_path": "",
|
||||
},
|
||||
"provenance": Provenance::service_result(expected_call_result_cid2.clone()),
|
||||
}]
|
||||
}));
|
||||
let expected_canon_cid = extract_canon_result_cid(&expected_canon_state);
|
||||
|
||||
let mut expected_tracker = SignatureTracker::new();
|
||||
expected_tracker.register(init_peer_id, &expected_call_result_cid1);
|
||||
expected_tracker.register(init_peer_id, &expected_call_result_cid2);
|
||||
expected_tracker.register(init_peer_id, &expected_canon_cid);
|
||||
let expected_signature = expected_tracker.into_signature(init_peer_id, &keypair).unwrap();
|
||||
|
||||
let signature = last_data.signatures.get(&keypair.public().into());
|
||||
assert_eq!(signature, Some(&expected_signature), "{:?}", last_data);
|
||||
}
|
@ -310,28 +310,20 @@ fn invalid_dst_generations() {
|
||||
(ap "a" $s)
|
||||
"#
|
||||
);
|
||||
// TODO generate data instead, as the code will be apdated on each data change
|
||||
let data = json!(
|
||||
{
|
||||
"version": "0.6.3",
|
||||
"interpreter_version": "1.1.1",
|
||||
"trace": [
|
||||
{"ap":
|
||||
{"gens": [42,42]}
|
||||
}
|
||||
],
|
||||
"streams": {},
|
||||
"r_streams": {},
|
||||
"lcid": 0,
|
||||
"cid_info": {
|
||||
"value_store": {},
|
||||
"tetraplet_store": {},
|
||||
"canon_element_store": {},
|
||||
"canon_result_store": {},
|
||||
"service_result_store": {}
|
||||
}
|
||||
});
|
||||
let data: Vec<u8> = serde_json::to_vec(&data).unwrap();
|
||||
|
||||
let empty_data = InterpreterData::from_execution_result(
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
semver::Version::new(1, 1, 1),
|
||||
);
|
||||
let mut data_value = serde_json::to_value(&empty_data).unwrap();
|
||||
data_value["trace"] = json!([{"ap": {"gens": [42, 42]}}]);
|
||||
|
||||
let data: Vec<u8> = serde_json::to_vec(&data_value).unwrap();
|
||||
// let result = peer_vm_1.call(script, "", data, <_>::default()).unwrap();
|
||||
let result = call_vm!(peer_vm_1, <_>::default(), &script, "", data);
|
||||
let expected_error = UncatchableError::TraceError {
|
||||
|
@ -32,7 +32,7 @@ use serde::Serialize;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct CID<T: ?Sized>(String, #[serde(skip)] PhantomData<*const T>);
|
||||
|
||||
@ -46,6 +46,11 @@ impl<T: ?Sized> CID<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Clone for CID<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone(), self.1)
|
||||
}
|
||||
}
|
||||
impl<T: ?Sized> fmt::Debug for CID<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("CID").field(&self.0).finish()
|
||||
|
@ -19,6 +19,7 @@ air-utils = { version = "0.1.0", path = "../utils" }
|
||||
aquavm-air-parser = { version = "0.7.4", path = "../air-parser" }
|
||||
air-interpreter-interface = { version = "0.13.0", path = "../interpreter-interface" }
|
||||
air-interpreter-cid = { version = "0.2.0", path = "../interpreter-cid" }
|
||||
air-interpreter-signatures = { version = "0.1.0", path = "../interpreter-signatures" }
|
||||
polyplets = { version = "0.3.2", path = "../polyplets" }
|
||||
|
||||
serde = {version = "1.0.159", features = ["derive", "rc"]}
|
||||
|
@ -62,6 +62,18 @@ impl CallResult {
|
||||
pub fn failed(service_result_agg_cid: Rc<CID<ServiceResultCidAggregate>>) -> CallResult {
|
||||
CallResult::Failed(service_result_agg_cid)
|
||||
}
|
||||
|
||||
pub fn get_cid(&self) -> Option<Rc<CID<ServiceResultCidAggregate>>> {
|
||||
match self {
|
||||
CallResult::RequestSentBy(_) => None,
|
||||
CallResult::Executed(executed) => match executed {
|
||||
ValueRef::Scalar(cid) => Some(cid.clone()),
|
||||
ValueRef::Stream { cid, .. } => Some(cid.clone()),
|
||||
ValueRef::Unused(_) => None,
|
||||
},
|
||||
CallResult::Failed(cid) => Some(cid.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SubTraceDesc {
|
||||
|
@ -23,6 +23,7 @@ use crate::ExecutionTrace;
|
||||
use crate::JValue;
|
||||
use crate::ServiceResultCidAggregate;
|
||||
|
||||
use air_interpreter_signatures::SignatureStore;
|
||||
use air_utils::measure;
|
||||
use polyplets::SecurityTetraplet;
|
||||
|
||||
@ -61,6 +62,12 @@ pub struct InterpreterData {
|
||||
|
||||
/// CID-to-somethings mappings.
|
||||
pub cid_info: CidInfo,
|
||||
|
||||
/// Signature store.
|
||||
///
|
||||
/// Every peer signs call results and canon values it produced (all together), and stores the signatures
|
||||
/// in this store.
|
||||
pub signatures: SignatureStore,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -84,6 +91,7 @@ impl InterpreterData {
|
||||
last_call_request_id: 0,
|
||||
restricted_streams: RestrictedStreamGens::new(),
|
||||
cid_info: <_>::default(),
|
||||
signatures: <_>::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +101,7 @@ impl InterpreterData {
|
||||
streams: GlobalStreamGens,
|
||||
restricted_streams: RestrictedStreamGens,
|
||||
cid_info: CidInfo,
|
||||
signatures: SignatureStore,
|
||||
last_call_request_id: u32,
|
||||
interpreter_version: semver::Version,
|
||||
) -> Self {
|
||||
@ -105,6 +114,7 @@ impl InterpreterData {
|
||||
last_call_request_id,
|
||||
restricted_streams,
|
||||
cid_info,
|
||||
signatures,
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,50 +159,3 @@ pub struct CidInfo {
|
||||
/// Map CID to a service result aggregate.
|
||||
pub service_result_store: CidStore<ServiceResultCidAggregate>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[test]
|
||||
fn compatible_with_0_6_0_version() {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct InterpreterData0_6_0 {
|
||||
pub trace: ExecutionTrace,
|
||||
#[serde(rename = "streams")] // for compatibility with versions <= 0.2.1
|
||||
pub global_streams: GlobalStreamGens,
|
||||
pub version: semver::Version,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "lcid")]
|
||||
pub last_call_request_id: u32,
|
||||
#[serde(default)]
|
||||
#[serde(rename = "r_streams")]
|
||||
pub restricted_streams: RestrictedStreamGens,
|
||||
pub interpreter_version: semver::Version,
|
||||
pub cid_info: CidInfo,
|
||||
}
|
||||
|
||||
// test 0.6.0 to 0.6.1 conversion
|
||||
let data_0_6_0 = InterpreterData0_6_0 {
|
||||
trace: ExecutionTrace::default(),
|
||||
global_streams: GlobalStreamGens::default(),
|
||||
version: semver::Version::new(0, 2, 0),
|
||||
last_call_request_id: 0,
|
||||
restricted_streams: RestrictedStreamGens::default(),
|
||||
interpreter_version: semver::Version::new(0, 1, 1),
|
||||
cid_info: CidInfo::default(),
|
||||
};
|
||||
|
||||
let data_0_6_0_se = serde_json::to_vec(&data_0_6_0).unwrap();
|
||||
let data_0_6_1 = serde_json::from_slice::<InterpreterData>(&data_0_6_0_se);
|
||||
assert!(data_0_6_1.is_ok());
|
||||
|
||||
// test 0.6.1 to 0.6.0 conversion
|
||||
let data_0_6_1 = InterpreterData::new(semver::Version::new(1, 1, 1));
|
||||
let data_0_6_1_se = serde_json::to_vec(&data_0_6_1).unwrap();
|
||||
let data_0_6_0 = serde_json::from_slice::<InterpreterData0_6_0>(&data_0_6_1_se);
|
||||
assert!(data_0_6_0.is_ok());
|
||||
}
|
||||
}
|
||||
|
26
crates/air-lib/interpreter-signatures/Cargo.toml
Normal file
26
crates/air-lib/interpreter-signatures/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "air-interpreter-signatures"
|
||||
description = "AIR interpreter signatures util module"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
documentation = "https://docs.rs/air-interpreter-signatures"
|
||||
repository = "https://github.com/fluencelabs/aquavm/tree/master/crates/air-lib/interpreter-signatures"
|
||||
keywords = ["fluence", "air", "programming-language"]
|
||||
categories = ["wasm"]
|
||||
|
||||
[dependencies]
|
||||
air-interpreter-cid = { version = "0.2.0", path = "../interpreter-cid" }
|
||||
fluence-keypair = "0.10.1"
|
||||
|
||||
base64ct = { version = "1.6.0", features = ["std"] }
|
||||
serde = { version = "1.0.159", features = ["derive"] }
|
||||
serde_json = "1.0.96"
|
||||
zeroize = { version = "1.6.0" }
|
||||
|
||||
# TODO to be moved to test-utils:
|
||||
ed25519-dalek = "1.0.1"
|
||||
rand_chacha = "0.2.2"
|
||||
sha2 = "0.10.6"
|
||||
bs58 = "0.4.0"
|
165
crates/air-lib/interpreter-signatures/src/lib.rs
Normal file
165
crates/air-lib/interpreter-signatures/src/lib.rs
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2023 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
|
||||
use air_interpreter_cid::CID;
|
||||
use fluence_keypair::error::SigningError;
|
||||
use fluence_keypair::KeyPair;
|
||||
use rand_chacha::rand_core::SeedableRng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
|
||||
/// An opaque serializable representation of public key.
|
||||
///
|
||||
/// It can be string or binary, you shouldn't care about it unless you change serialization format.
|
||||
// surrent implementation uses string as it is used as a key in a JSON map
|
||||
#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Deserialize, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct PublicKey(Box<str>);
|
||||
|
||||
impl From<fluence_keypair::PublicKey> for PublicKey {
|
||||
fn from(value: fluence_keypair::PublicKey) -> Self {
|
||||
Self(bs58::encode(&value.to_vec()).into_string().into())
|
||||
}
|
||||
}
|
||||
|
||||
/// An opaque serializable representation of signature key.
|
||||
///
|
||||
/// It can be string or binary, you shouldn't care about it unless you change serialization format.
|
||||
// surrent implementation uses string as more compact in JSON representation than number array
|
||||
#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Deserialize, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct Signature(Box<str>);
|
||||
|
||||
impl Signature {
|
||||
fn new(signature: fluence_keypair::Signature) -> Self {
|
||||
signature.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<fluence_keypair::Signature> for Signature {
|
||||
fn from(value: fluence_keypair::Signature) -> Self {
|
||||
Self(bs58::encode(value.to_vec()).into_string().into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct SignatureTracker {
|
||||
peer_to_cids: HashMap<Box<str>, Vec<Box<str>>>,
|
||||
}
|
||||
|
||||
impl SignatureTracker {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn register<T>(&mut self, peer_id: impl Into<Box<str>>, cid: &CID<T>) {
|
||||
self.peer_to_cids
|
||||
.entry(peer_id.into())
|
||||
.or_default()
|
||||
.push(cid.clone().into_inner().into());
|
||||
}
|
||||
|
||||
pub fn into_signature(
|
||||
&mut self,
|
||||
peer_id: &str,
|
||||
signer: &KeyPair,
|
||||
) -> Result<Signature, SigningError> {
|
||||
let mut cids = self.peer_to_cids.get(peer_id).cloned().unwrap_or_default();
|
||||
cids.sort_unstable();
|
||||
|
||||
// TODO make pluggable serialization
|
||||
// TODO it will be useful for CID too
|
||||
// TODO please note that using serde::Serializer is not enough
|
||||
let serialized_cids =
|
||||
serde_json::to_string(&cids).expect("default serialization shouldn't fail");
|
||||
|
||||
signer.sign(serialized_cids.as_bytes()).map(Signature::new)
|
||||
}
|
||||
}
|
||||
|
||||
/// A dictionary-like structure that stores peer public keys and their particle data signatures.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SignatureStore<Key: Hash + Eq = PublicKey, Sign = Signature>(HashMap<Key, Sign>);
|
||||
|
||||
impl<Key: Hash + Eq, Sign> SignatureStore<Key, Sign> {
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn get<Q>(&self, peer_pk: &Q) -> Option<&Sign>
|
||||
where
|
||||
Key: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.0.get(peer_pk)
|
||||
}
|
||||
|
||||
pub fn put(&mut self, peer_pk: Key, signature: Sign) {
|
||||
self.0.insert(peer_pk, signature);
|
||||
}
|
||||
|
||||
pub fn merge(prev: Self, _current: Self) -> Self {
|
||||
// TODO STUB
|
||||
prev
|
||||
}
|
||||
}
|
||||
|
||||
impl<Key: Hash + Eq, Sign> Default for SignatureStore<Key, Sign> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Derive fake keypair for testing proposes.
|
||||
///
|
||||
/// This function should be used in production, but it is yet.
|
||||
/// It returns a keypair determinisitically derived from seed, and a corresponding peer ID
|
||||
/// that might be useful in tests.
|
||||
// Should be moved to test lib when keypair interface PR is merged.
|
||||
pub fn derive_dummy_keypair(seed: &str) -> (KeyPair, String) {
|
||||
use sha2::{Digest as _, Sha256};
|
||||
|
||||
let mut rng = {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(seed);
|
||||
rand_chacha::ChaCha8Rng::from_seed(hasher.finalize().into())
|
||||
};
|
||||
|
||||
let keypair_ed25519 = ed25519_dalek::Keypair::generate(&mut rng);
|
||||
let keypair: KeyPair = KeyPair::Ed25519(keypair_ed25519.into());
|
||||
|
||||
let peer_id = keypair.public().to_peer_id().to_string();
|
||||
(keypair, peer_id)
|
||||
}
|
@ -100,6 +100,7 @@ pub fn raw_data_from_trace(
|
||||
<_>::default(),
|
||||
<_>::default(),
|
||||
cid_state.into(),
|
||||
<_>::default(),
|
||||
0,
|
||||
semver::Version::new(1, 1, 1),
|
||||
);
|
||||
@ -121,6 +122,7 @@ pub fn raw_data_from_trace_with_canon(
|
||||
canon_result_store: cid_state.canon_result_tracker.into(),
|
||||
service_result_store: cid_state.service_result_agg_tracker.into(),
|
||||
},
|
||||
<_>::default(),
|
||||
0,
|
||||
semver::Version::new(1, 1, 1),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user