From d20099a3c65a4400ad0055999f7b741295abf447 Mon Sep 17 00:00:00 2001 From: guibescos <59208140+guibescos@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:33:55 -0500 Subject: [PATCH] Guibescos/executor (#283) * Start anchor program * pythnet folder * Renames * Implement processor * Comments * More comments * Bump anchor * Use new version of the wormhole package * Get Solana chain id from wormhole core * Pythnet bridge address * Remove comment * Fix borsh headers --- pythnet/remote-executor/Cargo.lock | 478 +++++++++++++----- .../programs/remote-executor/Cargo.toml | 4 +- .../programs/remote-executor/src/error.rs | 12 + .../programs/remote-executor/src/lib.rs | 50 +- .../remote-executor/src/state/claim_record.rs | 10 + .../src/state/governance_payload.rs | 125 +++++ .../programs/remote-executor/src/state/mod.rs | 3 + .../remote-executor/src/state/posted_vaa.rs | 43 ++ 8 files changed, 588 insertions(+), 137 deletions(-) create mode 100644 pythnet/remote-executor/programs/remote-executor/src/error.rs create mode 100644 pythnet/remote-executor/programs/remote-executor/src/state/claim_record.rs create mode 100644 pythnet/remote-executor/programs/remote-executor/src/state/governance_payload.rs create mode 100644 pythnet/remote-executor/programs/remote-executor/src/state/mod.rs create mode 100644 pythnet/remote-executor/programs/remote-executor/src/state/posted_vaa.rs diff --git a/pythnet/remote-executor/Cargo.lock b/pythnet/remote-executor/Cargo.lock index 9dfd2a8d..0c415bcd 100644 --- a/pythnet/remote-executor/Cargo.lock +++ b/pythnet/remote-executor/Cargo.lock @@ -24,9 +24,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b75d05b6b4ac9d95bb6e3b786b27d3a708c4c5a87c92ffaa25bbe9ae4c5d91" +checksum = "70f6ee9518f50ff4d434471ccf569186022bdd5ef65a21d14da3ea5231af944f" dependencies = [ "anchor-syn", "anyhow", @@ -38,9 +38,9 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "485351a6d8157750d10d88c8e256f1bf8339262b2220ae9125aed3471309b5de" +checksum = "32c92bcf5388b52676d990f85bbfd838a8f5672393135063a50dc79b2b837c79" dependencies = [ "anchor-syn", "anyhow", @@ -53,9 +53,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc632c540913dd051a78b00587cc47f57013d303163ddfaf4fa18717f7ccc1e0" +checksum = "0844974ac35e8ced62056b0d63777ebcdc5807438b8b189c881e2b647450b70a" dependencies = [ "anchor-syn", "proc-macro2", @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5bd1dcfa7f3bc22dacef233d70a9e0bee269c4ac484510662f257cba2353a1" +checksum = "0f7467345e67a6f1d4b862b9763a4160ad89d18c247b8c902807768f7b6e23df" dependencies = [ "anchor-syn", "proc-macro2", @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6f9e6ce551ac9a177a45c99a65699a860c9e95fac68675138af1246e2591b0" +checksum = "8774e4c1ac71f71a5aea7e4932fb69c30e3b8155c4fa59fd69401195434528a9" dependencies = [ "anchor-syn", "anyhow", @@ -89,9 +89,9 @@ dependencies = [ [[package]] name = "anchor-attribute-interface" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d104aa17418cb329ed7418b227e083d5f326a27f26ce98f5d92e33da62a5f459" +checksum = "90eeb6e1c80f9f94fcef93a52813f6472186200e275e83cb3fac92b801de92f7" dependencies = [ "anchor-syn", "anyhow", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6831b920b173c004ddf7ae1167d1d25e9f002ffcb1773bbc5c7ce532a4441e1" +checksum = "ac515a7a5a4fea7fc768b1cec40ddb948e148ea657637c75f94f283212326cb9" dependencies = [ "anchor-syn", "anyhow", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "anchor-attribute-state" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde147b10c71d95dc679785db0b5f3abac0091f789167aa62ac0135e2f54e8b9" +checksum = "43dc667b62ff71450f19dcfcc37b0c408fd4ddd89e8650368c2b0984b110603f" dependencies = [ "anchor-syn", "anyhow", @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cde98a0e1a56046b040ff591dfda391f88917af2b6487d02b45093c05be3514" +checksum = "7354d583a06701d24800a8ec4c2b0491f62581a331af349205e23421e0b56643" dependencies = [ "anchor-syn", "anyhow", @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85dd2c5e29e20c7f4701a43724d6cd5406d0ee5694705522e43da0f26542a84" +checksum = "ff5f57ec5e12fa6874b27f3d5c1f6f44302d3ad86c1266197ff7611bf6f5d251" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03549dc2eae0b20beba6333b14520e511822a6321cdb1760f841064a69347316" +checksum = "55aa1e680d9471342122ed5b6bc13bf5da473b0f7e4677d41a6954e5cc8ad155" dependencies = [ "anyhow", "bs58 0.3.1", @@ -178,7 +178,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.9.9", "syn", "thiserror", ] @@ -201,17 +201,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -245,6 +234,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + [[package]] name = "blake3" version = "1.3.1" @@ -265,7 +263,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -278,12 +275,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "borsh" version = "0.9.3" @@ -341,6 +332,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + [[package]] name = "bumpalo" version = "3.11.0" @@ -430,6 +432,51 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "once_cell", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -464,7 +511,7 @@ checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" dependencies = [ "byteorder", "digest 0.9.0", - "rand_core", + "rand_core 0.5.1", "subtle", "zeroize", ] @@ -495,25 +542,21 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "feature-probe" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "static_assertions", +] + [[package]] name = "generic-array" version = "0.14.6" @@ -576,6 +619,18 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + [[package]] name = "hmac" version = "0.8.1" @@ -598,18 +653,19 @@ dependencies = [ ] [[package]] -name = "humantime" -version = "2.1.0" +name = "im" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" dependencies = [ - "cfg-if", + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", ] [[package]] @@ -650,9 +706,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "libsecp256k1" @@ -669,7 +725,7 @@ dependencies = [ "libsecp256k1-gen-genmult", "rand", "serde", - "sha2", + "sha2 0.9.9", "typenum", ] @@ -736,6 +792,31 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -756,6 +837,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.14.0" @@ -770,27 +861,25 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] @@ -799,6 +888,16 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "uint", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -848,7 +947,7 @@ dependencies = [ "getrandom 0.1.16", "libc", "rand_chacha", - "rand_core", + "rand_core 0.5.1", "rand_hc", ] @@ -859,7 +958,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -871,13 +970,52 @@ dependencies = [ "getrandom 0.1.16", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", ] [[package]] @@ -900,6 +1038,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.27" @@ -911,6 +1055,8 @@ name = "remote-executor" version = "0.1.0" dependencies = [ "anchor-lang", + "wormhole-core", + "wormhole-solana", ] [[package]] @@ -1000,15 +1146,34 @@ dependencies = [ ] [[package]] -name = "sha3" -version = "0.9.1" +name = "sha2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.10.5", +] + +[[package]] +name = "sha3" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2904bea16a1ae962b483322a1c7b81d976029203aea1f461e51cd7705db7ba9" +dependencies = [ + "digest 0.10.5", "keccak", - "opaque-debug", +] + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", ] [[package]] @@ -1019,29 +1184,31 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "solana-frozen-abi" -version = "1.9.29" +version = "1.10.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d4fcb89eb3d0f30bd4b4a31ad1825c9d95cd638509acead00969d7601713288" +checksum = "efde683c5a9ab4e579766f92c2861ea9d74716afe2b245762f2c03e10fd4a02c" dependencies = [ "bs58 0.4.0", "bv", "generic-array", + "im", + "lazy_static", "log", "memmap2", "rustc_version", "serde", + "serde_bytes", "serde_derive", - "sha2", + "sha2 0.10.6", "solana-frozen-abi-macro", - "solana-logger", "thiserror", ] [[package]] name = "solana-frozen-abi-macro" -version = "1.9.29" +version = "1.10.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63ab101db88ecccd8da34065b9097b88367e0744fdfd05cb7de87b4ede3717f" +checksum = "b9a72cd208a4c577932f4323103227933fb8a4dd2be4732600483cf944171cc5" dependencies = [ "proc-macro2", "quote", @@ -1049,22 +1216,11 @@ dependencies = [ "syn", ] -[[package]] -name = "solana-logger" -version = "1.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1805d52fc8277a84c4803c7850c8f41471b57fb0dec7750338955ad6e43e2" -dependencies = [ - "env_logger", - "lazy_static", - "log", -] - [[package]] name = "solana-program" -version = "1.9.29" +version = "1.10.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5deafc4902425d40197f74166640300dd20b078e4ffd518c1bb56ceb7e01680" +checksum = "18a937936021d7428561136929aaf15c10f7487c38130067585286d6ab40d80e" dependencies = [ "base64 0.13.0", "bincode", @@ -1093,11 +1249,10 @@ dependencies = [ "serde", "serde_bytes", "serde_derive", - "sha2", + "sha2 0.10.6", "sha3", "solana-frozen-abi", "solana-frozen-abi-macro", - "solana-logger", "solana-sdk-macro", "thiserror", "wasm-bindgen", @@ -1105,9 +1260,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.9.29" +version = "1.10.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db4c93bd43c91290ad54fe6ff86179a859954f196507c4789a4876d38a62f17" +checksum = "89a9241b0327549f0331b46463c48226e9d76fb470fa537d98086035d894a578" dependencies = [ "bs58 0.4.0", "proc-macro2", @@ -1116,6 +1271,12 @@ dependencies = [ "syn", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "subtle" version = "2.4.1" @@ -1124,24 +1285,15 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.35" @@ -1177,6 +1329,18 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.4" @@ -1272,35 +1436,81 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-sys" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_msvc" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows_i686_gnu" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "wormhole-core" +version = "0.1.0" +source = "git+https://github.com/guibescos/wormhole?branch=gbescos/sdk-solana#2a6169c646a78d76407323d138fa4aeb09b1655a" dependencies = [ - "winapi", + "borsh", + "bstr", + "byteorder", + "hex", + "hex-literal", + "nom", + "primitive-types", + "sha3", + "thiserror", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +name = "wormhole-solana" +version = "0.1.0" +source = "git+https://github.com/guibescos/wormhole?branch=gbescos/sdk-solana#2a6169c646a78d76407323d138fa4aeb09b1655a" +dependencies = [ + "borsh", + "bstr", + "byteorder", + "hex", + "hex-literal", + "nom", + "primitive-types", + "sha3", + "solana-program", + "thiserror", + "wormhole-core", +] [[package]] name = "yansi" diff --git a/pythnet/remote-executor/programs/remote-executor/Cargo.toml b/pythnet/remote-executor/programs/remote-executor/Cargo.toml index 3a5275b3..461efb22 100644 --- a/pythnet/remote-executor/programs/remote-executor/Cargo.toml +++ b/pythnet/remote-executor/programs/remote-executor/Cargo.toml @@ -19,4 +19,6 @@ default = [] overflow-checks = true [dependencies] -anchor-lang = "0.24.2" +anchor-lang = {version = "0.25.0", features = ["init-if-needed"]} +wormhole-solana = { git = "https://github.com/guibescos/wormhole", branch = "gbescos/sdk-solana"} +wormhole-core = { git = "https://github.com/guibescos/wormhole", branch = "gbescos/sdk-solana"} diff --git a/pythnet/remote-executor/programs/remote-executor/src/error.rs b/pythnet/remote-executor/programs/remote-executor/src/error.rs new file mode 100644 index 00000000..462728a1 --- /dev/null +++ b/pythnet/remote-executor/programs/remote-executor/src/error.rs @@ -0,0 +1,12 @@ + +use anchor_lang::prelude::*; + +#[error_code] +pub enum ExecutorError { + EmitterChainNotSolana, + NonIncreasingSequence, + GovernanceHeaderInvalidMagicNumber, + GovernanceHeaderInvalidModule, + GovernanceHeaderInvalidAction, + GovernanceHeaderInvalidReceiverChain +} \ No newline at end of file diff --git a/pythnet/remote-executor/programs/remote-executor/src/lib.rs b/pythnet/remote-executor/programs/remote-executor/src/lib.rs index 4d39daed..6ad278a3 100644 --- a/pythnet/remote-executor/programs/remote-executor/src/lib.rs +++ b/pythnet/remote-executor/programs/remote-executor/src/lib.rs @@ -1,15 +1,61 @@ -use anchor_lang::prelude::*; +#![deny(warnings)] + +use anchor_lang::{prelude::*, solana_program::borsh::get_packed_len}; +use state::{claim_record::ClaimRecord, posted_vaa::AnchorVaa}; + +mod state; +mod error; declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); #[program] pub mod remote_executor { + use anchor_lang::solana_program::{program::invoke_signed, instruction::Instruction}; + use wormhole::Chain::{Solana, self}; + + use crate::{state::{governance_payload::ExecutorPayload}, error::ExecutorError}; + use super::*; pub fn execute_posted_vaa(ctx: Context) -> Result<()> { + let posted_vaa = &ctx.accounts.posted_vaa; + let claim_record = &mut ctx.accounts.claim_record; + assert_or_err(Chain::from(posted_vaa.emitter_chain) == Solana, err!(ExecutorError::EmitterChainNotSolana))?; + assert_or_err(posted_vaa.sequence > claim_record.sequence, err!(ExecutorError::NonIncreasingSequence))?; + claim_record.sequence = posted_vaa.sequence; + + let payload = ExecutorPayload::try_from_slice(&posted_vaa.payload)?; + payload.check_header()?; + + for instruction in payload.instructions.iter().map(Instruction::from) { + // TO DO: We currently pass `remaining_accounts` down to the CPIs, is there a more efficient way to do it? + invoke_signed(&instruction, ctx.remaining_accounts, &[&[EXECUTOR_KEY_SEED.as_bytes(), &posted_vaa.emitter_address, &[*ctx.bumps.get("executor_key").unwrap()]]])?; + } Ok(()) } } +const EXECUTOR_KEY_SEED : &str = "EXECUTOR_KEY"; +const CLAIM_RECORD_SEED : &str = "CLAIM_RECORD"; + + #[derive(Accounts)] -pub struct ExecutePostedVaa {} +pub struct ExecutePostedVaa<'info> { + #[account(mut)] + pub payer : Signer<'info>, + pub posted_vaa : Account<'info, AnchorVaa>, + #[account(seeds = [EXECUTOR_KEY_SEED.as_bytes(), &posted_vaa.emitter_address], bump)] + pub executor_key : UncheckedAccount<'info>, + /// The reason claim record is separated from executor_key is that executor key might need to pay in the CPI, so we want it to be a wallet + #[account(init_if_needed, space = 8 + get_packed_len::(), payer=payer, seeds = [CLAIM_RECORD_SEED.as_bytes(), &posted_vaa.emitter_address], bump)] + pub claim_record : Account<'info, ClaimRecord>, + pub system_program: Program<'info, System> +} + +pub fn assert_or_err(condition : bool, error : Result<()>) -> Result<()>{ + if !condition { + error + } else { + Result::Ok(()) + } +} \ No newline at end of file diff --git a/pythnet/remote-executor/programs/remote-executor/src/state/claim_record.rs b/pythnet/remote-executor/programs/remote-executor/src/state/claim_record.rs new file mode 100644 index 00000000..68adea29 --- /dev/null +++ b/pythnet/remote-executor/programs/remote-executor/src/state/claim_record.rs @@ -0,0 +1,10 @@ +use anchor_lang::prelude::*; +use anchor_lang::account; +use anchor_lang::prelude::borsh::BorshSchema; + +#[account] +#[derive(Default, BorshSchema)] +/// This struct records +pub struct ClaimRecord{ + pub sequence : u64 +} \ No newline at end of file diff --git a/pythnet/remote-executor/programs/remote-executor/src/state/governance_payload.rs b/pythnet/remote-executor/programs/remote-executor/src/state/governance_payload.rs new file mode 100644 index 00000000..6b944035 --- /dev/null +++ b/pythnet/remote-executor/programs/remote-executor/src/state/governance_payload.rs @@ -0,0 +1,125 @@ +use std::{ops::Deref, mem::size_of, io::ErrorKind}; + +use anchor_lang::{prelude::*, solana_program::instruction::Instruction}; +use wormhole::Chain; + +use crate::{assert_or_err, error::ExecutorError}; + +pub const MAGIC_NUMBER : u32 = 0x4d475450; // Reverse order of the solidity contract because borsh uses little endian numbers + +#[derive(AnchorDeserialize, AnchorSerialize)] +pub struct ExecutorPayload{ + pub header : GovernanceHeader, + pub instructions: Vec, + +} + +#[derive(AnchorDeserialize, AnchorSerialize, PartialEq)] +pub enum Module { + Executor = 0, + Target +} + +#[derive(AnchorDeserialize, AnchorSerialize, PartialEq)] +pub enum Action { + ExecutePostedVaa = 0, +} + + +/// The Governance Header format for pyth governance messages is the following: +/// - A 4 byte magic number `['P','T','G','M']` +/// - A one byte module variant (0 for Executor and 1 for Target contracts) +/// - A one byte action variant (for Executor only 0 is currently valid) +/// - A bigendian 2 bytes u16 chain id +#[derive(AnchorDeserialize, AnchorSerialize)] +pub struct GovernanceHeader { + pub magic_number : u32, + pub module : Module, + pub action : Action, + pub chain : BigEndianU16 +} + +/// Hack to get Borsh to deserialize, serialize this number with big endian order +pub struct BigEndianU16{ + pub value : u16 +} + +impl AnchorDeserialize for BigEndianU16 { + fn deserialize(buf: &mut &[u8]) -> std::result::Result { + if buf.len() < size_of::() { + return Err(std::io::Error::new( + ErrorKind::InvalidInput, + "Unexpected length of input", + )); + } + let res = u16::from_be_bytes(buf[..size_of::()].try_into().unwrap()); + *buf = &buf[size_of::()..]; + Ok(BigEndianU16{ value:res}) + } +} + +impl AnchorSerialize for BigEndianU16 { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + writer.write_all(&self.to_be_bytes()) + } +} + +impl Deref for BigEndianU16 { + type Target = u16; + + fn deref(&self) -> &Self::Target { + &self.value + } +} + +/// InstructionData wrapper. It can be removed once Borsh serialization for Instruction is supported in the SDK +#[derive(Clone, Debug, PartialEq, Eq, AnchorDeserialize, AnchorSerialize)] +pub struct InstructionData { + /// Pubkey of the instruction processor that executes this instruction + pub program_id: Pubkey, + /// Metadata for what accounts should be passed to the instruction processor + pub accounts: Vec, + /// Opaque data passed to the instruction processor + pub data: Vec, +} + +/// Account metadata used to define Instructions +#[derive(Clone, Debug, PartialEq, Eq, AnchorDeserialize, AnchorSerialize)] +pub struct AccountMetaData { + /// An account's public key + pub pubkey: Pubkey, + /// True if an Instruction requires a Transaction signature matching `pubkey`. + pub is_signer: bool, + /// True if the `pubkey` can be loaded as a read-write account. + pub is_writable: bool, +} + +impl From<&InstructionData> for Instruction { + fn from(instruction: &InstructionData) -> Self { + Instruction { + program_id: instruction.program_id, + accounts: instruction + .accounts + .iter() + .map(|a| AccountMeta { + pubkey: a.pubkey, + is_signer: a.is_signer, + is_writable: a.is_writable, + }) + .collect(), + data: instruction.data.clone(), + } + } +} + +impl ExecutorPayload { + const MODULE : Module = Module::Executor; + const ACTION : Action = Action::ExecutePostedVaa; + + pub fn check_header(&self) -> Result<()>{ + assert_or_err(self.header.magic_number == MAGIC_NUMBER, err!(ExecutorError::GovernanceHeaderInvalidMagicNumber))?; + assert_or_err(self.header.module == ExecutorPayload::MODULE, err!(ExecutorError::GovernanceHeaderInvalidMagicNumber))?; + assert_or_err(self.header.action == ExecutorPayload::ACTION, err!(ExecutorError::GovernanceHeaderInvalidMagicNumber))?; + assert_or_err(Chain::from(self.header.chain.value) == Chain::Pythnet, err!(ExecutorError::GovernanceHeaderInvalidMagicNumber)) + } +} \ No newline at end of file diff --git a/pythnet/remote-executor/programs/remote-executor/src/state/mod.rs b/pythnet/remote-executor/programs/remote-executor/src/state/mod.rs new file mode 100644 index 00000000..a0d1fbed --- /dev/null +++ b/pythnet/remote-executor/programs/remote-executor/src/state/mod.rs @@ -0,0 +1,3 @@ +pub mod claim_record; +pub mod posted_vaa; +pub mod governance_payload; \ No newline at end of file diff --git a/pythnet/remote-executor/programs/remote-executor/src/state/posted_vaa.rs b/pythnet/remote-executor/programs/remote-executor/src/state/posted_vaa.rs new file mode 100644 index 00000000..4315bc73 --- /dev/null +++ b/pythnet/remote-executor/programs/remote-executor/src/state/posted_vaa.rs @@ -0,0 +1,43 @@ +use std::{io::Write, str::FromStr, ops::Deref}; +use anchor_lang::prelude::*; +use wormhole_solana::VAA; + +impl Owner for AnchorVaa { + fn owner() -> Pubkey{ + Pubkey::from_str("H3fxXJ86ADW2PNuDDmZJg6mzTtPxkYCpNuQUTgmJ7AjU").unwrap() // Pythnet bridge address + } +} + +impl AccountDeserialize for AnchorVaa { + // Manual implementation because this account does not have an anchor discriminator + fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result { + Self::try_deserialize_unchecked(buf) + } + + // Manual implementation because this account does not have an anchor discriminator + fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result { + AnchorDeserialize::deserialize(buf) + .map_err(|_| anchor_lang::error::ErrorCode::AccountDidNotDeserialize.into()) + } +} + +impl AccountSerialize for AnchorVaa { + // Make this fail, this is readonly VAA it should never be serialized by this program + fn try_serialize(&self, _writer: &mut W) -> Result<()> { + return Err(anchor_lang::error::ErrorCode::AccountDidNotSerialize.into()); + } +} + +impl Deref for AnchorVaa { + type Target = VAA; + + fn deref(&self) -> &Self::Target { + &self.vaa + } +} + + +#[derive(Clone, AnchorDeserialize, AnchorSerialize)] +pub struct AnchorVaa{ + pub vaa : VAA +}