diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4d72be20..611bb6c6 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,7 +1,6 @@ name: check on: pull_request: - branches: [main] push: branches: [main] @@ -51,6 +50,18 @@ jobs: with: path: coverage-result/cobertura.xml minimum_coverage: 60 + + - name: kairos-contracts x86_64-linux + if: matrix.os == 'ubuntu-latest' + run: nix build -L --no-link --show-trace .#packages.x86_64-linux.kairos-contracts + + - name: kairos-contracts x86_64-darwin + if: matrix.os == 'macos-latest' + run: nix build -L --no-link --show-trace .#packages.x86_64-darwin.kairos-contracts + + - name: kairos-contracts aarch64-darwin + if: matrix.os == 'macos-14' + run: nix build -L --no-link --show-trace .#packages.aarch64-darwin.kairos-contracts - name: kairos x86_64-linux if: matrix.os == 'ubuntu-latest' diff --git a/.gitignore b/.gitignore index 37358052..e4383a5f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ result target .tmp .nixos-test-history +.env diff --git a/Cargo.lock b/Cargo.lock index 541b1d95..603615f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,9 +107,9 @@ version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -215,9 +215,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" dependencies = [ "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -314,6 +314,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -441,7 +450,7 @@ dependencies = [ "async-trait", "base16", "base64 0.13.1", - "casper-hashing", + "casper-hashing 2.0.0", "casper-types 3.0.0", "clap", "clap_complete", @@ -507,6 +516,83 @@ dependencies = [ "vergen", ] +[[package]] +name = "casper-contract" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42901eb5b09bb79e7d7403642e70983ccac0f4812edf1de77d978abea5f3299" +dependencies = [ + "casper-types 4.0.1", + "hex_fmt", +] + +[[package]] +name = "casper-engine-test-support" +version = "7.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7967f1032f17243fbc9df3e4a8591dba169676adb3262b53dab4bb98f37d3c01" +dependencies = [ + "casper-execution-engine", + "casper-hashing 3.0.0", + "casper-types 4.0.1", + "filesize", + "humantime", + "lmdb-rkv", + "log", + "num-rational", + "num-traits", + "once_cell", + "rand 0.8.5", + "serde", + "tempfile", + "toml", +] + +[[package]] +name = "casper-execution-engine" +version = "7.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e4b48df024b3424cc994c60403472f66ca0961bffb25800f66318bb66c80611" +dependencies = [ + "anyhow", + "base16", + "bincode", + "casper-hashing 3.0.0", + "casper-types 4.0.1", + "casper-wasm", + "casper-wasm-utils", + "casper-wasmi", + "datasize", + "either", + "hex-buffer-serde 0.2.2", + "hex_fmt", + "hostname", + "humantime", + "itertools", + "libc", + "linked-hash-map", + "lmdb-rkv", + "log", + "num", + "num-derive", + "num-rational", + "num-traits", + "num_cpus", + "once_cell", + "proptest", + "rand 0.8.5", + "rand_chacha 0.3.1", + "schemars", + "serde", + "serde_bytes", + "serde_json", + "strum", + "thiserror", + "tracing", + "uint", + "uuid 0.8.2", +] + [[package]] name = "casper-hashing" version = "2.0.0" @@ -527,6 +613,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "casper-hashing" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c29b63e179d67da0c6b32c1b84bad5480f5f4bfd1b2d7f88390c85f92e87ae0" +dependencies = [ + "base16", + "blake2", + "casper-types 4.0.1", + "datasize", + "hex", + "hex-buffer-serde 0.3.0", + "hex_fmt", + "itertools", + "once_cell", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "casper-types" version = "3.0.0" @@ -571,6 +677,7 @@ dependencies = [ "base64 0.13.1", "bitflags 1.3.2", "blake2", + "datasize", "derp", "ed25519-dalek 2.1.1", "getrandom", @@ -585,15 +692,70 @@ dependencies = [ "num-traits", "once_cell", "pem 0.8.3", + "proptest", + "proptest-derive", "rand 0.8.5", + "rand_pcg", + "schemars", "serde", "serde_bytes", "serde_json", + "strum", "thiserror", "uint", "untrusted 0.7.1", ] +[[package]] +name = "casper-wasm" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f53c4e789fbff66ead0ea44030b1af2fc3c465201973483528e479a9155f98" + +[[package]] +name = "casper-wasm-utils" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d9f1a2269d52961812862f67d209ef29742d06b47634e2982a96e80d0fe2b4" +dependencies = [ + "byteorder", + "casper-wasm", + "log", +] + +[[package]] +name = "casper-wasmi" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8357f19a7fd98073d8fe8df60f1bef1e677b7c623c1e6e2e07d2f8e59ceb87fc" +dependencies = [ + "casper-wasm", + "casper-wasmi-core", + "casper-wasmi-validation", +] + +[[package]] +name = "casper-wasmi-core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60089625560924f184cf91d59b0731373d5114b81224f1201c6a39ccc1d8388c" +dependencies = [ + "downcast-rs", + "libm", + "memory_units", + "num-rational", + "num-traits", +] + +[[package]] +name = "casper-wasmi-validation" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f669d385132ce321a57fdf453588d69c01654e75991bee3d22392a3aaaad80bb" +dependencies = [ + "casper-wasm", +] + [[package]] name = "cc" version = "1.0.90" @@ -658,9 +820,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -837,9 +999,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -857,11 +1019,24 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613e4ee15899913285b7612004bbd490abd605be7b11d35afada5902fb6b91d5" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] +[[package]] +name = "demo-contract-tests" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "casper-contract", + "casper-engine-test-support", + "casper-execution-engine", + "casper-types 4.0.1", + "dotenvy", + "lazy_static", +] + [[package]] name = "der" version = "0.1.0" @@ -944,6 +1119,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "dyn-clone" version = "1.0.17" @@ -1086,9 +1267,9 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -1140,6 +1321,15 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" +[[package]] +name = "filesize" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12d741e2415d4e2e5bd1c1d00409d1a8865a57892c2d689b504365655d237d43" +dependencies = [ + "winapi", +] + [[package]] name = "float-cmp" version = "0.9.0" @@ -1268,8 +1458,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" dependencies = [ "proc-macro-error", - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -1415,6 +1605,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-buffer-serde" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310e9578ff64e65a3a18e0624609f6833ee4a20503ef38eebb48430cf8ac3ab8" +dependencies = [ + "hex", + "serde", +] + [[package]] name = "hex-buffer-serde" version = "0.3.0" @@ -1460,6 +1660,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "http" version = "0.2.12" @@ -1884,12 +2095,41 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +[[package]] +name = "lmdb-rkv" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447a296f7aca299cfbb50f4e4f3d49451549af655fb7215d7f8c0c3d64bad42b" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "libc", + "lmdb-rkv-sys", +] + +[[package]] +name = "lmdb-rkv-sys" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61b9ce6b3be08acefa3003c57b7565377432a89ec24476bbe72e11d101f852fe" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "lock_api" version = "0.4.11" @@ -1905,6 +2145,16 @@ name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "serde", + "value-bag", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "matchers" @@ -1927,6 +2177,12 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "mime" version = "0.3.17" @@ -2059,8 +2315,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -2094,6 +2350,7 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", + "serde", ] [[package]] @@ -2158,9 +2415,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -2251,9 +2508,9 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -2358,8 +2615,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", "version_check", ] @@ -2370,11 +2627,20 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "version_check", ] +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -2404,19 +2670,39 @@ dependencies = [ "unarray", ] +[[package]] +name = "proptest-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b46295382dc76166cb7cf2bb4a97952464e4b7ed5a43e6cd34e1fec3349ddc" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + [[package]] name = "quote" version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.79", ] [[package]] @@ -2497,6 +2783,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_pcg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rand_xorshift" version = "0.3.0" @@ -2537,11 +2832,11 @@ checksum = "cbaf7105cd254b632f4732fbcc243ce750cef87d8335826125ef6df5733b5a0c" dependencies = [ "either", "itertools", - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "rayon", "syn 1.0.109", - "uuid", + "uuid 1.8.0", ] [[package]] @@ -2840,8 +3135,8 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791c2c848cff1abaeae34fef7e70da5f93171d9eea81ce0fe969a1df627a61a8" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "serde_derive_internals", "syn 1.0.109", ] @@ -2924,9 +3219,9 @@ version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -2935,8 +3230,8 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -3093,8 +3388,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" dependencies = [ "heck 0.4.1", - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -3130,20 +3425,53 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.79", + "quote 1.0.35", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "subtle" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid", +] + [[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "unicode-ident", ] @@ -3153,8 +3481,8 @@ version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "unicode-ident", ] @@ -3240,8 +3568,8 @@ version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.79", + "quote 1.0.35", "syn 1.0.109", ] @@ -3327,9 +3655,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -3356,6 +3684,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "tower" version = "0.4.13" @@ -3402,9 +3739,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] [[package]] @@ -3521,6 +3858,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "untrusted" version = "0.7.1" @@ -3550,6 +3893,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + [[package]] name = "uuid" version = "1.8.0" @@ -3565,6 +3918,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" + [[package]] name = "vcpkg" version = "0.2.15" @@ -3636,9 +3995,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", "wasm-bindgen-shared", ] @@ -3660,7 +4019,7 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote", + "quote 1.0.35", "wasm-bindgen-macro-support", ] @@ -3670,9 +4029,9 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3903,7 +4262,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 2.0.53", ] diff --git a/Cargo.toml b/Cargo.toml index de810b4b..8e5f42dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,9 @@ members = [ "kairos-crypto", "kairos-server", "kairos-tx", - "kairos-test-utils", + "kairos-test-utils", "kairos-l1-utils", + "kairos-contracts/demo-contract-tests", ] [workspace.package] diff --git a/flake.lock b/flake.lock index 6bc0c0a1..52ed4d09 100644 --- a/flake.lock +++ b/flake.lock @@ -117,11 +117,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1710734606, - "narHash": "sha256-rFJl+WXfksu2NkWJWKGd5Km17ZGEjFg9hOQNwstsoU8=", + "lastModified": 1713128889, + "narHash": "sha256-aB90ZqzosyRDpBh+rILIcyP5lao8SKz8Sr2PSWvZrzk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "79bb4155141a5e68f2bdee2bf6af35b1d27d3a1d", + "rev": "2748d22b45a99fb2deafa5f11c7531c212b2cefa", "type": "github" }, "original": { @@ -149,23 +149,38 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1713013257, + "narHash": "sha256-ZEfGB3YCBVggvk0BQIqVY7J8XF/9jxQ68fCca6nib+8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "90055d5e616bd943795d38808c94dbf0dd35abe8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, "risc0pkgs": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ] + "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1705057078, - "narHash": "sha256-IvTD2yh6vYFKgvBATOl793csHbu2Vki3D19MKCHp8sk=", + "lastModified": 1707207642, + "narHash": "sha256-EjzGyFHs+hpSuvOjNnVBx48V5h5whRIyAjIUgSOzqLk=", "owner": "cspr-rad", "repo": "risc0pkgs", - "rev": "144c9a42850a245f581db2586208cd18f98ff62b", + "rev": "7acff27ce7116777cc7f5a162efa9b599808ed97", "type": "github" }, "original": { "owner": "cspr-rad", "repo": "risc0pkgs", + "rev": "7acff27ce7116777cc7f5a162efa9b599808ed97", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 0d4b29e8..07c0160e 100644 --- a/flake.nix +++ b/flake.nix @@ -25,8 +25,10 @@ crane.inputs.nixpkgs.follows = "nixpkgs"; advisory-db.url = "github:rustsec/advisory-db"; advisory-db.flake = false; - risc0pkgs.url = "github:cspr-rad/risc0pkgs"; - risc0pkgs.inputs.nixpkgs.follows = "nixpkgs"; + # Pin to a revision with working risc0 build + risc0pkgs.url = "github:cspr-rad/risc0pkgs/7acff27ce7116777cc7f5a162efa9b599808ed97"; + # FIXME once we are able to build with upstream rustc we should uncomment this + #risc0pkgs.inputs.nixpkgs.follows = "nixpkgs"; csprpkgs.url = "github:cspr-rad/csprpkgs/add-cctl"; csprpkgs.inputs.nixpkgs.follows = "nixpkgs"; }; @@ -41,9 +43,35 @@ ]; perSystem = { config, self', inputs', system, pkgs, lib, ... }: let - rustToolchain = inputs'.fenix.packages.stable.toolchain; + rustToolchain = with inputs'.fenix.packages; combine [ + latest.toolchain + targets.wasm32-unknown-unknown.latest.rust-std + ]; craneLib = inputs.crane.lib.${system}.overrideToolchain rustToolchain; + kairosContractsAttrs = { + src = lib.cleanSourceWith { + src = craneLib.path ./kairos-contracts; + filter = path: type: craneLib.filterCargoSources path type; + }; + cargoExtraArgs = "--target wasm32-unknown-unknown"; + nativeBuildInputs = [ pkgs.binaryen ]; + doCheck = false; + # Append "-optimized" to wasm files, to make the tests pass + postInstall = '' + directory="$out/bin/" + for file in "$directory"*.wasm; do + if [ -e "$file" ]; then + # Extract the file name without extension + filename=$(basename "$file" .wasm) + # Append "-optimized" to the filename and add back the .wasm extension + new_filename="$directory$filename-optimized.wasm" + wasm-opt --strip-debug --signext-lowering "$file" -o "$new_filename" + fi + done + ''; + }; + kairosNodeAttrs = { src = lib.cleanSourceWith { src = craneLib.path ./.; @@ -76,6 +104,9 @@ checkInputs = [ inputs'.csprpkgs.packages.cctl ]; + + PATH_TO_WASM_BINARIES = "${self'.packages.kairos-contracts}/bin"; + meta.mainProgram = "kairos-server"; }; in @@ -116,6 +147,14 @@ kairos-docs = craneLib.cargoDoc (kairosNodeAttrs // { cargoArtifacts = self'.packages.kairos-deps; }); + + kairos-contracts-deps = craneLib.buildPackage (kairosContractsAttrs // { + pname = "kairos-contracts"; + }); + + kairos-contracts = craneLib.buildPackage (kairosContractsAttrs // { + cargoArtifacts = self'.packages.kairos-contracts-deps; + }); }; checks = { @@ -126,9 +165,11 @@ coverage-report = craneLib.cargoTarpaulin (kairosNodeAttrs // { cargoArtifacts = self'.packages.kairos-deps; + # Default values from https://crane.dev/API.html?highlight=tarpau#cranelibcargotarpaulin # --avoid-cfg-tarpaulin fixes nom/bitvec issue https://github.com/xd009642/tarpaulin/issues/756#issuecomment-838769320 cargoTarpaulinExtraArgs = "--skip-clean --out xml --output-dir $out --avoid-cfg-tarpaulin"; + # For some reason cargoTarpaulin runs the tests in the buildPhase buildInputs = kairosNodeAttrs.buildInputs ++ [ inputs'.csprpkgs.packages.cctl @@ -143,6 +184,16 @@ # FIXME --ignore RUSTSEC-2024-0013 ignores libgit2-sys 0.14.2+1.5.1 vulnerability caused by introducing casper-client 2.0.0 cargoAuditExtraArgs = "--ignore yanked --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2024-0013"; }; + + kairos-contracts-lint = craneLib.cargoClippy (kairosContractsAttrs // { + cargoArtifacts = self'.packages.kairos-contracts-deps; + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; + }); + + kairos-contracts-audit = craneLib.cargoAudit { + inherit (kairosContractsAttrs) src; + advisory-db = inputs.advisory-db; + }; }; treefmt = { diff --git a/kairos-contracts/Cargo.lock b/kairos-contracts/Cargo.lock new file mode 100644 index 00000000..a6eb1a6d --- /dev/null +++ b/kairos-contracts/Cargo.lock @@ -0,0 +1,802 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blake2" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "casper-contract" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42901eb5b09bb79e7d7403642e70983ccac0f4812edf1de77d978abea5f3299" +dependencies = [ + "casper-types", + "hex_fmt", + "wee_alloc", +] + +[[package]] +name = "casper-event-standard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3a1bdb142b4bfcdceec757422b2e292f446b72ce3613f881eb694f3925ef10" +dependencies = [ + "casper-contract", + "casper-event-standard-macro", + "casper-types", +] + +[[package]] +name = "casper-event-standard-macro" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485810e6c8387863a92e9b81e4e66ce290e2c96c0ad8ec4352e95128aa88900e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "casper-types" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e01525b7bbae90fe9de3f1def6ffe05052a94ed7d14b1c2b38baec81eeec31b" +dependencies = [ + "base16", + "base64 0.13.1", + "bitflags", + "blake2", + "ed25519-dalek", + "hex", + "hex_fmt", + "k256", + "num", + "num-derive", + "num-integer", + "num-rational", + "num-traits", + "rand", + "serde", + "serde_bytes", + "serde_json", + "uint", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "contract" +version = "0.1.0" +dependencies = [ + "base64 0.20.0", + "bincode", + "casper-contract", + "casper-event-standard", + "casper-types", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "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 = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "deposit-session" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "malicious-reader" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + +[[package]] +name = "malicious-session" +version = "0.1.0" +dependencies = [ + "casper-contract", + "casper-types", +] + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/kairos-contracts/Cargo.toml b/kairos-contracts/Cargo.toml new file mode 100644 index 00000000..454c4ad9 --- /dev/null +++ b/kairos-contracts/Cargo.toml @@ -0,0 +1,15 @@ +[workspace] +resolver = "2" + +members = [ + "demo-contract/malicious-reader", + "demo-contract/malicious-session", + "demo-contract/deposit-session", + "demo-contract/contract", +] + +[workspace.package] +name = "kairos-contracts" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" diff --git a/kairos-contracts/demo-contract-tests/Cargo.toml b/kairos-contracts/demo-contract-tests/Cargo.toml new file mode 100644 index 00000000..53c84aaa --- /dev/null +++ b/kairos-contracts/demo-contract-tests/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "demo-contract-tests" +version.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dev-dependencies] +base64 = {version = "0.21.2", default-features = false, features = ["alloc"] } +casper-engine-test-support = {version="7.0.0", default-features=false} +casper-execution-engine = {version="7.0.0", default-features=false} +casper-contract = {version="4.0.0", default-features=false} +casper-types = {version="4.0.0", default-features=false} +dotenvy = "0.15.7" +lazy_static = "1.4.0" diff --git a/kairos-contracts/demo-contract-tests/rust-toolchain.toml b/kairos-contracts/demo-contract-tests/rust-toolchain.toml new file mode 100644 index 00000000..292fe499 --- /dev/null +++ b/kairos-contracts/demo-contract-tests/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" diff --git a/kairos-contracts/demo-contract-tests/tests/integration_tests.rs b/kairos-contracts/demo-contract-tests/tests/integration_tests.rs new file mode 100644 index 00000000..45607079 --- /dev/null +++ b/kairos-contracts/demo-contract-tests/tests/integration_tests.rs @@ -0,0 +1,64 @@ +mod test_fixture; +#[cfg(test)] +mod tests { + use crate::test_fixture::TestContext; + use casper_types::{account::AccountHash, U512}; + + #[test] + fn should_install_deposit_contract() { + let mut fixture: TestContext = TestContext::new(); + fixture.install_demo_contract(fixture.account_1); + } + + fn setup() -> (TestContext, AccountHash, AccountHash) { + let fixture: TestContext = TestContext::new(); + let installer = fixture.account_1; + let user = fixture.account_2; + (fixture, installer, user) + } + + #[test] + fn deposit_into_purse() { + let deposit_amount: U512 = U512::from(100000000000u64); + let (mut fixture, installer, user) = setup(); + fixture.install_demo_contract(installer); + + let user_purse_uref = fixture.get_account_purse_uref(user); + let user_balance_before = fixture.builder.get_purse_balance(user_purse_uref); + + let contract_balance_before = fixture.get_contract_purse_balance(installer); + assert_eq!(contract_balance_before, U512::zero()); + + fixture.run_deposit_session(deposit_amount, installer, user); + + let contract_balance_after = fixture.get_contract_purse_balance(installer); + assert_eq!(contract_balance_after, deposit_amount); + + let user_balance_after = fixture.builder.get_purse_balance(user_purse_uref); + assert!(user_balance_after <= user_balance_before - deposit_amount); + } + + // see malicious-session + #[test] + fn run_malicious_session() { + let (mut fixture, installer, user) = setup(); + fixture.install_demo_contract(installer); + fixture.run_deposit_session(U512::from(100000000000u64), installer, user); + fixture.run_malicious_session(fixture.account_2, U512::from(100000000000u64), installer); + } + + // see malicious-reader + #[test] + fn run_malicious_reader() { + let (mut fixture, installer, user) = setup(); + fixture.install_demo_contract(installer); + fixture.run_deposit_session(U512::from(100000000000u64), installer, user); + let deposit_purse_uref = fixture.get_contract_purse_uref(installer); + fixture.run_malicious_reader_session( + fixture.account_2, + U512::from(100000000000u64), + installer, + deposit_purse_uref, + ); + } +} diff --git a/kairos-contracts/demo-contract-tests/tests/lib.rs b/kairos-contracts/demo-contract-tests/tests/lib.rs new file mode 100644 index 00000000..66d4fc53 --- /dev/null +++ b/kairos-contracts/demo-contract-tests/tests/lib.rs @@ -0,0 +1,3 @@ +pub mod test_fixture { + pub mod utils; +} diff --git a/kairos-contracts/demo-contract-tests/tests/test_fixture/mod.rs b/kairos-contracts/demo-contract-tests/tests/test_fixture/mod.rs new file mode 100644 index 00000000..d7c8549e --- /dev/null +++ b/kairos-contracts/demo-contract-tests/tests/test_fixture/mod.rs @@ -0,0 +1,208 @@ +mod utils; +use casper_engine_test_support::{ + ExecuteRequestBuilder, InMemoryWasmTestBuilder, PRODUCTION_RUN_GENESIS_REQUEST, +}; +use casper_types::{ + account::AccountHash, contracts::NamedKeys, runtime_args, ContractHash, Key, RuntimeArgs, URef, + U512, +}; +use lazy_static::lazy_static; +use utils::create_funded_dummy_account; +extern crate dotenvy; +use dotenvy::dotenv; +use std::env; + +pub const ACCOUNT_USER_1: [u8; 32] = [1u8; 32]; +pub const ACCOUNT_USER_2: [u8; 32] = [2u8; 32]; +pub const ACCOUNT_USER_3: [u8; 32] = [3u8; 32]; + +// This defines a static variable for the path to WASM binaries +lazy_static! { + static ref PATH_TO_WASM_BINARIES: String = { + dotenv().ok(); + env::var("PATH_TO_WASM_BINARIES") + .expect("Missing environment variable PATH_TO_WASM_BINARIES") + }; +} + +pub struct TestContext { + pub builder: InMemoryWasmTestBuilder, + pub account_1: AccountHash, + pub account_2: AccountHash, + #[allow(dead_code)] + pub account_3: AccountHash, +} + +impl TestContext { + pub fn new() -> TestContext { + let mut builder = InMemoryWasmTestBuilder::default(); + builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST); + let account_1 = create_funded_dummy_account(&mut builder, Some(ACCOUNT_USER_1)); + let account_2 = create_funded_dummy_account(&mut builder, Some(ACCOUNT_USER_2)); + let account_3 = create_funded_dummy_account(&mut builder, Some(ACCOUNT_USER_3)); + + TestContext { + builder, + account_1, + account_2, + account_3, + } + } + + pub fn named_keys(&self, account: AccountHash) -> NamedKeys { + self.builder + .get_expected_account(account) + .named_keys() + .clone() + } + + pub fn get_contract_named_key( + &self, + contract_name: &str, + key_name: &str, + account: AccountHash, + ) -> Key { + let contract_hash = self.contract_hash_from_named_keys(contract_name, account); + *self + .builder + .get_contract(contract_hash) + .expect("should have contract") + .named_keys() + .get(key_name) + .expect("Key not found") + } + + pub fn contract_hash_from_named_keys( + &self, + key_name: &str, + account: AccountHash, + ) -> ContractHash { + self.named_keys(account) + .get(key_name) + .expect("must have contract hash key as part of contract creation") + .into_hash() + .map(ContractHash::new) + .expect("must get contract hash") + } + + pub fn contract_hash(&self, name: &str, account: AccountHash) -> ContractHash { + self.builder + .get_expected_account(account) + .named_keys() + .get(name) + .expect("must have contract hash key as part of contract creation") + .into_hash() + .map(ContractHash::new) + .expect("must get contract hash") + } + + pub fn install_demo_contract(&mut self, admin: AccountHash) { + let session_args = runtime_args! {}; + let install_contract_request = ExecuteRequestBuilder::standard( + admin, + &format!( + "{}/{}", + *PATH_TO_WASM_BINARIES, "demo-contract-optimized.wasm" + ), + session_args, + ) + .build(); + self.builder + .exec(install_contract_request) + .expect_success() + .commit(); + } + + pub fn get_contract_purse_uref(&self, account: AccountHash) -> URef { + let seed_uref: URef = *self + .get_contract_named_key("kairos_demo_contract", "kairos_deposit_purse", account) + .as_uref() + .unwrap(); + seed_uref + } + + pub fn get_account_purse_uref(&self, account: AccountHash) -> URef { + self.builder.get_expected_account(account).main_purse() + } + + #[allow(dead_code)] + pub fn get_contract_purse_balance(&self, account: AccountHash) -> U512 { + let contract_purse_uref: URef = *self + .get_contract_named_key("kairos_demo_contract", "kairos_deposit_purse", account) + .as_uref() + .unwrap(); + self.builder.get_purse_balance(contract_purse_uref) + } + + /*// read a u64 counter from the contract named keys e.g. "last_processed_deposit_counter" + pub fn read_counter_value(&mut self, account: AccountHash, name: &str) -> u64 { + let contract_hash = self.contract_hash("kairos_demo_contract", account); + self.builder.get_value(contract_hash, name) + }*/ + + // see deposit-session + pub fn run_deposit_session(&mut self, amount: U512, installer: AccountHash, user: AccountHash) { + let session_args = runtime_args! { + "amount" => amount, + "demo_contract" => self.contract_hash("kairos_demo_contract", installer) + }; + let session_request = ExecuteRequestBuilder::standard( + user, + &format!( + "{}/{}", + *PATH_TO_WASM_BINARIES, "deposit-session-optimized.wasm" + ), + session_args, + ) + .build(); + self.builder.exec(session_request).expect_success().commit(); + } + + // see malicious-session + pub fn run_malicious_session( + &mut self, + msg_sender: AccountHash, + amount: U512, + account: AccountHash, + ) { + let session_args = runtime_args! { + "amount" => amount, + "demo_contract" => self.contract_hash("kairos_demo_contract", account) + }; + let session_request = ExecuteRequestBuilder::standard( + msg_sender, + &format!( + "{}/{}", + *PATH_TO_WASM_BINARIES, "malicious-session-optimized.wasm" + ), + session_args, + ) + .build(); + self.builder.exec(session_request).expect_failure().commit(); + } + + // see malicious-reader + pub fn run_malicious_reader_session( + &mut self, + msg_sender: AccountHash, + amount: U512, + account: AccountHash, + deposit_purse_uref: URef, + ) { + let session_args = runtime_args! { + "amount" => amount, + "demo_contract" => self.contract_hash("kairos_demo_contract", account), + "purse_uref" => deposit_purse_uref + }; + let session_request = ExecuteRequestBuilder::standard( + msg_sender, + &format!( + "{}/{}", + *PATH_TO_WASM_BINARIES, "malicious-reader-optimized.wasm" + ), + session_args, + ) + .build(); + self.builder.exec(session_request).expect_failure().commit(); + } +} diff --git a/kairos-contracts/demo-contract-tests/tests/test_fixture/utils.rs b/kairos-contracts/demo-contract-tests/tests/test_fixture/utils.rs new file mode 100644 index 00000000..dd1fa2cd --- /dev/null +++ b/kairos-contracts/demo-contract-tests/tests/test_fixture/utils.rs @@ -0,0 +1,38 @@ +use casper_engine_test_support::{ + ExecuteRequestBuilder, WasmTestBuilder, ARG_AMOUNT, DEFAULT_ACCOUNT_ADDR, + DEFAULT_ACCOUNT_INITIAL_BALANCE, +}; +use casper_execution_engine::storage::global_state::in_memory::InMemoryGlobalState; +use casper_types::{ + account::AccountHash, + runtime_args, + system::{handle_payment::ARG_TARGET, mint::ARG_ID}, + PublicKey, RuntimeArgs, SecretKey, +}; + +// Creates a dummy account and transfer funds to it +pub fn create_funded_dummy_account( + builder: &mut WasmTestBuilder, + account_string: Option<[u8; 32]>, +) -> AccountHash { + let (_, account_public_key) = create_dummy_key_pair(account_string.unwrap_or([7u8; 32])); + let account = account_public_key.to_account_hash(); + let transfer = ExecuteRequestBuilder::transfer( + *DEFAULT_ACCOUNT_ADDR, + runtime_args! { + ARG_AMOUNT => DEFAULT_ACCOUNT_INITIAL_BALANCE / 10_u64, + ARG_TARGET => account, + ARG_ID => Option::::None, + }, + ) + .build(); + builder.exec(transfer).expect_success().commit(); + account +} + +pub fn create_dummy_key_pair(account_string: [u8; 32]) -> (SecretKey, PublicKey) { + let secret_key = + SecretKey::ed25519_from_bytes(account_string).expect("failed to create secret key"); + let public_key = PublicKey::from(&secret_key); + (secret_key, public_key) +} diff --git a/kairos-contracts/demo-contract/contract/.cargo/config.toml b/kairos-contracts/demo-contract/contract/.cargo/config.toml new file mode 100644 index 00000000..f4e8c002 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" diff --git a/kairos-contracts/demo-contract/contract/Cargo.toml b/kairos-contracts/demo-contract/contract/Cargo.toml new file mode 100644 index 00000000..27e3f193 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "contract" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +casper-contract = {version="4.0.0", features=["std", "test-support"]} +casper-types = {version="4.0.0", default-features=false} +casper-event-standard="0.5.0" +base64 = { version = "0.20.0", default-features = false, features = ["alloc"] } +bincode = "1.3.3" + + +[build] +target = "wasm32-unknown-unknown" + +[[bin]] +name = "demo-contract" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[profile.release] +codegen-units = 1 +lto = true diff --git a/kairos-contracts/demo-contract/contract/src/constants.rs b/kairos-contracts/demo-contract/contract/src/constants.rs new file mode 100644 index 00000000..9f3540ef --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/constants.rs @@ -0,0 +1,17 @@ +pub const KAIROS_DEPOSIT_CONTRACT_NAME: &str = "kairos_demo_contract"; + +//#[allow(dead_code)] +pub const KAIROS_DEPOSIT_CONTRACT_PACKAGE: &str = "kairos_contract_package"; +pub const KAIROS_DEPOSIT_CONTRACT_UREF: &str = "demo_contract"; + +pub const KAIROS_LAST_PROCESSED_DEPOSIT_COUNTER: &str = "last_processed_deposit_counter"; +pub const KAIROS_DEPOSIT_PURSE: &str = "kairos_deposit_purse"; + +pub const RUNTIME_ARG_TEMP_PURSE: &str = "temp_purse"; + +//#[allow(dead_code)] +pub const RUNTIME_ARG_AMOUNT: &str = "amount"; + +pub const EP_INIT_NAME: &str = "init"; +pub const EP_GET_PURSE_NAME: &str = "get_purse"; +pub const EP_DEPOSIT_NAME: &str = "deposit"; diff --git a/kairos-contracts/demo-contract/contract/src/entry_points.rs b/kairos-contracts/demo-contract/contract/src/entry_points.rs new file mode 100644 index 00000000..ad6fc41e --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/entry_points.rs @@ -0,0 +1,38 @@ +use crate::constants::{ + EP_DEPOSIT_NAME, EP_GET_PURSE_NAME, EP_INIT_NAME, RUNTIME_ARG_AMOUNT, RUNTIME_ARG_TEMP_PURSE, +}; +use alloc::vec; +use casper_types::{CLType, EntryPoint, EntryPointAccess, EntryPointType, Parameter}; + +pub fn init() -> EntryPoint { + EntryPoint::new( + EP_INIT_NAME, + vec![], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Contract, + ) +} + +pub fn get_purse() -> EntryPoint { + EntryPoint::new( + EP_GET_PURSE_NAME, + vec![], + CLType::URef, + EntryPointAccess::Public, + EntryPointType::Contract, + ) +} + +pub fn deposit() -> EntryPoint { + EntryPoint::new( + EP_DEPOSIT_NAME, + vec![ + Parameter::new(RUNTIME_ARG_AMOUNT, CLType::U512), + Parameter::new(RUNTIME_ARG_TEMP_PURSE, CLType::URef), + ], + CLType::Unit, + EntryPointAccess::Public, + EntryPointType::Contract, + ) +} diff --git a/kairos-contracts/demo-contract/contract/src/main.rs b/kairos-contracts/demo-contract/contract/src/main.rs new file mode 100644 index 00000000..0f8c9224 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/main.rs @@ -0,0 +1,130 @@ +#![no_std] +#![no_main] +extern crate alloc; +use alloc::{string::ToString, vec::Vec}; +use casper_contract::{ + contract_api::{runtime, storage, system}, + unwrap_or_revert::UnwrapOrRevert, +}; +use casper_event_standard::Schemas; +use casper_types::{ + contracts::NamedKeys, runtime_args, AccessRights, ApiError, CLValue, EntryPoints, Key, + RuntimeArgs, URef, U512, +}; +mod constants; +use constants::{ + KAIROS_DEPOSIT_CONTRACT_NAME, KAIROS_DEPOSIT_CONTRACT_PACKAGE, KAIROS_DEPOSIT_CONTRACT_UREF, + KAIROS_DEPOSIT_PURSE, KAIROS_LAST_PROCESSED_DEPOSIT_COUNTER, RUNTIME_ARG_AMOUNT, + RUNTIME_ARG_TEMP_PURSE, +}; +mod entry_points; +mod utils; +use utils::errors::DepositError; +use utils::events::Deposit; +use utils::get_immediate_caller; + +// This entry point is called once when the contract is installed +// and sets up the security badges with the installer as an admin or the +// optional list of admins. +// The optional list of admins is passed to the installation session as a runtime argument. +// The contract purse will be created in contract context so that it is "owned" by the contract +// rather than the installing account. +#[no_mangle] +pub extern "C" fn init() { + if runtime::get_key(KAIROS_DEPOSIT_PURSE).is_some() { + runtime::revert(DepositError::AlreadyInitialized); + } + + // initialize event schema + let schemas = Schemas::new().with::(); + casper_event_standard::init(schemas); + + let new_deposit_purse: URef = system::create_purse(); + runtime::put_key(KAIROS_DEPOSIT_PURSE, new_deposit_purse.into()); +} + +#[no_mangle] +pub extern "C" fn get_purse() { + let deposit_purse: URef = runtime::get_key(KAIROS_DEPOSIT_PURSE) + .unwrap_or_revert_with(DepositError::MissingKeyDepositPurse) + .into_uref() + .unwrap_or_revert(); + let reference_to_deposit_purse_with_restricted_access = + deposit_purse.with_access_rights(AccessRights::ADD); + runtime::ret( + CLValue::from_t(reference_to_deposit_purse_with_restricted_access) + .unwrap_or_revert_with(DepositError::FailedToReturnContractPurseAsReference), + ); +} + +// Batch submission with host verifier: Unimplemented +// This entry point will verify a batch proof and update the trie root +// TODO: Store the trie root under a URef in this deposit contract +// QUESTION: What is the initial root and state of the trie? +#[no_mangle] +pub extern "C" fn submit_batch() { + // receive some serialized proof + // the proof will include a public journal with the updated trie root + let _serialized_proof: Vec = runtime::get_named_arg("serialized_proof"); + + // TODO: VERIFY proof and UPDATE the trie root + // TODO: UPDATE last_processed_deposit_counter by `n`, where `n` is the amount of deposits processed in this batch. + + // OPEN QUESTIONS + // How are L1 deposits verified when proving? + // Are deposits and transfers private or public inputs to the circuit / guest? +} + +// Entry point called by a user through session code to deposit funds. +// Due to Casper < 2.0 purse management and access control, it is necessary that +// a temporary purse is funded and passed to the deposit contract, since this is +// the only secure method of making a payment to a contract purse. +#[no_mangle] +pub extern "C" fn deposit() { + let temp_purse: URef = runtime::get_named_arg(RUNTIME_ARG_TEMP_PURSE); + let amount: U512 = runtime::get_named_arg(RUNTIME_ARG_AMOUNT); + let deposit_purse_uref: URef = runtime::get_key(KAIROS_DEPOSIT_PURSE) + .unwrap_or_revert_with(DepositError::MissingKeyDepositPurse) + .into_uref() + .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant); + system::transfer_from_purse_to_purse(temp_purse, deposit_purse_uref, amount, None) + .unwrap_or_revert(); + + let new_deposit_record: Deposit = Deposit { + account: get_immediate_caller().unwrap_or_revert(), + amount, + timestamp: None, + }; + casper_event_standard::emit(new_deposit_record); +} + +#[no_mangle] +pub extern "C" fn call() { + let entry_points = { + let mut entry_points = EntryPoints::new(); + entry_points.add_entry_point(entry_points::init()); + entry_points.add_entry_point(entry_points::get_purse()); + entry_points.add_entry_point(entry_points::deposit()); + entry_points + }; + // this counter will be udpated by the entry point that processes / verifies batches + let mut named_keys = NamedKeys::new(); + let last_processed_deposit_counter = storage::new_uref(u64::from(0u8)); + + named_keys.insert( + KAIROS_LAST_PROCESSED_DEPOSIT_COUNTER.to_string(), + last_processed_deposit_counter.into(), + ); + + let (contract_hash, _) = storage::new_locked_contract( + entry_points, + Some(named_keys), + Some(KAIROS_DEPOSIT_CONTRACT_UREF.to_string()), + Some(KAIROS_DEPOSIT_CONTRACT_PACKAGE.to_string()), + ); + let contract_hash_key = Key::from(contract_hash); + runtime::put_key(KAIROS_DEPOSIT_CONTRACT_NAME, contract_hash_key); + + let init_args = runtime_args! {}; + runtime::call_contract::<()>(contract_hash, "init", init_args); +} diff --git a/kairos-contracts/demo-contract/contract/src/utils.rs b/kairos-contracts/demo-contract/contract/src/utils.rs new file mode 100644 index 00000000..461d74c2 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/utils.rs @@ -0,0 +1,38 @@ +/* + The utilities found in this file were scraped from other Casper contracts, + mainly cep-78 and cep-18. + This file is not necessarily due for review, unless breaking changes are suspected. +*/ +use casper_contract::contract_api::runtime; +use casper_types::{system::CallStackElement, Key}; + +pub mod errors; +pub mod events; +use errors::DepositError; + +/// Wrap the immediate caller as a Key and return it +fn call_stack_element_to_key(call_stack_element: CallStackElement) -> Key { + match call_stack_element { + CallStackElement::Session { account_hash } => Key::from(account_hash), + CallStackElement::StoredSession { account_hash, .. } => { + // Stored session code acts in account's context, so if stored session wants to interact + // with an CEP-18 token caller's address will be used. + Key::from(account_hash) + } + CallStackElement::StoredContract { + contract_package_hash, + .. + } => Key::from(contract_package_hash), + } +} + +/// Traverse the callstack to retrieve the n - 1 th element of the callstack +pub(crate) fn get_immediate_caller() -> Result { + let call_stack = runtime::get_call_stack(); + call_stack + .into_iter() + .rev() + .nth(1) + .map(call_stack_element_to_key) + .ok_or(DepositError::InvalidContext) +} diff --git a/kairos-contracts/demo-contract/contract/src/utils/errors.rs b/kairos-contracts/demo-contract/contract/src/utils/errors.rs new file mode 100644 index 00000000..39603190 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/utils/errors.rs @@ -0,0 +1,24 @@ +//! Error handling on the Casper platform. +use casper_types::ApiError; + +#[repr(u16)] +#[derive(Clone, Copy)] +pub enum DepositError { + InvalidContext = 0, + MissingKey = 1, + FailedToGetArgBytes = 2, + MissingOptionalArgument = 3, + AlreadyInitialized = 4, + MissingKeyDepositPurse = 5, + MissingKeyMostRecentDepositCounter = 6, + MissingKeyLastProcessedDepositCounter = 7, + MissingKeyDepositEventDict = 8, + FailedToCreateDepositDict = 9, + FailedToReturnContractPurseAsReference = 10, +} + +impl From for ApiError { + fn from(error: DepositError) -> Self { + ApiError::User(error as u16) + } +} diff --git a/kairos-contracts/demo-contract/contract/src/utils/events.rs b/kairos-contracts/demo-contract/contract/src/utils/events.rs new file mode 100644 index 00000000..980b7b14 --- /dev/null +++ b/kairos-contracts/demo-contract/contract/src/utils/events.rs @@ -0,0 +1,11 @@ +use casper_event_standard::Event; +extern crate alloc; +use alloc::string::String; +use casper_types::{Key, U512}; + +#[derive(Event)] +pub struct Deposit { + pub account: Key, + pub amount: U512, + pub timestamp: Option, +} diff --git a/kairos-contracts/demo-contract/deposit-session/Cargo.toml b/kairos-contracts/demo-contract/deposit-session/Cargo.toml new file mode 100644 index 00000000..8122eeec --- /dev/null +++ b/kairos-contracts/demo-contract/deposit-session/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "deposit-session" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +casper-contract = {version="4.0.0", features=["test-support"]} +casper-types = "4.0.0" + +[[bin]] +name = "deposit-session" +path = "src/main.rs" +bench = false +doctest = false +test = false + +[profile.release] +codegen-units = 1 +lto = true diff --git a/kairos-contracts/demo-contract/deposit-session/src/main.rs b/kairos-contracts/demo-contract/deposit-session/src/main.rs new file mode 100644 index 00000000..3729e7c5 --- /dev/null +++ b/kairos-contracts/demo-contract/deposit-session/src/main.rs @@ -0,0 +1,36 @@ +/* + Transfer native Casper tokens from the caller to the deposit smart contract. + Due to the purse access control in Casper 1.5.x, a temporary purse is created and funded + by the user first, to then be passed to the deposit contract. + + Finally the temporary purse is emptied / all funds are transferred to the deposit contract's + purse. +*/ +#![no_std] +#![no_main] +use casper_contract::contract_api::{account, runtime, system}; +use casper_types::{runtime_args, ContractHash, RuntimeArgs, URef, U512}; + +#[no_mangle] +pub extern "C" fn call() { + let contract_hash: ContractHash = runtime::get_named_arg("demo_contract"); + let amount: U512 = runtime::get_named_arg("amount"); + let source: URef = account::get_main_purse(); + // create a temporary purse that can be passed to the deposit contract + // this is required due to the access control model of the purse system used + // in casper_node 1.5.x + // this will likely be drastically changed in 2.0 + let temp_purse: URef = system::create_purse(); + // fund the temporary purse + system::transfer_from_purse_to_purse(source, temp_purse, amount, None) + .expect("Failed to transfer into temporary purse"); + // call the deposit endpoint + runtime::call_contract::<()>( + contract_hash, + "deposit", + runtime_args! { + "temp_purse" => temp_purse, + "amount" => amount + }, + ); +} diff --git a/kairos-contracts/demo-contract/malicious-reader/Cargo.toml b/kairos-contracts/demo-contract/malicious-reader/Cargo.toml new file mode 100644 index 00000000..659962ef --- /dev/null +++ b/kairos-contracts/demo-contract/malicious-reader/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "malicious-reader" +version.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +casper-contract = "4.0.0" +casper-types = "4.0.0" + +[[bin]] +name = "malicious-reader" +path = "src/main.rs" +bench = false +doctest = false +test = false diff --git a/kairos-contracts/demo-contract/malicious-reader/src/main.rs b/kairos-contracts/demo-contract/malicious-reader/src/main.rs new file mode 100644 index 00000000..dee773d1 --- /dev/null +++ b/kairos-contracts/demo-contract/malicious-reader/src/main.rs @@ -0,0 +1,19 @@ +/* + This session code emulates an attack where a user tries to transfer funds + out of the deposit contract's purse, by passing the deposit contract purse as a runtime argument + and calling transfer_from_purse_to_purse +*/ + +#![no_std] +#![no_main] +use casper_contract::contract_api::{account, runtime, system}; +use casper_types::{URef, U512}; + +#[no_mangle] +pub extern "C" fn call() { + let amount: U512 = runtime::get_named_arg("amount"); + let purse_uref: URef = runtime::get_named_arg("purse_uref"); + let destination_purse: URef = account::get_main_purse(); + system::transfer_from_purse_to_purse(purse_uref, destination_purse, amount, None) + .expect("Failed to transfer from purse to purse"); +} diff --git a/kairos-contracts/demo-contract/malicious-session/Cargo.toml b/kairos-contracts/demo-contract/malicious-session/Cargo.toml new file mode 100644 index 00000000..f38620ec --- /dev/null +++ b/kairos-contracts/demo-contract/malicious-session/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "malicious-session" +version.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +casper-contract = "4.0.0" +casper-types = "4.0.0" + +[[bin]] +name = "malicious-session" +path = "src/main.rs" +bench = false +doctest = false +test = false diff --git a/kairos-contracts/demo-contract/malicious-session/src/main.rs b/kairos-contracts/demo-contract/malicious-session/src/main.rs new file mode 100644 index 00000000..02294fa1 --- /dev/null +++ b/kairos-contracts/demo-contract/malicious-session/src/main.rs @@ -0,0 +1,21 @@ +/* + This session code emulates an attack where a user tries to transfer funds + out of the deposit contract's purse, by querying the get_purse entry point + and calling transfer_from_purse_to_purse +*/ + +#![no_std] +#![no_main] +use casper_contract::contract_api::{account, runtime, system}; +use casper_types::{runtime_args, ContractHash, RuntimeArgs, URef, U512}; + +#[no_mangle] +pub extern "C" fn call() { + let contract_hash: ContractHash = runtime::get_named_arg("demo_contract"); + let amount: U512 = runtime::get_named_arg("amount"); + let destination_purse: URef = account::get_main_purse(); + let borrowed_contract_purse: URef = + runtime::call_contract::(contract_hash, "get_purse", runtime_args! {}); + system::transfer_from_purse_to_purse(borrowed_contract_purse, destination_purse, amount, None) + .expect("Failed to transfer from purse to purse"); +} diff --git a/kairos-contracts/rust-toolchain.toml b/kairos-contracts/rust-toolchain.toml new file mode 100644 index 00000000..a0f1a930 --- /dev/null +++ b/kairos-contracts/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-01-04"