diff --git a/generate-wasm.sh b/generate-wasm.sh new file mode 100755 index 00000000..34c4a2a0 --- /dev/null +++ b/generate-wasm.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# Regenerate bridge_ui/rust_modules +set -euo pipefail + +( + cd solana + mkdir -p ../bridge_ui/rust_modules/core + docker build -t localhost/certusone/wormhole-wasmpack:latest -f Dockerfile.wasm . + docker run --rm -it --workdir /usr/src/bridge/bridge/program \ + -v $(pwd)/../bridge_ui/rust_modules/core:/usr/src/bridge/bridge/program/pkg \ + -e EMITTER_ADDRESS=11111111111111111111111111111115 \ + localhost/certusone/wormhole-wasmpack:latest \ + /usr/local/cargo/bin/wasm-pack build --target nodejs -- --features no-entrypoint + cp $(pwd)/../bridge_ui/rust_modules/core/. $(pwd)/../clients/solana/pkg/ -R +) diff --git a/solana/Dockerfile.wasm b/solana/Dockerfile.wasm new file mode 100644 index 00000000..7d3ed36a --- /dev/null +++ b/solana/Dockerfile.wasm @@ -0,0 +1,17 @@ +# syntax=docker.io/docker/dockerfile:experimental@sha256:de85b2f3a3e8a2f7fe48e8e84a65f6fdd5cd5183afa6412fff9caa6871649c44 +FROM docker.io/library/rust:1.49@sha256:a50165ea96983c21832578afb1c8c028674c965bc1ed43b607871b1f362e06a5 + +RUN apt-get update && apt-get install -y libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang +RUN rustup component add rustfmt +RUN rustup default nightly + +WORKDIR /usr/src/bridge + +RUN cargo install wasm-pack + +ENV RUST_LOG="solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=trace,solana_bpf_loader=debug,solana_rbpf=debug" +ENV EMITTER_ADDRESS="11111111111111111111111111111115" + +COPY bridge bridge +COPY modules modules +COPY solitaire solitaire \ No newline at end of file diff --git a/solana/bridge/Cargo.lock b/solana/bridge/Cargo.lock index f95de276..2859a41a 100644 --- a/solana/bridge/Cargo.lock +++ b/solana/bridge/Cargo.lock @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "arrayref" @@ -125,9 +125,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -136,9 +136,9 @@ version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -282,7 +282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a7111f797cc721407885a323fb071636aee57f750b1a4ddc27397eba168a74" dependencies = [ "borsh-derive", - "hashbrown", + "hashbrown 0.9.1", ] [[package]] @@ -293,9 +293,9 @@ checksum = "307f3740906bac2c118a8122fe22681232b244f1369273e45f1156b45c43d2dd" dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", - "proc-macro-crate", - "proc-macro2 1.0.27", - "syn 1.0.73", + "proc-macro-crate 0.1.5", + "proc-macro2 1.0.28", + "syn 1.0.74", ] [[package]] @@ -304,9 +304,9 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2104c73179359431cc98e016998f2f23bc7a05bc53e79741bcba705f30047bc" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -315,9 +315,9 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae29eb8418fcd46f723f8691a2ac06857d31179d33d2f2d91eb13967de97c728" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -329,14 +329,16 @@ dependencies = [ "hex", "hex-literal", "libsecp256k1", - "primitive-types 0.9.0", + "primitive-types 0.9.1", "rand 0.7.3", + "serde", "sha3", "solana-client", "solana-program", "solana-sdk", "solitaire", "solitaire-client", + "wasm-bindgen", ] [[package]] @@ -349,7 +351,7 @@ dependencies = [ "hex", "hex-literal", "libsecp256k1", - "primitive-types 0.9.0", + "primitive-types 0.9.1", "rand 0.7.3", "sha3", "solana-client", @@ -445,9 +447,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" dependencies = [ "jobserver", ] @@ -578,9 +580,9 @@ checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] name = "cpufeatures" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" dependencies = [ "libc", ] @@ -719,7 +721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.4", - "subtle 2.4.0", + "subtle 2.4.1", ] [[package]] @@ -729,29 +731,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" dependencies = [ "generic-array 0.14.4", - "subtle 2.4.0", + "subtle 2.4.1", ] [[package]] name = "crypto-mac" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" dependencies = [ "generic-array 0.14.4", - "subtle 2.4.0", + "subtle 2.4.1", ] [[package]] name = "curve25519-dalek" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434e1720189a637d44fe464f4df1e6eb900b4835255b14354497c78af37d9bb8" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" dependencies = [ "byteorder", "digest 0.8.1", "rand_core 0.5.1", - "subtle 2.4.0", + "subtle 2.4.1", "zeroize", ] @@ -764,7 +766,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.4.0", + "subtle 2.4.1", "zeroize", ] @@ -794,9 +796,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -866,9 +868,9 @@ checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] name = "ed25519" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0860415b12243916284c67a9be413e044ee6668247b99ba26d94b2bc06c8f6" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" dependencies = [ "serde", "signature", @@ -952,9 +954,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", "synstructure", ] @@ -1130,9 +1132,9 @@ checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" dependencies = [ "autocfg", "proc-macro-hack", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -1161,7 +1163,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -1266,7 +1268,7 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-util 0.6.7", "tracing", ] @@ -1280,6 +1282,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" version = "0.3.3" @@ -1291,9 +1299,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -1306,9 +1314,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" +checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" [[package]] name = "hidapi" @@ -1357,7 +1365,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ - "crypto-mac 0.10.0", + "crypto-mac 0.10.1", "digest 0.9.0", ] @@ -1401,7 +1409,7 @@ checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" dependencies = [ "bytes 1.0.1", "http", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", ] [[package]] @@ -1444,7 +1452,7 @@ dependencies = [ "httparse", "httpdate 0.3.2", "itoa", - "pin-project 1.0.7", + "pin-project 1.0.8", "socket2 0.3.19", "tokio 0.2.25", "tower-service", @@ -1454,9 +1462,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.9" +version = "0.14.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" +checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" dependencies = [ "bytes 1.0.1", "futures-channel", @@ -1468,9 +1476,9 @@ dependencies = [ "httparse", "httpdate 1.0.1", "itoa", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "socket2 0.4.0", - "tokio 1.7.1", + "tokio 1.9.0", "tower-service", "tracing", "want", @@ -1483,10 +1491,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" dependencies = [ "futures-util", - "hyper 0.14.9", + "hyper 0.14.11", "log", "rustls", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-rustls", "webpki", ] @@ -1513,12 +1521,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -1544,9 +1552,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ "cfg-if 1.0.0", ] @@ -1650,9 +1658,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.97" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "libloading" @@ -1676,7 +1684,7 @@ dependencies = [ "hmac-drbg", "rand 0.7.3", "sha2 0.8.2", - "subtle 2.4.0", + "subtle 2.4.1", "typenum", ] @@ -1734,8 +1742,6 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memmap2" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" dependencies = [ "libc", ] @@ -1900,9 +1906,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -1936,9 +1942,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066" +checksum = "e5adf0198d427ee515335639f275e806ca01acf9f07d7cf14bb36a10532a6169" dependencies = [ "derivative", "num_enum_derive", @@ -1946,14 +1952,14 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e" +checksum = "b1def5a3f69d4707d8a040b12785b98029a39e8c610ae685c7f6265669767482" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.27", + "proc-macro-crate 1.0.0", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2014,9 +2020,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-sys" -version = "0.9.64" +version = "0.9.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209efc2fe0e980c8849efacdb567f975a1c80245c4f6980d6f012733bfa851af" +checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" dependencies = [ "autocfg", "cc", @@ -2042,9 +2048,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec33dfceabec83cd0e95a5ce9d20e76ab3a5cbfef59659b8c927f69b93ed8ae" dependencies = [ "Inflector", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2149,7 +2155,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3b8c0d71734018084da0c0354193a5edfb81b20d2d57a92c5b154aefc554a4a" dependencies = [ - "crypto-mac 0.10.0", + "crypto-mac 0.10.1", ] [[package]] @@ -2188,11 +2194,11 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" dependencies = [ - "pin-project-internal 1.0.7", + "pin-project-internal 1.0.8", ] [[package]] @@ -2201,20 +2207,20 @@ version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] name = "pin-project-internal" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2225,9 +2231,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -2260,12 +2266,12 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2415937401cb030a2a0a4d922483f945fa068f52a7dbb22ce0fe5f2b6f6adace" +checksum = "06345ee39fbccfb06ab45f3a1a5798d9dafa04cb8921a76d227040003a234b0e" dependencies = [ "fixed-hash 0.7.0", - "uint 0.9.0", + "uint 0.9.1", ] [[package]] @@ -2277,6 +2283,16 @@ dependencies = [ "toml", ] +[[package]] +name = "proc-macro-crate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +dependencies = [ + "thiserror", + "toml", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -2300,9 +2316,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid 0.2.2", ] @@ -2343,9 +2359,9 @@ checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", "itertools 0.8.2", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2382,7 +2398,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", ] [[package]] @@ -2560,9 +2576,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" +checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" dependencies = [ "base64 0.13.0", "bytes 1.0.1", @@ -2571,7 +2587,7 @@ dependencies = [ "futures-util", "http", "http-body 0.4.2", - "hyper 0.14.9", + "hyper 0.14.11", "hyper-rustls", "ipnet", "js-sys", @@ -2579,12 +2595,12 @@ dependencies = [ "log", "mime", "percent-encoding", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "rustls", "serde", "serde_json", "serde_urlencoded", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-rustls", "url", "wasm-bindgen", @@ -2614,11 +2630,11 @@ name = "rocksalt" version = "0.1.0" dependencies = [ "byteorder", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", "sha3", "solana-program", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2798,9 +2814,9 @@ version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -2852,9 +2868,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" +checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2920,9 +2936,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" [[package]] name = "slab" @@ -3050,7 +3066,7 @@ dependencies = [ "solana-version", "solana-vote-program", "thiserror", - "tokio 1.7.1", + "tokio 1.9.0", "tungstenite 0.10.1", "url", ] @@ -3079,7 +3095,7 @@ dependencies = [ "backtrace", "bytes 0.4.12", "cc", - "curve25519-dalek 2.1.2", + "curve25519-dalek 2.1.3", "ed25519-dalek", "either", "lazy_static", @@ -3090,7 +3106,7 @@ dependencies = [ "ring", "serde", "syn 0.15.44", - "syn 1.0.73", + "syn 1.0.74", "tokio 0.1.22", "winapi 0.3.9", ] @@ -3115,7 +3131,7 @@ dependencies = [ "solana-version", "spl-memo", "thiserror", - "tokio 1.7.1", + "tokio 1.9.0", ] [[package]] @@ -3144,10 +3160,10 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f617daa0187bcc4665d63fcf9454c998e9cdad6a33181f6214558d738230bfe2" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", "rustc_version", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -3203,7 +3219,7 @@ dependencies = [ "solana-clap-utils", "solana-logger", "solana-version", - "tokio 1.7.1", + "tokio 1.9.0", "url", ] @@ -3219,7 +3235,7 @@ dependencies = [ "borsh-derive", "bs58", "bv", - "curve25519-dalek 2.1.2", + "curve25519-dalek 2.1.3", "hex", "itertools 0.9.0", "lazy_static", @@ -3379,10 +3395,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d27426b2a09676929c5e49df96967bbcffff003183c11a3c3ef11d78bac4aaaa" dependencies = [ "bs58", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", "rustversion", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -3570,9 +3586,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "symlink" @@ -3593,24 +3609,24 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", "unicode-xid 0.2.2", ] [[package]] name = "synstructure" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", "unicode-xid 0.2.2", ] @@ -3678,22 +3694,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -3726,9 +3742,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" dependencies = [ "tinyvec_macros", ] @@ -3786,9 +3802,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" +checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" dependencies = [ "autocfg", "bytes 1.0.1", @@ -3798,9 +3814,9 @@ dependencies = [ "num_cpus", "once_cell", "parking_lot 0.11.1", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "signal-hook-registry", - "tokio-macros 1.2.0", + "tokio-macros 1.3.0", "winapi 0.3.9", ] @@ -3863,20 +3879,20 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] name = "tokio-macros" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -3905,7 +3921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ "rustls", - "tokio 1.7.1", + "tokio 1.9.0", "webpki", ] @@ -4019,8 +4035,8 @@ dependencies = [ "futures-core", "futures-sink", "log", - "pin-project-lite 0.2.6", - "tokio 1.7.1", + "pin-project-lite 0.2.7", + "tokio 1.9.0", ] [[package]] @@ -4068,10 +4084,10 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19970cf58f3acc820962be74c4021b8bbc8e8a1c4e3a02095d0aa60cde5f3633" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "prost-build", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -4260,7 +4276,7 @@ checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.6", + "pin-project-lite 0.2.7", "tracing-attributes", "tracing-core", ] @@ -4271,9 +4287,9 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", ] [[package]] @@ -4291,7 +4307,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.7", + "pin-project 1.0.8", "tracing", ] @@ -4336,7 +4352,7 @@ dependencies = [ "log", "native-tls", "rand 0.7.3", - "sha-1 0.9.6", + "sha-1 0.9.7", "url", "utf-8", ] @@ -4367,9 +4383,9 @@ dependencies = [ [[package]] name = "uint" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11fe9a9348741cf134085ad57c249508345fe16411b3d7fb4ff2da2f1d6382e" +checksum = "6470ab50f482bde894a037a57064480a246dbfdd5960bd65a44824693f08da5f" dependencies = [ "byteorder", "crunchy", @@ -4525,9 +4541,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", "wasm-bindgen-shared", ] @@ -4559,9 +4575,9 @@ version = "0.2.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4692,9 +4708,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" dependencies = [ "zeroize_derive", ] @@ -4705,9 +4721,9 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" dependencies = [ - "proc-macro2 1.0.27", + "proc-macro2 1.0.28", "quote 1.0.9", - "syn 1.0.73", + "syn 1.0.74", "synstructure", ] diff --git a/solana/bridge/Cargo.toml b/solana/bridge/Cargo.toml index 95aa69d9..d8ff5755 100644 --- a/solana/bridge/Cargo.toml +++ b/solana/bridge/Cargo.toml @@ -1,2 +1,5 @@ [workspace] -members = ["agent", "program", "client", "program_stub"] \ No newline at end of file +members = ["agent", "program", "client", "program_stub"] + +[patch.crates-io] +memmap2 = { path = "memmap2-rs" } \ No newline at end of file diff --git a/solana/bridge/memmap2-rs/Cargo.toml b/solana/bridge/memmap2-rs/Cargo.toml new file mode 100644 index 00000000..263f539a --- /dev/null +++ b/solana/bridge/memmap2-rs/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "memmap2" +version = "0.1.0" +authors = ["Dan Burkert ", "Evgeniy Reizner "] +license = "MIT/Apache-2.0" +repository = "https://github.com/RazrFalcon/memmap2-rs" +documentation = "https://docs.rs/memmap2" +description = "Cross-platform Rust API for memory-mapped file IO" +keywords = ["mmap", "memory-map", "io", "file"] +edition = "2018" + +[target.'cfg(unix)'.dependencies] +libc = "0.2" + +[dev-dependencies] +tempdir = "0.3" diff --git a/solana/bridge/memmap2-rs/LICENSE-APACHE b/solana/bridge/memmap2-rs/LICENSE-APACHE new file mode 100644 index 00000000..7be3d81a --- /dev/null +++ b/solana/bridge/memmap2-rs/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [2015] [Dan Burkert] + +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. diff --git a/solana/bridge/memmap2-rs/LICENSE-MIT b/solana/bridge/memmap2-rs/LICENSE-MIT new file mode 100644 index 00000000..5cc9371f --- /dev/null +++ b/solana/bridge/memmap2-rs/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2020 Evgeniy Reizner +Copyright (c) 2015 Dan Burkert + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/solana/bridge/memmap2-rs/README.md b/solana/bridge/memmap2-rs/README.md new file mode 100644 index 00000000..19667ded --- /dev/null +++ b/solana/bridge/memmap2-rs/README.md @@ -0,0 +1,3 @@ +This is a fork of https://github.com/RazrFalcon/memmap2-rs which implements stubs for all functions which is required +to make the client code compile to WASM. It uses the v0.3.0 code (which has stubs) but was adapted to the v0.1.0 API +which is used by Solana. \ No newline at end of file diff --git a/solana/bridge/memmap2-rs/src/lib.rs b/solana/bridge/memmap2-rs/src/lib.rs new file mode 100644 index 00000000..916b2beb --- /dev/null +++ b/solana/bridge/memmap2-rs/src/lib.rs @@ -0,0 +1,839 @@ +//! A cross-platform Rust API for memory mapped buffers. + +#![doc(html_root_url = "https://docs.rs/memmap2/0.3.0")] + + +mod stub; +use crate::stub::MmapInner; + +use std::fmt; +#[cfg(unix)] +use std::fs::File; +use std::io::{Error, ErrorKind, Result}; +use std::ops::{Deref, DerefMut}; +#[cfg(unix)] +use std::os::unix::io::AsRawFd; +use std::slice; +use std::usize; + + +pub struct MmapRawDescriptor(i32); + +pub trait MmapAsRawDesc { + fn as_raw_desc(&self) -> MmapRawDescriptor; +} + +#[cfg(unix)] +impl MmapAsRawDesc for &File { + fn as_raw_desc(&self) -> MmapRawDescriptor { + MmapRawDescriptor(self.as_raw_fd()) + } +} + + +/// A memory map builder, providing advanced options and flags for specifying memory map behavior. +/// +/// `MmapOptions` can be used to create an anonymous memory map using [`map_anon()`], or a +/// file-backed memory map using one of [`map()`], [`map_mut()`], [`map_exec()`], +/// [`map_copy()`], or [`map_copy_read_only()`]. +/// +/// ## Safety +/// +/// All file-backed memory map constructors are marked `unsafe` because of the potential for +/// *Undefined Behavior* (UB) using the map if the underlying file is subsequently modified, in or +/// out of process. Applications must consider the risk and take appropriate precautions when +/// using file-backed maps. Solutions such as file permissions, locks or process-private (e.g. +/// unlinked) files exist but are platform specific and limited. +/// +/// [`map_anon()`]: MmapOptions::map_anon() +/// [`map()`]: MmapOptions::map() +/// [`map_mut()`]: MmapOptions::map_mut() +/// [`map_exec()`]: MmapOptions::map_exec() +/// [`map_copy()`]: MmapOptions::map_copy() +/// [`map_copy_read_only()`]: MmapOptions::map_copy_read_only() +#[derive(Clone, Debug, Default)] +pub struct MmapOptions { + offset: u64, + len: Option, + stack: bool, + populate: bool, +} + +impl MmapOptions { + /// Creates a new set of options for configuring and creating a memory map. + /// + /// # Example + /// + /// ``` + /// use memmap2::{MmapMut, MmapOptions}; + /// # use std::io::Result; + /// + /// # fn main() -> Result<()> { + /// // Create a new memory map builder. + /// let mut mmap_options = MmapOptions::new(); + /// + /// // Configure the memory map builder using option setters, then create + /// // a memory map using one of `mmap_options.map_anon`, `mmap_options.map`, + /// // `mmap_options.map_mut`, `mmap_options.map_exec`, or `mmap_options.map_copy`: + /// let mut mmap: MmapMut = mmap_options.len(36).map_anon()?; + /// + /// // Use the memory map: + /// mmap.copy_from_slice(b"...data to copy to the memory map..."); + /// # Ok(()) + /// # } + /// ``` + pub fn new() -> MmapOptions { + MmapOptions::default() + } + + /// Configures the memory map to start at byte `offset` from the beginning of the file. + /// + /// This option has no effect on anonymous memory maps. + /// + /// By default, the offset is 0. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// + /// # fn main() -> std::io::Result<()> { + /// let mmap = unsafe { + /// MmapOptions::new() + /// .offset(30) + /// .map(&File::open("LICENSE-APACHE")?)? + /// }; + /// assert_eq!(&b"Apache License"[..], + /// &mmap[..14]); + /// # Ok(()) + /// # } + /// ``` + pub fn offset(&mut self, offset: u64) -> &mut Self { + self.offset = offset; + self + } + + /// Configures the created memory mapped buffer to be `len` bytes long. + /// + /// This option is mandatory for anonymous memory maps. + /// + /// For file-backed memory maps, the length will default to the file length. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// + /// # fn main() -> std::io::Result<()> { + /// let mmap = unsafe { + /// MmapOptions::new() + /// .len(9) + /// .map(&File::open("README.md")?)? + /// }; + /// assert_eq!(&b"# memmap2"[..], &mmap[..]); + /// # Ok(()) + /// # } + /// ``` + pub fn len(&mut self, len: usize) -> &mut Self { + self.len = Some(len); + self + } + + /// Returns the configured length, or the length of the provided file. + fn get_len(&self, _file: &T) -> Result { + self.len.map(Ok).unwrap_or_else(|| { + let file_len = 0; + let len = file_len as u64 - self.offset; + if len > (usize::MAX as u64) { + return Err(Error::new( + ErrorKind::InvalidData, + "memory map length overflows usize", + )); + } + Ok(len as usize) + }) + } + + /// Configures the anonymous memory map to be suitable for a process or thread stack. + /// + /// This option corresponds to the `MAP_STACK` flag on Linux. It has no effect on Windows. + /// + /// This option has no effect on file-backed memory maps. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// + /// # fn main() -> std::io::Result<()> { + /// let stack = MmapOptions::new().stack().len(4096).map_anon(); + /// # Ok(()) + /// # } + /// ``` + pub fn stack(&mut self) -> &mut Self { + self.stack = true; + self + } + + /// Populate (prefault) page tables for a mapping. + /// + /// For a file mapping, this causes read-ahead on the file. This will help to reduce blocking on page faults later. + /// + /// This option corresponds to the `MAP_POPULATE` flag on Linux. It has no effect on Windows. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// + /// # fn main() -> std::io::Result<()> { + /// let file = File::open("LICENSE-MIT")?; + /// + /// let mmap = unsafe { + /// MmapOptions::new().populate().map(&file)? + /// }; + /// + /// assert_eq!(&b"Copyright"[..], &mmap[..9]); + /// # Ok(()) + /// # } + /// ``` + pub fn populate(&mut self) -> &mut Self { + self.populate = true; + self + } + + /// Creates a read-only memory map backed by a file. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read permissions. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// use std::io::Read; + /// + /// # fn main() -> std::io::Result<()> { + /// let mut file = File::open("LICENSE-APACHE")?; + /// + /// let mut contents = Vec::new(); + /// file.read_to_end(&mut contents)?; + /// + /// let mmap = unsafe { + /// MmapOptions::new().map(&file)? + /// }; + /// + /// assert_eq!(&contents[..], &mmap[..]); + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| Mmap { inner }) + } + + /// Creates a readable and executable memory map backed by a file. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read permissions. + pub unsafe fn map_exec(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map_exec(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| Mmap { inner: inner }) + } + + /// Creates a writeable memory map backed by a file. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read and write permissions. + /// + /// # Example + /// + /// ``` + /// # extern crate memmap2; + /// # extern crate tempdir; + /// # + /// use std::fs::OpenOptions; + /// use std::path::PathBuf; + /// + /// use memmap2::MmapOptions; + /// # + /// # fn main() -> std::io::Result<()> { + /// # let tempdir = tempdir::TempDir::new("mmap")?; + /// let path: PathBuf = /* path to file */ + /// # tempdir.path().join("map_mut"); + /// let file = OpenOptions::new().read(true).write(true).create(true).open(&path)?; + /// file.set_len(13)?; + /// + /// let mut mmap = unsafe { + /// MmapOptions::new().map_mut(&file)? + /// }; + /// + /// mmap.copy_from_slice(b"Hello, world!"); + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map_mut(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map_mut(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| MmapMut { inner: inner }) + } + + /// Creates a copy-on-write memory map backed by a file. + /// + /// Data written to the memory map will not be visible by other processes, + /// and will not be carried through to the underlying file. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with writable permissions. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// use std::io::Write; + /// + /// # fn main() -> std::io::Result<()> { + /// let file = File::open("LICENSE-APACHE")?; + /// let mut mmap = unsafe { MmapOptions::new().map_copy(&file)? }; + /// (&mut mmap[..]).write_all(b"Hello, world!")?; + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map_copy(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map_copy(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| MmapMut { inner: inner }) + } + + /// Creates a copy-on-write read-only memory map backed by a file. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read permissions. + /// + /// # Example + /// + /// ``` + /// use memmap2::MmapOptions; + /// use std::fs::File; + /// use std::io::Read; + /// + /// # fn main() -> std::io::Result<()> { + /// let mut file = File::open("README.md")?; + /// + /// let mut contents = Vec::new(); + /// file.read_to_end(&mut contents)?; + /// + /// let mmap = unsafe { + /// MmapOptions::new().map_copy_read_only(&file)? + /// }; + /// + /// assert_eq!(&contents[..], &mmap[..]); + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map_copy_read_only(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map_copy_read_only(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| Mmap { inner: inner }) + } + + /// Creates an anonymous memory map. + /// + /// Note: the memory map length must be configured to be greater than 0 before creating an + /// anonymous memory map using `MmapOptions::len()`. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails. + pub fn map_anon(&self) -> Result { + MmapInner::map_anon(self.len.unwrap_or(0), self.stack).map(|inner| MmapMut { inner }) + } + + /// Creates a raw memory map. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read and write permissions. + pub fn map_raw(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map_mut(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| MmapRaw { inner: inner }) + } +} + +/// A handle to an immutable memory mapped buffer. +/// +/// A `Mmap` may be backed by a file, or it can be anonymous map, backed by volatile memory. Use +/// [`MmapOptions`] or [`map()`] to create a file-backed memory map. To create an immutable +/// anonymous memory map, first create a mutable anonymous memory map, and then make it immutable +/// with [`MmapMut::make_read_only()`]. +/// +/// A file backed `Mmap` is created by `&File` reference, and will remain valid even after the +/// `File` is dropped. In other words, the `Mmap` handle is completely independent of the `File` +/// used to create it. For consistency, on some platforms this is achieved by duplicating the +/// underlying file handle. The memory will be unmapped when the `Mmap` handle is dropped. +/// +/// Dereferencing and accessing the bytes of the buffer may result in page faults (e.g. swapping +/// the mapped pages into physical memory) though the details of this are platform specific. +/// +/// `Mmap` is [`Sync`](std::marker::Sync) and [`Send`](std::marker::Send). +/// +/// ## Safety +/// +/// All file-backed memory map constructors are marked `unsafe` because of the potential for +/// *Undefined Behavior* (UB) using the map if the underlying file is subsequently modified, in or +/// out of process. Applications must consider the risk and take appropriate precautions when using +/// file-backed maps. Solutions such as file permissions, locks or process-private (e.g. unlinked) +/// files exist but are platform specific and limited. +/// +/// ## Example +/// +/// ``` +/// use memmap2::MmapOptions; +/// use std::io::Write; +/// use std::fs::File; +/// +/// # fn main() -> std::io::Result<()> { +/// let file = File::open("README.md")?; +/// let mmap = unsafe { MmapOptions::new().map(&file)? }; +/// assert_eq!(b"# memmap2", &mmap[0..9]); +/// # Ok(()) +/// # } +/// ``` +/// +/// See [`MmapMut`] for the mutable version. +/// +/// [`map()`]: Mmap::map() +pub struct Mmap { + inner: MmapInner, +} + +impl Mmap { + /// Creates a read-only memory map backed by a file. + /// + /// This is equivalent to calling `MmapOptions::new().map(file)`. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read permissions. + /// + /// # Example + /// + /// ``` + /// use std::fs::File; + /// use std::io::Read; + /// + /// use memmap2::Mmap; + /// + /// # fn main() -> std::io::Result<()> { + /// let mut file = File::open("LICENSE-APACHE")?; + /// + /// let mut contents = Vec::new(); + /// file.read_to_end(&mut contents)?; + /// + /// let mmap = unsafe { Mmap::map(&file)? }; + /// + /// assert_eq!(&contents[..], &mmap[..]); + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map(file: T) -> Result { + MmapOptions::new().map(file) + } + + /// Transition the memory map to be writable. + /// + /// If the memory map is file-backed, the file must have been opened with write permissions. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with writable permissions. + /// + /// # Example + /// + /// ``` + /// # extern crate memmap2; + /// # extern crate tempdir; + /// # + /// use memmap2::Mmap; + /// use std::ops::DerefMut; + /// use std::io::Write; + /// # use std::fs::OpenOptions; + /// + /// # fn main() -> std::io::Result<()> { + /// # let tempdir = tempdir::TempDir::new("mmap")?; + /// let file = /* file opened with write permissions */ + /// # OpenOptions::new() + /// # .read(true) + /// # .write(true) + /// # .create(true) + /// # .open(tempdir.path() + /// # .join("make_mut"))?; + /// # file.set_len(128)?; + /// let mmap = unsafe { Mmap::map(&file)? }; + /// // ... use the read-only memory map ... + /// let mut mut_mmap = mmap.make_mut()?; + /// mut_mmap.deref_mut().write_all(b"hello, world!")?; + /// # Ok(()) + /// # } + /// ``` + pub fn make_mut(mut self) -> Result { + self.inner.make_mut()?; + Ok(MmapMut { inner: self.inner }) + } +} + +impl Deref for Mmap { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.inner.ptr(), self.inner.len()) } + } +} + +impl AsRef<[u8]> for Mmap { + #[inline] + fn as_ref(&self) -> &[u8] { + self.deref() + } +} + +impl fmt::Debug for Mmap { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("Mmap") + .field("ptr", &self.as_ptr()) + .field("len", &self.len()) + .finish() + } +} + +/// A handle to a raw memory mapped buffer. +/// +/// This struct never hands out references to its interior, only raw pointers. +/// This can be helpful when creating shared memory maps between untrusted processes. +pub struct MmapRaw { + inner: MmapInner, +} + +impl MmapRaw { + /// Creates a writeable memory map backed by a file. + /// + /// This is equivalent to calling `MmapOptions::new().map_raw(file)`. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read and write permissions. + pub fn map_raw(file: T) -> Result { + MmapOptions::new().map_raw(file) + } + + /// Returns a raw pointer to the memory mapped file. + /// + /// Before dereferencing this pointer, you have to make sure that the file has not been + /// truncated since the memory map was created. + /// Avoiding this will not introduce memory safety issues in Rust terms, + /// but will cause SIGBUS (or equivalent) signal. + #[inline] + pub fn as_ptr(&self) -> *const u8 { + self.inner.ptr() + } + + /// Returns an unsafe mutable pointer to the memory mapped file. + /// + /// Before dereferencing this pointer, you have to make sure that the file has not been + /// truncated since the memory map was created. + /// Avoiding this will not introduce memory safety issues in Rust terms, + /// but will cause SIGBUS (or equivalent) signal. + #[inline] + pub fn as_mut_ptr(&self) -> *mut u8 { + self.inner.ptr() as _ + } + + /// Returns the length in bytes of the memory map. + /// + /// Note that truncating the file can cause the length to change (and render this value unusable). + #[inline] + pub fn len(&self) -> usize { + self.inner.len() + } +} + +impl fmt::Debug for MmapRaw { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("MmapRaw") + .field("ptr", &self.as_ptr()) + .field("len", &self.len()) + .finish() + } +} + +/// A handle to a mutable memory mapped buffer. +/// +/// A file-backed `MmapMut` buffer may be used to read from or write to a file. An anonymous +/// `MmapMut` buffer may be used any place that an in-memory byte buffer is needed. Use +/// [`MmapMut::map_mut()`] and [`MmapMut::map_anon()`] to create a mutable memory map of the +/// respective types, or [`MmapOptions::map_mut()`] and [`MmapOptions::map_anon()`] if non-default +/// options are required. +/// +/// A file backed `MmapMut` is created by `&File` reference, and will remain valid even after the +/// `File` is dropped. In other words, the `MmapMut` handle is completely independent of the `File` +/// used to create it. For consistency, on some platforms this is achieved by duplicating the +/// underlying file handle. The memory will be unmapped when the `MmapMut` handle is dropped. +/// +/// Dereferencing and accessing the bytes of the buffer may result in page faults (e.g. swapping +/// the mapped pages into physical memory) though the details of this are platform specific. +/// +/// `Mmap` is [`Sync`](std::marker::Sync) and [`Send`](std::marker::Send). +/// +/// See [`Mmap`] for the immutable version. +/// +/// ## Safety +/// +/// All file-backed memory map constructors are marked `unsafe` because of the potential for +/// *Undefined Behavior* (UB) using the map if the underlying file is subsequently modified, in or +/// out of process. Applications must consider the risk and take appropriate precautions when using +/// file-backed maps. Solutions such as file permissions, locks or process-private (e.g. unlinked) +/// files exist but are platform specific and limited. +pub struct MmapMut { + inner: MmapInner, +} + +impl MmapMut { + /// Creates a writeable memory map backed by a file. + /// + /// This is equivalent to calling `MmapOptions::new().map_mut(file)`. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file is not open with read and write permissions. + /// + /// # Example + /// + /// ``` + /// # extern crate memmap2; + /// # extern crate tempdir; + /// # + /// use std::fs::OpenOptions; + /// use std::path::PathBuf; + /// + /// use memmap2::MmapMut; + /// # + /// # fn main() -> std::io::Result<()> { + /// # let tempdir = tempdir::TempDir::new("mmap")?; + /// let path: PathBuf = /* path to file */ + /// # tempdir.path().join("map_mut"); + /// let file = OpenOptions::new() + /// .read(true) + /// .write(true) + /// .create(true) + /// .open(&path)?; + /// file.set_len(13)?; + /// + /// let mut mmap = unsafe { MmapMut::map_mut(&file)? }; + /// + /// mmap.copy_from_slice(b"Hello, world!"); + /// # Ok(()) + /// # } + /// ``` + pub unsafe fn map_mut(file: T) -> Result { + MmapOptions::new().map_mut(file) + } + + /// Creates an anonymous memory map. + /// + /// This is equivalent to calling `MmapOptions::new().len(length).map_anon()`. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails. + pub fn map_anon(length: usize) -> Result { + MmapOptions::new().len(length).map_anon() + } + + /// Flushes outstanding memory map modifications to disk. + /// + /// When this method returns with a non-error result, all outstanding changes to a file-backed + /// memory map are guaranteed to be durably stored. The file's metadata (including last + /// modification timestamp) may not be updated. + /// + /// # Example + /// + /// ``` + /// # extern crate memmap2; + /// # extern crate tempdir; + /// # + /// use std::fs::OpenOptions; + /// use std::io::Write; + /// use std::path::PathBuf; + /// + /// use memmap2::MmapMut; + /// + /// # fn main() -> std::io::Result<()> { + /// # let tempdir = tempdir::TempDir::new("mmap")?; + /// let path: PathBuf = /* path to file */ + /// # tempdir.path().join("flush"); + /// let file = OpenOptions::new().read(true).write(true).create(true).open(&path)?; + /// file.set_len(128)?; + /// + /// let mut mmap = unsafe { MmapMut::map_mut(&file)? }; + /// + /// (&mut mmap[..]).write_all(b"Hello, world!")?; + /// mmap.flush()?; + /// # Ok(()) + /// # } + /// ``` + pub fn flush(&self) -> Result<()> { + let len = self.len(); + self.inner.flush(0, len) + } + + /// Asynchronously flushes outstanding memory map modifications to disk. + /// + /// This method initiates flushing modified pages to durable storage, but it will not wait for + /// the operation to complete before returning. The file's metadata (including last + /// modification timestamp) may not be updated. + pub fn flush_async(&self) -> Result<()> { + let len = self.len(); + self.inner.flush_async(0, len) + } + + /// Flushes outstanding memory map modifications in the range to disk. + /// + /// The offset and length must be in the bounds of the memory map. + /// + /// When this method returns with a non-error result, all outstanding changes to a file-backed + /// memory in the range are guaranteed to be durable stored. The file's metadata (including + /// last modification timestamp) may not be updated. It is not guaranteed the only the changes + /// in the specified range are flushed; other outstanding changes to the memory map may be + /// flushed as well. + pub fn flush_range(&self, offset: usize, len: usize) -> Result<()> { + self.inner.flush(offset, len) + } + + /// Asynchronously flushes outstanding memory map modifications in the range to disk. + /// + /// The offset and length must be in the bounds of the memory map. + /// + /// This method initiates flushing modified pages to durable storage, but it will not wait for + /// the operation to complete before returning. The file's metadata (including last + /// modification timestamp) may not be updated. It is not guaranteed that the only changes + /// flushed are those in the specified range; other outstanding changes to the memory map may + /// be flushed as well. + pub fn flush_async_range(&self, offset: usize, len: usize) -> Result<()> { + self.inner.flush_async(offset, len) + } + + /// Returns an immutable version of this memory mapped buffer. + /// + /// If the memory map is file-backed, the file must have been opened with read permissions. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file has not been opened with read permissions. + /// + /// # Example + /// + /// ``` + /// # extern crate memmap2; + /// # + /// use std::io::Write; + /// use std::path::PathBuf; + /// + /// use memmap2::{Mmap, MmapMut}; + /// + /// # fn main() -> std::io::Result<()> { + /// let mut mmap = MmapMut::map_anon(128)?; + /// + /// (&mut mmap[..]).write(b"Hello, world!")?; + /// + /// let mmap: Mmap = mmap.make_read_only()?; + /// # Ok(()) + /// # } + /// ``` + pub fn make_read_only(mut self) -> Result { + self.inner.make_read_only()?; + Ok(Mmap { inner: self.inner }) + } + + /// Transition the memory map to be readable and executable. + /// + /// If the memory map is file-backed, the file must have been opened with execute permissions. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails, which can happen for a + /// variety of reasons, such as when the file has not been opened with execute permissions. + pub fn make_exec(mut self) -> Result { + self.inner.make_exec()?; + Ok(Mmap { inner: self.inner }) + } +} + +impl Deref for MmapMut { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.inner.ptr(), self.inner.len()) } + } +} + +impl DerefMut for MmapMut { + #[inline] + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.inner.mut_ptr(), self.inner.len()) } + } +} + +impl AsRef<[u8]> for MmapMut { + #[inline] + fn as_ref(&self) -> &[u8] { + self.deref() + } +} + +impl AsMut<[u8]> for MmapMut { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + self.deref_mut() + } +} + +impl fmt::Debug for MmapMut { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("MmapMut") + .field("ptr", &self.as_ptr()) + .field("len", &self.len()) + .finish() + } +} diff --git a/solana/bridge/memmap2-rs/src/stub.rs b/solana/bridge/memmap2-rs/src/stub.rs new file mode 100644 index 00000000..88f270b1 --- /dev/null +++ b/solana/bridge/memmap2-rs/src/stub.rs @@ -0,0 +1,75 @@ +use std::io; + +pub struct MmapInner { + // Private member to prevent external construction + // (might be nice to change the type to ! once that's stable) + __: (), +} + +impl MmapInner { + fn new() -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "platform not supported", + )) + } + + pub fn map(_: usize, _: i32, _: u64, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn map_exec(_: usize, _: i32, _: u64, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn map_mut(_: usize, _: i32, _: u64, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn map_copy(_: usize, _: i32, _: u64, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn map_copy_read_only(_: usize, _: i32, _: u64, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn map_anon(_: usize, _: bool) -> io::Result { + MmapInner::new() + } + + pub fn flush(&self, _: usize, _: usize) -> io::Result<()> { + unreachable!("self unconstructable"); + } + + pub fn flush_async(&self, _: usize, _: usize) -> io::Result<()> { + unreachable!("self unconstructable"); + } + + pub fn make_read_only(&mut self) -> io::Result<()> { + unreachable!("self unconstructable"); + } + + pub fn make_exec(&mut self) -> io::Result<()> { + unreachable!("self unconstructable"); + } + + pub fn make_mut(&mut self) -> io::Result<()> { + unreachable!("self unconstructable"); + } + + #[inline] + pub fn ptr(&self) -> *const u8 { + unreachable!("self unconstructable"); + } + + #[inline] + pub fn mut_ptr(&mut self) -> *mut u8 { + unreachable!("self unconstructable"); + } + + #[inline] + pub fn len(&self) -> usize { + unreachable!("self unconstructable"); + } +} diff --git a/solana/bridge/program/Cargo.toml b/solana/bridge/program/Cargo.toml index 4bbe0eec..cdec6e77 100644 --- a/solana/bridge/program/Cargo.toml +++ b/solana/bridge/program/Cargo.toml @@ -21,8 +21,10 @@ byteorder = "1.4.3" primitive-types = { version = "0.9.0", default-features = false } sha3 = "0.9.1" solana-program = "=1.7.0" -solitaire-client = { path = "../../solitaire/client", optional = true} -solitaire = { path = "../../solitaire/program"} +solitaire-client = { path = "../../solitaire/client", optional = true } +solitaire = { path = "../../solitaire/program" } +wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] } +serde = { version = "1.0", features = ["derive"] } [dev-dependencies] hex = "*" diff --git a/solana/bridge/program/src/instructions.rs b/solana/bridge/program/src/instructions.rs index d3729189..58ea206d 100644 --- a/solana/bridge/program/src/instructions.rs +++ b/solana/bridge/program/src/instructions.rs @@ -9,10 +9,19 @@ use solana_program::{ }; use std::str::FromStr; +use byteorder::{ + BigEndian, + WriteBytesExt, +}; +use sha3::Digest; use solitaire::{ processors::seeded::Seeded, AccountState, }; +use std::io::{ + Cursor, + Write, +}; use crate::{ accounts::{ @@ -398,15 +407,6 @@ pub fn transfer_fees( // Convert a full VAA structure into the serialization of its unique components, this structure is // what is hashed and verified by Guardians. pub fn serialize_vaa(vaa: &PostVAAData) -> Vec { - use byteorder::{ - BigEndian, - WriteBytesExt, - }; - use std::io::{ - Cursor, - Write, - }; - let mut v = Cursor::new(Vec::new()); v.write_u32::(vaa.timestamp).unwrap(); v.write_u32::(vaa.nonce).unwrap(); @@ -420,11 +420,8 @@ pub fn serialize_vaa(vaa: &PostVAAData) -> Vec { // Hash a VAA, this combines serialization and hashing. pub fn hash_vaa(vaa: &PostVAAData) -> [u8; 32] { - use sha3::Digest; - use std::io::Write; - let body = serialize_vaa(vaa); let mut h = sha3::Keccak256::default(); h.write(body.as_slice()).unwrap(); h.finalize().into() -} +} \ No newline at end of file diff --git a/solana/bridge/program/src/lib.rs b/solana/bridge/program/src/lib.rs index b9e1b972..5d04d8cb 100644 --- a/solana/bridge/program/src/lib.rs +++ b/solana/bridge/program/src/lib.rs @@ -11,6 +11,12 @@ pub mod vaa; #[cfg(feature = "no-entrypoint")] pub mod instructions; +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +extern crate wasm_bindgen; + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +pub mod wasm; + use solitaire::*; pub use api::{ diff --git a/solana/bridge/program/src/types.rs b/solana/bridge/program/src/types.rs index b5a64ead..eee3f676 100644 --- a/solana/bridge/program/src/types.rs +++ b/solana/bridge/program/src/types.rs @@ -36,8 +36,12 @@ use std::{ }, str::FromStr, }; +use serde::{ + Deserialize, + Serialize, +}; -#[derive(Default, BorshSerialize, BorshDeserialize)] +#[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)] pub struct GuardianSetData { /// Version number of this guardian set. pub index: u32, @@ -65,7 +69,7 @@ impl Owned for GuardianSetData { } } -#[derive(Default, BorshSerialize, BorshDeserialize)] +#[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)] pub struct BridgeConfig { /// Period for how long a guardian set is valid after it has been replaced by a new one. This /// guarantees that VAAs issued by that set can still be submitted for a certain period. In @@ -76,7 +80,7 @@ pub struct BridgeConfig { pub fee: u64, } -#[derive(Default, BorshSerialize, BorshDeserialize)] +#[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)] pub struct BridgeData { /// The current guardian set index, used to decide which signature sets to accept. pub guardian_set_index: u32, @@ -157,7 +161,7 @@ impl Clone for PostedMessage { } } -#[derive(Default, BorshSerialize, BorshDeserialize, Clone)] +#[derive(Default, BorshSerialize, BorshDeserialize, Clone, Serialize, Deserialize)] pub struct PostedMessageData { /// Header of the posted VAA pub vaa_version: u8, @@ -209,7 +213,7 @@ impl Owned for SequenceTracker { } } -#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize)] +#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize, Serialize, Deserialize)] pub struct ClaimData { pub claimed: bool, } @@ -233,8 +237,8 @@ impl SerializePayload for GovernancePayloadUpgrade { } impl DeserializePayload for GovernancePayloadUpgrade -where - Self: DeserializeGovernancePayload, + where + Self: DeserializeGovernancePayload, { fn deserialize(buf: &mut &[u8]) -> Result { let mut c = Cursor::new(buf); @@ -278,8 +282,8 @@ impl SerializePayload for GovernancePayloadGuardianSetChange { } impl DeserializePayload for GovernancePayloadGuardianSetChange -where - Self: DeserializeGovernancePayload, + where + Self: DeserializeGovernancePayload, { fn deserialize(buf: &mut &[u8]) -> Result { let mut c = Cursor::new(buf); @@ -326,8 +330,8 @@ impl SerializePayload for GovernancePayloadSetMessageFee { } impl DeserializePayload for GovernancePayloadSetMessageFee -where - Self: DeserializeGovernancePayload, + where + Self: DeserializeGovernancePayload, { fn deserialize(buf: &mut &[u8]) -> Result { let mut c = Cursor::new(buf); @@ -368,8 +372,8 @@ impl SerializePayload for GovernancePayloadTransferFees { } impl DeserializePayload for GovernancePayloadTransferFees -where - Self: DeserializeGovernancePayload, + where + Self: DeserializeGovernancePayload, { fn deserialize(buf: &mut &[u8]) -> Result { let mut c = Cursor::new(buf); @@ -395,7 +399,7 @@ impl DeserializeGovernancePayload for GovernancePayloadTransferFees { } #[repr(u8)] -#[derive(BorshSerialize, BorshDeserialize, Clone)] +#[derive(BorshSerialize, BorshDeserialize, Clone, Serialize, Deserialize)] pub enum ConsistencyLevel { Confirmed, Finalized, diff --git a/solana/bridge/program/src/vaa.rs b/solana/bridge/program/src/vaa.rs index d8676a19..e89f3e27 100644 --- a/solana/bridge/program/src/vaa.rs +++ b/solana/bridge/program/src/vaa.rs @@ -38,6 +38,8 @@ use std::{ }, ops::Deref, }; +use crate::api::ForeignAddress; +use serde::{Deserialize, Serialize}; pub trait SerializePayload: Sized { fn serialize(&self, writer: &mut W) -> std::result::Result<(), SolitaireError>; @@ -109,8 +111,8 @@ pub struct PayloadMessage<'b, T: DeserializePayload>( impl<'a, 'b: 'a, 'c, T: DeserializePayload> Peel<'a, 'b, 'c> for PayloadMessage<'b, T> { fn peel(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result - where - Self: Sized, + where + Self: Sized, { // Deserialize wrapped payload let data: Data<'b, PostedMessage, { AccountState::Initialized }> = Data::peel(ctx)?; @@ -201,3 +203,73 @@ impl<'b, T: DeserializePayload> ClaimableVAA<'b, T> { Ok(()) } } + +pub struct SignatureItem { + pub signature: Vec, + pub key: [u8; 20], + pub index: u8, +} + +#[derive(Serialize, Deserialize, Default)] +pub struct VAASignature { + pub signature: Vec, + pub guardian_index: u8, +} + +#[derive(Serialize, Deserialize, Default)] +pub struct VAA { + // Header part + pub version: u8, + pub guardian_set_index: u32, + pub signatures: Vec, + // Body part + pub timestamp: u32, + pub nonce: u32, + pub emitter_chain: u16, + pub emitter_address: ForeignAddress, + pub sequence: u64, + pub consistency_level: u8, + pub payload: Vec, +} + +impl VAA { + pub const HEADER_LEN: usize = 6; + pub const SIGNATURE_LEN: usize = 66; + + pub fn deserialize(data: &[u8]) -> std::result::Result { + let mut rdr = Cursor::new(data); + let mut v = VAA::default(); + + v.version = rdr.read_u8()?; + v.guardian_set_index = rdr.read_u32::()?; + + let len_sig = rdr.read_u8()?; + let mut sigs: Vec = Vec::with_capacity(len_sig as usize); + for _i in 0..len_sig { + let mut sig = VAASignature::default(); + + sig.guardian_index = rdr.read_u8()?; + let mut signature_data = [0u8; 65]; + rdr.read_exact(&mut signature_data)?; + sig.signature = signature_data.to_vec(); + + sigs.push(sig); + } + v.signatures = sigs; + + v.timestamp = rdr.read_u32::()?; + v.nonce = rdr.read_u32::()?; + v.emitter_chain = rdr.read_u16::()?; + + let mut emitter_address = [0u8; 32]; + rdr.read_exact(&mut emitter_address)?; + v.emitter_address = emitter_address; + + v.sequence = rdr.read_u64::()?; + v.consistency_level = rdr.read_u8()?; + + rdr.read_to_end(&mut v.payload)?; + + Ok(v) + } +} \ No newline at end of file diff --git a/solana/bridge/program/src/wasm.rs b/solana/bridge/program/src/wasm.rs new file mode 100644 index 00000000..c88b015f --- /dev/null +++ b/solana/bridge/program/src/wasm.rs @@ -0,0 +1,400 @@ +use solana_program::{ + instruction::Instruction, + pubkey::Pubkey, +}; +use std::str::FromStr; + +use crate::vaa::{ + DeserializePayload, + SignatureItem, + VAA, +}; +use borsh::BorshDeserialize; +use byteorder::WriteBytesExt; +use sha3::Digest; +use solitaire::{ + processors::seeded::Seeded, + AccountState, +}; +use std::io::Write; + +use crate::{ + accounts::{ + GuardianSet, + GuardianSetDerivationData, + Message, + MessageDerivationData, + }, + types::ConsistencyLevel, + PostVAAData, + VerifySignaturesData, +}; + +use crate::{ + accounts::{ + Bridge, + FeeCollector, + }, + instructions::{ + post_message, + post_vaa, + set_fees, + transfer_fees, + upgrade_contract, + upgrade_guardian_set, + verify_signatures, + }, + types::{ + BridgeData, + GovernancePayloadGuardianSetChange, + GovernancePayloadTransferFees, + GovernancePayloadUpgrade, + GuardianSetData, + PostedMessage, + }, +}; +use byteorder::LittleEndian; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn post_message_ix( + program_id: String, + payer: String, + emitter: String, + nonce: u32, + msg: Vec, + consistency: String, +) -> JsValue { + let consistency_level = match consistency.as_str() { + "CONFIRMED" => ConsistencyLevel::Confirmed, + "FINALIZED" => ConsistencyLevel::Finalized, + _ => panic!("invalid consistency level"), + }; + let (_, ix) = post_message( + Pubkey::from_str(program_id.as_str()).unwrap(), + Pubkey::from_str(payer.as_str()).unwrap(), + Pubkey::from_str(emitter.as_str()).unwrap(), + nonce, + msg, + consistency_level, + ) + .unwrap(); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn post_vaa_ix( + program_id: String, + payer: String, + signature_set: String, + vaa: Vec, +) -> JsValue { + let vaa = VAA::deserialize(vaa.as_slice()).unwrap(); + let vaa = PostVAAData { + version: vaa.version, + guardian_set_index: vaa.guardian_set_index, + timestamp: vaa.timestamp, + nonce: vaa.nonce, + emitter_chain: vaa.emitter_chain, + emitter_address: vaa.emitter_address, + sequence: vaa.sequence, + consistency_level: vaa.consistency_level, + payload: vaa.payload, + }; + let ix = post_vaa( + Pubkey::from_str(program_id.as_str()).unwrap(), + Pubkey::from_str(payer.as_str()).unwrap(), + Pubkey::from_str(signature_set.as_str()).unwrap(), + vaa, + ); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn update_guardian_set_ix(program_id: String, payer: String, vaa: Vec) -> JsValue { + let program_id = Pubkey::from_str(program_id.as_str()).unwrap(); + let vaa = VAA::deserialize(vaa.as_slice()).unwrap(); + let payload = + GovernancePayloadGuardianSetChange::deserialize(&mut vaa.payload.as_slice()).unwrap(); + let message_key = Message::<'_, { AccountState::Uninitialized }>::key( + &MessageDerivationData { + emitter_key: vaa.emitter_address, + emitter_chain: vaa.emitter_chain, + nonce: vaa.nonce, + payload: vaa.payload, + sequence: None, + }, + &program_id, + ); + let ix = upgrade_guardian_set( + program_id, + Pubkey::from_str(payer.as_str()).unwrap(), + message_key, + Pubkey::new(&vaa.emitter_address), + payload.new_guardian_set_index - 1, + payload.new_guardian_set_index, + vaa.sequence, + ); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn set_fees_ix(program_id: String, payer: String, vaa: Vec) -> JsValue { + let program_id = Pubkey::from_str(program_id.as_str()).unwrap(); + let vaa = VAA::deserialize(vaa.as_slice()).unwrap(); + let message_key = Message::<'_, { AccountState::Uninitialized }>::key( + &MessageDerivationData { + emitter_key: vaa.emitter_address, + emitter_chain: vaa.emitter_chain, + nonce: vaa.nonce, + payload: vaa.payload, + sequence: None, + }, + &program_id, + ); + let ix = set_fees( + program_id, + Pubkey::from_str(payer.as_str()).unwrap(), + message_key, + Pubkey::new(&vaa.emitter_address), + vaa.sequence, + ); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn transfer_fees_ix(program_id: String, payer: String, vaa: Vec) -> JsValue { + let program_id = Pubkey::from_str(program_id.as_str()).unwrap(); + let vaa = VAA::deserialize(vaa.as_slice()).unwrap(); + let payload = GovernancePayloadTransferFees::deserialize(&mut vaa.payload.as_slice()).unwrap(); + let message_key = Message::<'_, { AccountState::Uninitialized }>::key( + &MessageDerivationData { + emitter_key: vaa.emitter_address, + emitter_chain: vaa.emitter_chain, + nonce: vaa.nonce, + payload: vaa.payload, + sequence: None, + }, + &program_id, + ); + let ix = transfer_fees( + program_id, + Pubkey::from_str(payer.as_str()).unwrap(), + message_key, + Pubkey::new(&vaa.emitter_address), + vaa.sequence, + Pubkey::new(&payload.to[..]), + ); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn upgrade_contract_ix( + program_id: String, + payer: String, + spill: String, + vaa: Vec, +) -> JsValue { + let program_id = Pubkey::from_str(program_id.as_str()).unwrap(); + let spill = Pubkey::from_str(spill.as_str()).unwrap(); + let vaa = VAA::deserialize(vaa.as_slice()).unwrap(); + let payload = GovernancePayloadUpgrade::deserialize(&mut vaa.payload.as_slice()).unwrap(); + let message_key = Message::<'_, { AccountState::Uninitialized }>::key( + &MessageDerivationData { + emitter_key: vaa.emitter_address, + emitter_chain: vaa.emitter_chain, + nonce: vaa.nonce, + payload: vaa.payload, + sequence: None, + }, + &program_id, + ); + let ix = upgrade_contract( + program_id, + Pubkey::from_str(payer.as_str()).unwrap(), + message_key, + Pubkey::new(&vaa.emitter_address), + payload.new_contract, + spill, + vaa.sequence, + ); + return JsValue::from_serde(&ix).unwrap(); +} + +#[wasm_bindgen] +pub fn verify_signatures_ix( + program_id: String, + payer: String, + guardian_set_index: u32, + guardian_set: JsValue, + signature_set: String, + vaa_data: Vec, +) -> JsValue { + let program_id = Pubkey::from_str(program_id.as_str()).unwrap(); + let payer = Pubkey::from_str(payer.as_str()).unwrap(); + let signature_set = Pubkey::from_str(signature_set.as_str()).unwrap(); + + let guardian_set: GuardianSetData = guardian_set.into_serde().unwrap(); + let vaa = VAA::deserialize(vaa_data.as_slice()).unwrap(); + + // Map signatures to guardian set + let mut signature_items: Vec = Vec::new(); + for s in vaa.signatures.iter() { + let mut item = SignatureItem { + signature: s.signature.clone(), + key: [0; 20], + index: s.guardian_index as u8, + }; + item.key = guardian_set.keys[s.guardian_index as usize]; + + signature_items.push(item); + } + + let vaa_body = &vaa_data[VAA::HEADER_LEN + VAA::SIGNATURE_LEN * vaa.signatures.len()..]; + let body_hash: [u8; 32] = { + let mut h = sha3::Keccak256::default(); + h.write(vaa_body).unwrap(); + h.finalize().into() + }; + + let mut verify_txs: Vec> = Vec::new(); + for (_tx_index, chunk) in signature_items.chunks(6).enumerate() { + let mut secp_payload = Vec::new(); + let mut signature_status = [-1i8; 19]; + + let data_offset = 1 + chunk.len() * 11; + let message_offset = data_offset + chunk.len() * 85; + + // 1 number of signatures + secp_payload.write_u8(chunk.len() as u8).unwrap(); + + // Secp signature info description (11 bytes * n) + for (i, s) in chunk.iter().enumerate() { + secp_payload + .write_u16::((data_offset + 85 * i) as u16) + .unwrap(); + secp_payload.write_u8(0).unwrap(); + secp_payload + .write_u16::((data_offset + 85 * i + 65) as u16) + .unwrap(); + secp_payload.write_u8(0).unwrap(); + secp_payload + .write_u16::(message_offset as u16) + .unwrap(); + secp_payload + .write_u16::(body_hash.len() as u16) + .unwrap(); + secp_payload.write_u8(0).unwrap(); + signature_status[s.index as usize] = i as i8; + } + + // Write signatures and addresses + for s in chunk.iter() { + secp_payload.write(&s.signature).unwrap(); + secp_payload.write(&s.key).unwrap(); + } + + // Write body + secp_payload.write(&body_hash).unwrap(); + + let secp_ix = Instruction { + program_id: solana_program::secp256k1_program::id(), + data: secp_payload, + accounts: vec![], + }; + + let payload = VerifySignaturesData { + signers: signature_status, + }; + + let verify_ix = match verify_signatures( + program_id, + payer, + guardian_set_index, + signature_set, + payload, + ) { + Ok(v) => v, + Err(e) => panic!("{:?}", e), + }; + + verify_txs.push(vec![secp_ix, verify_ix]) + } + + JsValue::from_serde(&verify_txs).unwrap() +} + +#[wasm_bindgen] +pub fn guardian_set_address(bridge: String, index: u32) -> Vec { + let program_id = Pubkey::from_str(bridge.as_str()).unwrap(); + let guardian_key = GuardianSet::<'_, { AccountState::Initialized }>::key( + &GuardianSetDerivationData { index: index }, + &program_id, + ); + + guardian_key.to_bytes().to_vec() +} + +#[wasm_bindgen] +pub fn parse_guardian_set(data: Vec) -> JsValue { + JsValue::from_serde(&GuardianSetData::try_from_slice(data.as_slice()).unwrap()).unwrap() +} + +#[wasm_bindgen] +pub fn state_address(bridge: String) -> Vec { + let program_id = Pubkey::from_str(bridge.as_str()).unwrap(); + let bridge_key = Bridge::<'_, { AccountState::Initialized }>::key(None, &program_id); + + bridge_key.to_bytes().to_vec() +} + +#[wasm_bindgen] +pub fn parse_state(data: Vec) -> JsValue { + JsValue::from_serde(&BridgeData::try_from_slice(data.as_slice()).unwrap()).unwrap() +} + +#[wasm_bindgen] +pub fn fee_collector_address(bridge: String) -> Vec { + let program_id = Pubkey::from_str(bridge.as_str()).unwrap(); + let bridge_key = FeeCollector::key(None, &program_id); + + bridge_key.to_bytes().to_vec() +} + +#[wasm_bindgen] +pub fn posted_message_address( + bridge: String, + emitter_key: Vec, + emitter_chain: u16, + nonce: u32, + payload: Vec, + sequence: Option, +) -> Vec { + let program_id = Pubkey::from_str(bridge.as_str()).unwrap(); + + let mut ek = [0u8; 32]; + ek.copy_from_slice(emitter_key.as_slice()); + + let message_key = Message::<'_, { AccountState::Initialized }>::key( + &MessageDerivationData { + emitter_key: ek, + emitter_chain, + nonce, + payload, + sequence, + }, + &program_id, + ); + + message_key.to_bytes().to_vec() +} + +#[wasm_bindgen] +pub fn parse_posted_message(data: Vec) -> JsValue { + JsValue::from_serde(&PostedMessage::try_from_slice(data.as_slice()).unwrap().0).unwrap() +} + +#[wasm_bindgen] +pub fn parse_vaa(data: Vec) -> JsValue { + JsValue::from_serde(&VAA::deserialize(data.as_slice()).unwrap()).unwrap() +} diff --git a/solana/modules/token_bridge/Cargo.lock b/solana/modules/token_bridge/Cargo.lock index 6ef94e6b..248b56c3 100644 --- a/solana/modules/token_bridge/Cargo.lock +++ b/solana/modules/token_bridge/Cargo.lock @@ -251,9 +251,11 @@ dependencies = [ "borsh", "byteorder", "primitive-types", + "serde", "sha3", "solana-program", "solitaire", + "wasm-bindgen", ] [[package]] diff --git a/solana/solitaire/Cargo.lock b/solana/solitaire/Cargo.lock index 193ba902..9d15ff86 100644 --- a/solana/solitaire/Cargo.lock +++ b/solana/solitaire/Cargo.lock @@ -163,7 +163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a7111f797cc721407885a323fb071636aee57f750b1a4ddc27397eba168a74" dependencies = [ "borsh-derive", - "hashbrown", + "hashbrown 0.9.1", ] [[package]] @@ -459,9 +459,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0860415b12243916284c67a9be413e044ee6668247b99ba26d94b2bc06c8f6" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" dependencies = [ "serde", "signature", @@ -711,7 +711,7 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-util", "tracing", ] @@ -725,6 +725,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "hermit-abi" version = "0.1.18" @@ -823,9 +829,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.9" +version = "0.14.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" +checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" dependencies = [ "bytes 1.0.1", "futures-channel", @@ -839,7 +845,7 @@ dependencies = [ "itoa", "pin-project-lite", "socket2", - "tokio 1.7.1", + "tokio 1.9.0", "tower-service", "tracing", "want", @@ -855,7 +861,7 @@ dependencies = [ "hyper", "log", "rustls", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-rustls", "webpki", ] @@ -873,12 +879,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.11.2", ] [[package]] @@ -1240,9 +1246,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -1394,9 +1400,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "reqwest" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" +checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" dependencies = [ "base64", "bytes 1.0.1", @@ -1418,7 +1424,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "tokio 1.7.1", + "tokio 1.9.0", "tokio-rustls", "url", "wasm-bindgen", @@ -1617,9 +1623,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" [[package]] name = "slab" @@ -1925,9 +1931,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" dependencies = [ "tinyvec_macros", ] @@ -1964,9 +1970,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.7.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" +checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" dependencies = [ "autocfg", "bytes 1.0.1", @@ -2057,7 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ "rustls", - "tokio 1.7.1", + "tokio 1.9.0", "webpki", ] @@ -2158,7 +2164,7 @@ dependencies = [ "futures-sink", "log", "pin-project-lite", - "tokio 1.7.1", + "tokio 1.9.0", ] [[package]]