Explorar el Código

Update devnet and Solana program

Hendrik Hofstadt hace 5 años
padre
commit
49d2872d9c

+ 1 - 0
Tiltfile

@@ -25,6 +25,7 @@ docker_build(
     context = ".",
     only = ["./proto", "./solana"],
     dockerfile = "Dockerfile.agent",
+    ignore = ["./solana/target","./solana/agent/target", "./solana/cli/target"],
 )
 
 # solana local devnet

+ 18 - 0
devnet/solana-devnet.yaml

@@ -14,6 +14,21 @@ spec:
   selector:
     app: solana-devnet
 ---
+apiVersion: v1
+kind: Service
+metadata:
+  name: solana-faucet
+  labels:
+    app: solana-faucet
+spec:
+  ports:
+    - port: 9900
+      name: faucet
+      protocol: TCP
+  clusterIP: None
+  selector:
+    app: solana-devnet
+---
 apiVersion: apps/v1
 kind: StatefulSet
 metadata:
@@ -61,6 +76,9 @@ spec:
             - containerPort: 8900
               name: pubsub
               protocol: TCP
+            - containerPort: 9900
+              name: faucet
+              protocol: TCP
 #          volumeMounts:
 #            - name: solana-devnet-data
 #              mountPath: /data

+ 1 - 0
ethereum/.dockerignore

@@ -0,0 +1 @@
+node_modules

+ 2 - 0
solana/.dockerignore

@@ -0,0 +1,2 @@
+target
+bin

+ 97 - 75
solana/Cargo.lock

@@ -43,7 +43,7 @@ dependencies = [
  "solana-faucet",
  "solana-sdk",
  "solana-transaction-status",
- "spl-token 1.0.6 (git+https://github.com/solana-labs/solana-program-library)",
+ "spl-token 1.0.8 (git+https://github.com/solana-labs/solana-program-library)",
  "thiserror",
  "tokio 0.2.22",
  "tonic",
@@ -118,9 +118,9 @@ dependencies = [
 
 [[package]]
 name = "async-trait"
-version = "0.1.36"
+version = "0.1.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92"
+checksum = "caae68055714ff28740f310927e04f2eba76ff580b16fb18ed90073ee71646f7"
 dependencies = [
  "proc-macro2 1.0.19",
  "quote 1.0.7",
@@ -232,7 +232,7 @@ version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
 dependencies = [
- "block-padding 0.2.0",
+ "block-padding 0.2.1",
  "generic-array 0.14.4",
 ]
 
@@ -247,9 +247,9 @@ dependencies = [
 
 [[package]]
 name = "block-padding"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c98bfd7c112b6399fef97cc0614af1cd375b27a112e552ce60f94c1b5f13cb74"
+checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
 
 [[package]]
 name = "bs58"
@@ -344,9 +344,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
 [[package]]
 name = "chrono"
-version = "0.4.13"
+version = "0.4.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
+checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
 dependencies = [
  "num-integer",
  "num-traits",
@@ -356,9 +356,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "2.33.2"
+version = "2.33.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
+checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
 dependencies = [
  "ansi_term",
  "atty",
@@ -381,6 +381,7 @@ dependencies = [
  "serde_bytes",
  "serde_derive",
  "serde_json",
+ "solana-account-decoder",
  "solana-clap-utils",
  "solana-cli-config",
  "solana-client",
@@ -388,7 +389,7 @@ dependencies = [
  "solana-logger",
  "solana-sdk",
  "solana-transaction-status",
- "spl-token 1.0.6 (git+https://github.com/solana-labs/solana-program-library)",
+ "spl-token 1.0.8 (git+https://github.com/solana-labs/solana-program-library)",
  "thiserror",
  "tungstenite 0.11.1",
  "url",
@@ -421,6 +422,23 @@ dependencies = [
  "winapi-util",
 ]
 
+[[package]]
+name = "console"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0b1aacfaffdbff75be81c15a399b4bedf78aaefe840e8af1d299ac2ade885d2"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "regex",
+ "terminal_size",
+ "termios",
+ "unicode-width",
+ "winapi 0.3.9",
+ "winapi-util",
+]
+
 [[package]]
 name = "constant_time_eq"
 version = "0.1.5"
@@ -532,7 +550,7 @@ version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f4aa86af7b19b40ef9cbef761ed411a49f0afa06b7b6dcd3dfe2f96a3c546138"
 dependencies = [
- "console",
+ "console 0.11.3",
  "lazy_static",
  "tempfile",
 ]
@@ -608,9 +626,9 @@ dependencies = [
 
 [[package]]
 name = "either"
-version = "1.5.3"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
 
 [[package]]
 name = "encode_unicode"
@@ -1033,7 +1051,7 @@ version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
 dependencies = [
- "console",
+ "console 0.12.0",
  "lazy_static",
  "number_prefix",
  "regex",
@@ -1500,7 +1518,7 @@ dependencies = [
  "cloudabi",
  "libc",
  "redox_syscall",
- "smallvec 1.4.1",
+ "smallvec 1.4.2",
  "winapi 0.3.9",
 ]
 
@@ -2013,9 +2031,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
 name = "serde"
-version = "1.0.114"
+version = "1.0.115"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
+checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
 dependencies = [
  "serde_derive",
 ]
@@ -2031,9 +2049,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.114"
+version = "1.0.115"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
+checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
 dependencies = [
  "proc-macro2 1.0.19",
  "quote 1.0.7",
@@ -2147,9 +2165,9 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.4.1"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
+checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
 
 [[package]]
 name = "socket2"
@@ -2165,28 +2183,32 @@ dependencies = [
 
 [[package]]
 name = "solana-account-decoder"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87caa87fb0a2775180e617610c9878ada40e77d862d32c0aff4a6ed66280d58c"
+checksum = "170e0bf8226d79ab2bdcb35230ada6af41a0eb5efe384d0e3b8ec4f9cc7ad269"
 dependencies = [
  "Inflector",
+ "base64 0.12.3",
  "bincode",
  "bs58",
+ "bv",
  "lazy_static",
  "serde",
  "serde_derive",
  "serde_json",
+ "solana-config-program",
  "solana-sdk",
+ "solana-stake-program",
  "solana-vote-program",
- "spl-token 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "spl-token 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "thiserror",
 ]
 
 [[package]]
 name = "solana-clap-utils"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2e94f2ed64c0b80bb502bd1fe00dc75f06d22addf71971bc634f748376a2c5e"
+checksum = "f554b181647dbf8b0ddfe1578df396c7c9720641ed962580e7c36aedacb85d75"
 dependencies = [
  "chrono",
  "clap",
@@ -2200,9 +2222,9 @@ dependencies = [
 
 [[package]]
 name = "solana-cli-config"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fff59e68df0fed618ebac0906739dcf66b0ba425d3d8ac252f71accb1a63fca0"
+checksum = "8a0a49cc9480c5950611b15c74e081d3d4ff331bcc6e3bddca72debb6a054d1f"
 dependencies = [
  "dirs",
  "lazy_static",
@@ -2214,9 +2236,9 @@ dependencies = [
 
 [[package]]
 name = "solana-client"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "964ae6b8e4c10c7532f76f579749043ed332ee2ac0fd5ca78b77df74042ff5b0"
+checksum = "4d0c2d24aa3247e87eb1418efe95baff7d50dd9714cf7cdd41d6fe07a5151155"
 dependencies = [
  "bincode",
  "bs58",
@@ -2240,9 +2262,9 @@ dependencies = [
 
 [[package]]
 name = "solana-config-program"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd4460626e2d6de0f2096485010eab0d4a0865d32356299b8bb9c9c93cf99e7b"
+checksum = "6f48b715b669ba75edb1738352defc68b1b60ab3de5de2eae85d9c78f34bd01c"
 dependencies = [
  "bincode",
  "chrono",
@@ -2254,9 +2276,9 @@ dependencies = [
 
 [[package]]
 name = "solana-crate-features"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66ce44be0cf411c28919c5d2af9b87dcaf7a631df66494eef1134e12fa8916b6"
+checksum = "41045abbf3dd7ecb01db9851590cb2951df54d06f5f13667cfbc178497a9683b"
 dependencies = [
  "backtrace",
  "bytes 0.4.12",
@@ -2279,9 +2301,9 @@ dependencies = [
 
 [[package]]
 name = "solana-faucet"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17b671ff5988c308e85466f6e2253cbe6679d67b7d1a10d60c4c9b2d45e07ae0"
+checksum = "09940d08fe41cd1b9b733eb88fa8925ba0be9010de15d444c38b59b70a912647"
 dependencies = [
  "bincode",
  "byteorder",
@@ -2301,9 +2323,9 @@ dependencies = [
 
 [[package]]
 name = "solana-logger"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4c7ac685637629a11a6cd8d41f8b69c99f6deff8cf2a5ffdb1d5f659d81a7a4"
+checksum = "912c9224a8be284f28b49f173b5e3a99fce7c82cfde819f8086adb2a1ac4f2b3"
 dependencies = [
  "env_logger",
  "lazy_static",
@@ -2312,9 +2334,9 @@ dependencies = [
 
 [[package]]
 name = "solana-metrics"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e15c16f8db726d70710b461b27911e9321c653eeed5b1250bebc74bbb110be1"
+checksum = "553b78ee6975f361f521e08bd68fbbe2397d532a718acd2739184ccc9151f5a1"
 dependencies = [
  "env_logger",
  "gethostname",
@@ -2326,9 +2348,9 @@ dependencies = [
 
 [[package]]
 name = "solana-net-utils"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce583800adbcf6bc7dbdc1bcb973cde80c2c1996544f48c1786bb4b72cd5ed9"
+checksum = "4fecbf069f3cccf86a23c1ff681cc87f032aee1f2ffb265b39f0625e93fdd192"
 dependencies = [
  "bincode",
  "bytes 0.4.12",
@@ -2349,12 +2371,12 @@ dependencies = [
 
 [[package]]
 name = "solana-remote-wallet"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b0b488009a22dd0c21e7a26bdc2a31e990d0cd8161eb5bcc59e899bb3cbd158"
+checksum = "419c020d8c1a7ac86d067195e093ac5c030e1b8547f0d70a391f5e973f58d312"
 dependencies = [
  "base32",
- "console",
+ "console 0.11.3",
  "dialoguer",
  "hidapi",
  "log",
@@ -2369,9 +2391,9 @@ dependencies = [
 
 [[package]]
 name = "solana-sdk"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5502cfd8063437ac2b289b525cff9c271f59f3c267be6e2f6e8256df842d0d96"
+checksum = "d96fb797cf378f8c85ce4e37f45e2fdc75f3a27793e831b3cccd74b0c66e809d"
 dependencies = [
  "assert_matches",
  "bincode",
@@ -2408,9 +2430,9 @@ dependencies = [
 
 [[package]]
 name = "solana-sdk-macro"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4ea42a0ab1199059e60b00bebd58156bc6a8c89672fbb78bd474d98c49d330c"
+checksum = "0aad003e717fc4f1831494de7c5307d667a5c5d2fa22b3dfbedd34a6e61ed4ea"
 dependencies = [
  "bs58",
  "proc-macro2 1.0.19",
@@ -2421,9 +2443,9 @@ dependencies = [
 
 [[package]]
 name = "solana-sdk-macro-frozen-abi"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd83d11379007984161d413872ed8ba1f94c7625967d1a8de6f1e08215eede7"
+checksum = "a0e77bab38b9683d7f0c87e4a860b9b752f81c6b1785d89b49cfd0296846dcb1"
 dependencies = [
  "lazy_static",
  "proc-macro2 1.0.19",
@@ -2434,9 +2456,9 @@ dependencies = [
 
 [[package]]
 name = "solana-stake-program"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc4f7c409612f5a032f5666aa00af973a91cb63a04c1990a88247d7fe0c3f8b"
+checksum = "9c039393dbcb299e8a5c4cd4f3ea913d15c8ebb8d1efcc09f8e65887a1bb61af"
 dependencies = [
  "bincode",
  "log",
@@ -2455,9 +2477,9 @@ dependencies = [
 
 [[package]]
 name = "solana-transaction-status"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c15cafac36d23d432a5fb2bdee4bc8b4dcab353c3a11a2a8472f1184c225ebd"
+checksum = "f536a6157febe5013ee456bc9fdb1eb8840c7371130b536a90704dc29bd2c01b"
 dependencies = [
  "Inflector",
  "bincode",
@@ -2471,15 +2493,15 @@ dependencies = [
  "solana-stake-program",
  "solana-vote-program",
  "spl-memo",
- "spl-token 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "spl-token 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "thiserror",
 ]
 
 [[package]]
 name = "solana-version"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb9849b17e4a632ae09d1dc6a94bd3adf42b4a21baca2703d190f4c9a23549b0"
+checksum = "869fa3c53a1c0adb043c9ac317d80f3f09f76e9a436c2b9de81d9edf30dff788"
 dependencies = [
  "log",
  "rustc_version",
@@ -2492,9 +2514,9 @@ dependencies = [
 
 [[package]]
 name = "solana-vote-program"
-version = "1.3.1"
+version = "1.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13bd63110b90df800b551d014005a59bd86d2fff5422851bc476f1099d7c30d1"
+checksum = "ecd2e0c3a166eaa16bf1957db5e26fc72a5a3dd35cdc3a6e3216ef8b583e7d0f"
 dependencies = [
  "bincode",
  "log",
@@ -2527,8 +2549,8 @@ dependencies = [
 
 [[package]]
 name = "spl-token"
-version = "1.0.6"
-source = "git+https://github.com/solana-labs/solana-program-library#90cc4d3e7447de76d4526fe2574cf83eeacf164f"
+version = "1.0.8"
+source = "git+https://github.com/solana-labs/solana-program-library#b619da32aea7b2898d1fe2faf4cdc7dba99df164"
 dependencies = [
  "cbindgen",
  "num-derive 0.3.1",
@@ -2540,12 +2562,12 @@ dependencies = [
 
 [[package]]
 name = "spl-token"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07c8482ae4aac6bb7d73aef79df5fb403a16a0cfbe200442532cff6b98613383"
+checksum = "7e8bee8b59279b46d0627490b544c3bc38e440ff4da9851a34a26ab0a24bfe7d"
 dependencies = [
  "cbindgen",
- "num-derive 0.2.5",
+ "num-derive 0.3.1",
  "num-traits",
  "remove_dir_all",
  "solana-sdk",
@@ -3193,9 +3215,9 @@ dependencies = [
 
 [[package]]
 name = "tracing"
-version = "0.1.18"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178"
+checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
 dependencies = [
  "cfg-if",
  "log",
@@ -3205,9 +3227,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b"
+checksum = "1fe233f4227389ab7df5b32649239da7ebe0b281824b4e84b342d04d3fd8c25e"
 dependencies = [
  "proc-macro2 1.0.19",
  "quote 1.0.7",
@@ -3216,9 +3238,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-core"
-version = "0.1.13"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d593f98af59ebc017c0648f0117525db358745a8894a8d684e185ba3f45954f9"
+checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
 dependencies = [
  "lazy_static",
 ]
@@ -3287,9 +3309,9 @@ checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
 
 [[package]]
 name = "uint"
-version = "0.8.4"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "429ffcad8c8c15f874578c7337d156a3727eb4a1c2374c0ae937ad9a9b748c80"
+checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177"
 dependencies = [
  "byteorder",
  "crunchy",
@@ -3582,7 +3604,7 @@ dependencies = [
  "remove_dir_all",
  "sha3",
  "solana-sdk",
- "spl-token 1.0.6 (git+https://github.com/solana-labs/solana-program-library)",
+ "spl-token 1.0.8 (git+https://github.com/solana-labs/solana-program-library)",
  "thiserror",
  "zerocopy",
 ]

+ 1 - 0
solana/agent/.dockerignore

@@ -0,0 +1 @@
+target

+ 4 - 4
solana/agent/Cargo.toml

@@ -9,10 +9,10 @@ tonic = "0.3.0"
 tokio = { version = "0.2", features = ["rt-threaded", "time", "stream", "fs", "macros", "uds"] }
 prost = "0.6"
 prost-types = "0.6"
-solana-sdk = { version = "1.3.1" }
-solana-client = { version = "1.3.1" }
-solana-faucet = "1.3.1"
-solana-transaction-status = "1.3.1"
+solana-sdk = { version = "1.3.3" }
+solana-client = { version = "1.3.3" }
+solana-faucet = "1.3.3"
+solana-transaction-status = "1.3.3"
 spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library" }
 wormhole-bridge = { path = "../bridge" }
 primitive-types = {version ="0.7.2"}

+ 1 - 1
solana/bridge/Cargo.toml

@@ -19,7 +19,7 @@ default = ["solana-sdk/default", "spl-token/default"]
 num-derive = "0.2"
 num-traits = "0.2"
 remove_dir_all = "=0.5.0"
-solana-sdk = { version = "1.3.1", default-features = false, optional = true }
+solana-sdk = { version = "=1.3.3", default-features = false, optional = true }
 spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library", default-features = false, optional = true }
 thiserror = "1.0"
 byteorder = "1.3.4"

+ 13 - 4
solana/bridge/src/instruction.rs

@@ -1,8 +1,10 @@
 #![allow(clippy::too_many_arguments)]
 //! Instruction types
 
+use std::io::{Cursor, Read, Write};
 use std::mem::size_of;
 
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 use primitive_types::U256;
 use solana_sdk::{
     instruction::{AccountMeta, Instruction},
@@ -10,10 +12,10 @@ use solana_sdk::{
     pubkey::Pubkey,
 };
 
+use crate::error::Error;
 use crate::error::Error::VAATooLong;
 use crate::instruction::BridgeInstruction::{CreateWrapped, Initialize, PostVAA, TransferOut};
 use crate::state::{AssetMeta, Bridge, BridgeConfig};
-use crate::syscalls::RawKey;
 use crate::vaa::{VAABody, VAA};
 
 /// chain id of this chain
@@ -36,7 +38,7 @@ pub type ForeignAddress = [u8; FOREIGN_ADDRESS_SIZE];
 #[derive(Clone, Copy)]
 pub struct InitializePayload {
     /// guardians that are allowed to sign mints
-    pub initial_guardian: RawKey,
+    pub initial_guardian: [[u8; 20]; 20],
     /// config for the bridge
     pub config: BridgeConfig,
 }
@@ -190,12 +192,19 @@ impl BridgeInstruction {
 pub fn initialize(
     program_id: &Pubkey,
     sender: &Pubkey,
-    initial_guardian: RawKey,
+    initial_guardian: Vec<[u8; 20]>,
     config: &BridgeConfig,
 ) -> Result<Instruction, ProgramError> {
+    if initial_guardian.len() > 20 {
+        return Err(ProgramError::InvalidArgument);
+    }
+    let mut initial_g = [[0u8; 20]; 20];
+    for (i, key) in initial_guardian.iter().enumerate() {
+        initial_g[i] = *key;
+    }
     let data = BridgeInstruction::Initialize(InitializePayload {
         config: *config,
-        initial_guardian,
+        initial_guardian: initial_g,
     })
     .serialize()?;
 

+ 13 - 10
solana/bridge/src/processor.rs

@@ -7,12 +7,13 @@ use std::slice::Iter;
 use num_traits::AsPrimitive;
 use primitive_types::U256;
 use solana_sdk::clock::Clock;
+use solana_sdk::hash::Hasher;
 #[cfg(not(target_arch = "bpf"))]
 use solana_sdk::instruction::Instruction;
 #[cfg(target_arch = "bpf")]
 use solana_sdk::program::invoke_signed;
 use solana_sdk::rent::Rent;
-use solana_sdk::system_instruction::create_account;
+use solana_sdk::system_instruction::{create_account, SystemInstruction};
 use solana_sdk::sysvar::Sysvar;
 use solana_sdk::{
     account_info::next_account_info, account_info::AccountInfo, entrypoint::ProgramResult, info,
@@ -24,7 +25,6 @@ use crate::error::Error;
 use crate::instruction::BridgeInstruction::*;
 use crate::instruction::{BridgeInstruction, TransferOutPayload, VAAData, CHAIN_ID_SOLANA};
 use crate::state::*;
-use crate::syscalls::RawKey;
 use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
 
 /// Instruction processing logic
@@ -73,7 +73,7 @@ impl Bridge {
     pub fn process_initialize(
         program_id: &Pubkey,
         accounts: &[AccountInfo],
-        initial_guardian_key: RawKey,
+        initial_guardian_key: [[u8; 20]; 20],
         config: BridgeConfig,
     ) -> ProgramResult {
         let account_info_iter = &mut accounts.iter();
@@ -126,7 +126,7 @@ impl Bridge {
         guardian_info.is_initialized = true;
         guardian_info.index = 0;
         guardian_info.creation_time = clock.unix_timestamp.as_();
-        guardian_info.pubkey = initial_guardian_key;
+        guardian_info.keys = initial_guardian_key;
 
         Ok(())
     }
@@ -414,11 +414,11 @@ impl Bridge {
         }
 
         // Verify VAA signature
-        if !vaa.verify(&guardian_set.pubkey) {
+        if !vaa.verify(&guardian_set.keys) {
             return Err(Error::InvalidVAASignature.into());
         }
 
-        let payload = vaa.payload.ok_or(Error::InvalidVAAAction)?;
+        let payload = vaa.payload.as_ref().ok_or(Error::InvalidVAAAction)?;
         match payload {
             VAABody::UpdateGuardianSet(v) => Self::process_vaa_set_update(
                 program_id,
@@ -522,7 +522,9 @@ impl Bridge {
         // Set values on the new guardian set
         guardian_set_new.is_initialized = true;
         guardian_set_new.index = b.new_index;
-        guardian_set_new.pubkey = b.new_key;
+        let mut new_guardians = [[0u8; 20]; 20];
+        new_guardians.copy_from_slice(b.new_keys.as_slice());
+        guardian_set_new.keys = new_guardians;
         guardian_set_new.creation_time = clock.unix_timestamp as u32;
 
         // Update the bridge guardian set id
@@ -646,6 +648,7 @@ pub fn invoke_signed<'a>(
     account_infos: &[AccountInfo<'a>],
     signers_seeds: &[&[&[u8]]],
 ) -> ProgramResult {
+    let sys = solana_sdk::system_program::id();
     let mut new_account_infos = vec![];
     for meta in instruction.accounts.iter() {
         for account_info in account_infos.iter() {
@@ -653,7 +656,8 @@ pub fn invoke_signed<'a>(
                 let mut new_account_info = account_info.clone();
                 for seeds in signers_seeds.iter() {
                     let signer =
-                        Pubkey::create_program_address(seeds, &WORMHOLE_PROGRAM_ID).unwrap();
+                        solana_sdk::program::create_program_address(seeds, &WORMHOLE_PROGRAM_ID)
+                            .unwrap();
                     if *account_info.key == signer {
                         new_account_info.is_signer = true;
                     }
@@ -833,8 +837,7 @@ impl Bridge {
             program_id,
         );
         let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
-        //invoke_signed(&ix, accounts, &[s.as_slice()])
-        Ok(())
+        invoke_signed(&ix, accounts, &[s.as_slice()])
     }
 }
 

+ 17 - 3
solana/bridge/src/state.rs

@@ -8,7 +8,6 @@ use zerocopy::AsBytes;
 
 use crate::error::Error;
 use crate::instruction::{ForeignAddress, VAAData};
-use crate::syscalls::RawKey;
 use crate::vaa::BodyTransfer;
 
 /// fee rate as a ratio
@@ -28,7 +27,7 @@ pub struct GuardianSet {
     /// index of the set
     pub index: u32,
     /// public key of the threshold schnorr set
-    pub pubkey: RawKey,
+    pub keys: [[u8; 20]; 20],
     /// creation time
     pub creation_time: u32,
     /// expiration time when VAAs issued by this set are no longer valid
@@ -406,7 +405,22 @@ impl Bridge {
 
     pub fn derive_key(program_id: &Pubkey, seeds: &Vec<Vec<u8>>) -> Result<Pubkey, Error> {
         let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
-        Ok(Pubkey::find_program_address(s.as_slice(), program_id).0)
+        Ok(Self::find_program_address(s.as_slice(), program_id).0)
+    }
+
+    pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8) {
+        let mut nonce = [255];
+        for _ in 0..std::u8::MAX {
+            {
+                let mut seeds_with_nonce = seeds.to_vec();
+                seeds_with_nonce.push(&nonce);
+                if let Ok(address) = Pubkey::create_program_address(&seeds_with_nonce, program_id) {
+                    return (address, nonce[0]);
+                }
+            }
+            nonce[0] -= 1;
+        }
+        panic!("Unable to find a viable program address nonce");
     }
 }
 

+ 30 - 27
solana/bridge/src/syscalls.rs

@@ -1,44 +1,47 @@
+use solana_sdk::program_error::ProgramError;
+
+use crate::error::Error;
+
 #[repr(C)]
-pub struct SchnorrifyInput {
-    message: [u8; 32],
-    addr: [u8; 20],
-    signature: [u8; 32],
-    pub_key: RawKey,
+pub struct EcrecoverInput {
+    pub r: [u8; 32],
+    pub s: [u8; 32],
+    pub v: u8,
+    pub message: [u8; 32],
 }
 
 #[repr(C)]
-#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
-pub struct RawKey {
-    pub x: [u8; 32],
-    pub y_parity: bool,
+pub struct EcrecoverOutput {
+    pub address: [u8; 20],
 }
 
-impl SchnorrifyInput {
-    pub fn new(
-        pub_key: RawKey,
-        message: [u8; 32],
-        signature: [u8; 32],
-        addr: [u8; 20],
-    ) -> SchnorrifyInput {
-        SchnorrifyInput {
-            message,
-            addr,
-            signature,
-            pub_key,
-        }
+impl EcrecoverInput {
+    pub fn new(r: [u8; 32], s: [u8; 32], v: u8, message: [u8; 32]) -> EcrecoverInput {
+        EcrecoverInput { r, s, v, message }
     }
 }
 
 /// Verify an ETH optimized Schnorr signature
 ///
 /// @param input - Input for signature verification
+//#[cfg(target_arch = "bpf")]
 #[inline]
-pub fn sol_verify_schnorr(input: &SchnorrifyInput) -> bool {
-    let res = unsafe { sol_verify_ethschnorr(input as *const _ as *const u8) };
-
-    res == 1
+pub fn sol_syscall_ecrecover(input: &EcrecoverInput) -> Result<EcrecoverOutput, Error> {
+    let mut output = EcrecoverOutput { address: [0; 20] };
+    let res = unsafe {
+        sol_ecrecover(
+            input as *const _ as *const u8,
+            (&mut output) as *mut _ as *mut u8,
+        )
+    };
+    if res == 1 {
+        Ok(output)
+    } else {
+        Err(Error::InvalidVAASignature)
+    }
 }
 
+//#[cfg(target_arch = "bpf")]
 extern "C" {
-    fn sol_verify_ethschnorr(input: *const u8) -> u64;
+    fn sol_ecrecover(input: *const u8, output: *mut u8) -> u64;
 }

+ 129 - 79
solana/bridge/src/vaa.rs

@@ -7,7 +7,7 @@ use sha3::Digest;
 use crate::error::Error;
 use crate::error::Error::InvalidVAAFormat;
 use crate::state::AssetMeta;
-use crate::syscalls::{sol_verify_schnorr, RawKey, SchnorrifyInput};
+use crate::syscalls::{sol_syscall_ecrecover, EcrecoverInput, EcrecoverOutput};
 
 pub type ForeignAddress = [u8; 32];
 
@@ -16,27 +16,33 @@ pub struct VAA {
     // Header part
     pub version: u8,
     pub guardian_set_index: u32,
-    pub signature_sig: [u8; 32],
-    pub signature_addr: [u8; 20],
+    pub signatures: Vec<Signature>,
 
     // Body part
     pub timestamp: u32,
     pub payload: Option<VAABody>,
 }
 
+#[derive(Clone, Copy, Debug, Default, PartialEq)]
+pub struct Signature {
+    pub index: u8,
+    pub r: [u8; 32],
+    pub s: [u8; 32],
+    pub v: u8,
+}
+
 impl VAA {
     pub fn new() -> VAA {
         return VAA {
             version: 0,
             guardian_set_index: 0,
-            signature_sig: [0; 32],
-            signature_addr: [0; 20],
+            signatures: vec![],
             timestamp: 0,
             payload: None,
         };
     }
 
-    pub fn verify(&self, guardian_key: &RawKey) -> bool {
+    pub fn verify(&self, guardian_keys: &[[u8; 20]]) -> bool {
         let body = match self.signature_body() {
             Ok(v) => v,
             Err(_) => {
@@ -50,9 +56,24 @@ impl VAA {
         };
         let hash = h.finalize().into();
 
-        let schnorr_input =
-            SchnorrifyInput::new(*guardian_key, hash, self.signature_sig, self.signature_addr);
-        sol_verify_schnorr(&schnorr_input)
+        for sig in self.signatures.iter() {
+            let ecrecover_input = EcrecoverInput::new(sig.r, sig.s, sig.v, hash);
+            let res = match sol_syscall_ecrecover(&ecrecover_input) {
+                Ok(v) => v,
+                Err(_) => {
+                    return false;
+                }
+            };
+
+            if sig.index >= guardian_keys.len() as u8 {
+                return false;
+            }
+            if res.address != guardian_keys[sig.index as usize] {
+                return false;
+            }
+        }
+
+        true
     }
 
     pub fn body_hash(&self) -> Result<[u8; 32], Error> {
@@ -72,8 +93,15 @@ impl VAA {
 
         v.write_u8(self.version)?;
         v.write_u32::<BigEndian>(self.guardian_set_index)?;
-        v.write(self.signature_sig.as_ref())?;
-        v.write(self.signature_addr.as_ref())?;
+
+        v.write_u8(self.signatures.len() as u8)?;
+        for s in self.signatures.iter() {
+            v.write_u8(s.index)?;
+            v.write(&s.r)?;
+            v.write(&s.s)?;
+            v.write_u8(s.v)?;
+        }
+
         v.write_u32::<BigEndian>(self.timestamp)?;
 
         let payload = self.payload.as_ref().ok_or(Error::InvalidVAAAction)?;
@@ -107,8 +135,20 @@ impl VAA {
 
         v.version = rdr.read_u8()?;
         v.guardian_set_index = rdr.read_u32::<BigEndian>()?;
-        rdr.read_exact(&mut v.signature_sig)?;
-        rdr.read_exact(&mut v.signature_addr)?;
+
+        let len_sig = rdr.read_u8()?;
+        let mut sigs: Vec<Signature> = Vec::with_capacity(len_sig as usize);
+        for i in 0..len_sig {
+            let mut sig = Signature::default();
+
+            sig.index = rdr.read_u8()?;
+            rdr.read_exact(&mut sig.r)?;
+            rdr.read_exact(&mut sig.s)?;
+            sig.v = rdr.read_u8()?;
+
+            sigs.push(sig);
+        }
+        v.signatures = sigs;
 
         v.timestamp = rdr.read_u32::<BigEndian>()?;
 
@@ -120,7 +160,7 @@ impl VAA {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub enum VAABody {
     UpdateGuardianSet(BodyUpdateGuardianSet),
     Transfer(BodyTransfer),
@@ -160,13 +200,13 @@ impl VAABody {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct BodyUpdateGuardianSet {
     pub new_index: u32,
-    pub new_key: RawKey,
+    pub new_keys: Vec<[u8; 20]>,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct BodyTransfer {
     pub nonce: u32,
     pub source_chain: u8,
@@ -179,35 +219,30 @@ pub struct BodyTransfer {
 
 impl BodyUpdateGuardianSet {
     fn deserialize(data: &mut Cursor<&Vec<u8>>) -> Result<BodyUpdateGuardianSet, Error> {
-        let mut new_key_x: [u8; 32] = [0; 32];
-        data.read(&mut new_key_x)?;
-        let new_key_y_parity = match data.read_u8()? {
-            0 => false,
-            1 => true,
-            _ => return Err(InvalidVAAFormat),
-        };
-
         let new_index = data.read_u32::<BigEndian>()?;
 
+        let keys_len = data.read_u8()?;
+        let mut keys = Vec::with_capacity(keys_len as usize);
+        for _ in 0..keys_len {
+            let mut key: [u8; 20] = [0; 20];
+            data.read(&mut key)?;
+            keys.push(key);
+        }
+
         Ok(BodyUpdateGuardianSet {
             new_index,
-            new_key: RawKey {
-                x: new_key_x,
-                y_parity: new_key_y_parity,
-            },
+            new_keys: keys,
         })
     }
 
     fn serialize(&self) -> Result<Vec<u8>, Error> {
         let mut v: Cursor<Vec<u8>> = Cursor::new(Vec::new());
-        v.write(&self.new_key.x)?;
-        v.write_u8({
-            match self.new_key.y_parity {
-                false => 0,
-                true => 1,
-            }
-        })?;
         v.write_u32::<BigEndian>(self.new_index)?;
+        v.write_u8(self.new_keys.len() as u8)?;
+
+        for k in self.new_keys.iter() {
+            v.write(k)?;
+        }
 
         Ok(v.into_inner())
     }
@@ -268,16 +303,19 @@ mod tests {
     use primitive_types::U256;
 
     use crate::state::AssetMeta;
-    use crate::syscalls::RawKey;
-    use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
+    use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, Signature, VAABody, VAA};
 
     #[test]
     fn serialize_deserialize_vaa_transfer() {
         let vaa = VAA {
             version: 8,
             guardian_set_index: 3,
-            signature_sig: [7; 32],
-            signature_addr: [9; 20],
+            signatures: vec![Signature {
+                index: 1,
+                r: [2; 32],
+                s: [2; 32],
+                v: 7,
+            }],
             timestamp: 83,
             payload: Some(VAABody::Transfer(BodyTransfer {
                 nonce: 28,
@@ -303,15 +341,16 @@ mod tests {
         let vaa = VAA {
             version: 8,
             guardian_set_index: 3,
-            signature_sig: [7; 32],
-            signature_addr: [9; 20],
+            signatures: vec![Signature {
+                index: 1,
+                r: [2; 32],
+                s: [2; 32],
+                v: 7,
+            }],
             timestamp: 83,
             payload: Some(VAABody::UpdateGuardianSet(BodyUpdateGuardianSet {
                 new_index: 29,
-                new_key: RawKey {
-                    x: [2; 32],
-                    y_parity: true,
-                },
+                new_keys: vec![],
             })),
         };
 
@@ -324,25 +363,29 @@ mod tests {
     fn parse_given_guardian_set_update() {
         let vaa = VAA {
             version: 1,
-            guardian_set_index: 9,
-            signature_sig: [
-                2, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0,
-            ],
-            signature_addr: [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            timestamp: 2837,
+            guardian_set_index: 0,
+            signatures: vec![Signature {
+                index: 0,
+                r: [
+                    51, 130, 199, 26, 76, 121, 225, 81, 138, 108, 226, 156, 145, 86, 159, 100, 39,
+                    166, 10, 149, 105, 106, 53, 21, 184, 194, 52, 11, 106, 207, 253, 114,
+                ],
+                s: [
+                    51, 21, 189, 16, 17, 170, 119, 159, 34, 87, 56, 130, 164, 237, 254, 27, 130, 6,
+                    84, 142, 19, 72, 113, 162, 63, 139, 160, 193, 199, 208, 181, 237,
+                ],
+                v: 1,
+            }],
+            timestamp: 3000,
             payload: Some(VAABody::UpdateGuardianSet(BodyUpdateGuardianSet {
-                new_index: 2,
-                new_key: RawKey {
-                    x: [
-                        34, 23, 130, 103, 189, 101, 144, 104, 196, 19, 115, 119, 37, 80, 123, 46,
-                        218, 191, 167, 75, 3, 40, 130, 168, 218, 203, 128, 99, 120, 238, 102, 1,
-                    ],
-                    y_parity: true,
-                },
+                new_index: 1,
+                new_keys: vec![[
+                    190, 250, 66, 157, 87, 205, 24, 183, 248, 164, 217, 26, 45, 169, 171, 74, 240,
+                    93, 15, 190,
+                ]],
             })),
         };
-        let data = hex::decode("01000000090208000000000000000000000000000000000000000000000000000000000000010203040000000000000000000000000000000000000b15012522178267bd659068c413737725507b2edabfa74b032882a8dacb806378ee66010100000002").unwrap();
+        let data = hex::decode("010000000001003382c71a4c79e1518a6ce29c91569f6427a60a95696a3515b8c2340b6acffd723315bd1011aa779f22573882a4edfe1b8206548e134871a23f8ba0c1c7d0b5ed0100000bb801190000000101befa429d57cd18b7f8a4d91a2da9ab4af05d0fbe").unwrap();
         let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
         assert_eq!(vaa, parsed_vaa);
 
@@ -354,36 +397,43 @@ mod tests {
     fn parse_given_transfer() {
         let vaa = VAA {
             version: 1,
-            guardian_set_index: 9,
-            signature_sig: [
-                2, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                0, 0, 0, 0,
-            ],
-            signature_addr: [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            timestamp: 2837,
+            guardian_set_index: 0,
+            signatures: vec![Signature {
+                index: 0,
+                r: [
+                    146, 115, 122, 21, 4, 243, 179, 223, 140, 147, 203, 133, 198, 74, 72, 96, 187,
+                    39, 14, 38, 2, 107, 110, 55, 240, 149, 53, 106, 64, 111, 106, 244,
+                ],
+                s: [
+                    57, 198, 178, 233, 119, 95, 161, 198, 102, 149, 37, 240, 110, 218, 176, 51,
+                    186, 93, 68, 115, 8, 244, 227, 189, 179, 60, 15, 54, 29, 195, 46, 195,
+                ],
+                v: 1,
+            }],
+            timestamp: 1597440008,
             payload: Some(VAABody::Transfer(BodyTransfer {
-                nonce: 38,
-                source_chain: 2,
-                target_chain: 1,
+                nonce: 53,
+                source_chain: 1,
+                target_chain: 2,
                 source_address: [
                     2, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                 ],
                 target_address: [
-                    2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0,
+                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 248, 191, 106, 71, 159, 50, 14, 173,
+                    7, 68, 17, 164, 176, 231, 148, 78, 168, 201, 193,
                 ],
                 asset: AssetMeta {
                     address: [
-                        9, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                        0, 0, 0, 0, 0, 0, 0,
+                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 71, 239, 52, 104, 123, 220, 159, 24,
+                        158, 135, 169, 32, 6, 88, 217, 196, 14, 153, 136,
                     ],
-                    chain: 9,
+                    chain: 1,
                 },
-                amount: U256::from(29),
+                amount: U256::from_dec_str("5000000000000000000").unwrap(),
             })),
         };
-        let data = hex::decode("01000000090208000000000000000000000000000000000000000000000000000000000000010203040000000000000000000000000000000000000b15108700000026020102010400000000000000000000000000000000000000000000000000000000000201030000000000000000000000000000000000000000000000000000000000090902040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d").unwrap();
+        let data = hex::decode("0100000000010092737a1504f3b3df8c93cb85c64a4860bb270e26026b6e37f095356a406f6af439c6b2e9775fa1c6669525f06edab033ba5d447308f4e3bdb33c0f361dc32ec3015f3700081087000000350102020104000000000000000000000000000000000000000000000000000000000000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e99880000000000000000000000000000000000000000000000004563918244f40000").unwrap();
         let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
         assert_eq!(vaa, parsed_vaa);
 

+ 1 - 0
solana/cli/.dockerignore

@@ -0,0 +1 @@
+target

+ 8 - 7
solana/cli/Cargo.toml

@@ -8,13 +8,14 @@ edition = "2018"
 
 [dependencies]
 clap = "2.33.0"
-solana-clap-utils = { version = "1.3.1"}
-solana-cli-config = { version = "1.3.1" }
-solana-logger = { version = "1.3.1" }
-solana-sdk = { version = "1.3.1" }
-solana-client = { version = "1.3.1" }
-solana-faucet = "1.3.1"
-solana-transaction-status = "1.3.1"
+solana-clap-utils = { version = "1.3.3"}
+solana-cli-config = { version = "1.3.3" }
+solana-logger = { version = "1.3.3" }
+solana-sdk = { version = "1.3.3" }
+solana-client = { version = "=1.3.3" }
+solana-faucet = "1.3.3"
+solana-transaction-status = "1.3.3"
+solana-account-decoder = { version = "1.3.3" }
 spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library" }
 wormhole-bridge = { path = "../bridge" }
 primitive-types = {version ="0.7.2"}

+ 132 - 179
solana/cli/src/main.rs

@@ -31,9 +31,9 @@ use spl_token::{
     state::{Account, Mint},
 };
 
+use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData};
 use spl_bridge::instruction::*;
 use spl_bridge::state::*;
-use spl_bridge::syscalls::RawKey;
 
 struct Config {
     rpc_client: RpcClient,
@@ -45,64 +45,17 @@ struct Config {
 type Error = Box<dyn std::error::Error>;
 type CommmandResult = Result<Option<Transaction>, Error>;
 
-fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
-    let balance = config.rpc_client.get_balance(&config.fee_payer.pubkey())?;
-    if balance < required_balance {
-        Err(format!(
-            "Fee payer, {}, has insufficient balance: {} required, {} available",
-            config.fee_payer.pubkey(),
-            lamports_to_sol(required_balance),
-            lamports_to_sol(balance)
-        )
-        .into())
-    } else {
-        Ok(())
-    }
-}
-
-fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
-    let balance = config.rpc_client.get_balance(&config.owner.pubkey())?;
-    if balance < required_balance {
-        Err(format!(
-            "Owner, {}, has insufficient balance: {} required, {} available",
-            config.owner.pubkey(),
-            lamports_to_sol(required_balance),
-            lamports_to_sol(balance)
-        )
-        .into())
-    } else {
-        Ok(())
-    }
-}
-
-fn get_decimals_for_token(config: &Config, token: &Pubkey) -> Result<u8, Error> {
-    if *token == native_mint::id() {
-        Ok(native_mint::DECIMALS)
-    } else {
-        let mint = config
-            .rpc_client
-            .get_token_mint_with_commitment(token, config.commitment_config)?
-            .value
-            .ok_or_else(|| format!("Invalid token: {}", token))?;
-        Ok(mint.decimals)
-    }
-}
-
-fn command_deploy_bridge(config: &Config) -> CommmandResult {
+fn command_deploy_bridge(config: &Config, bridge: &Pubkey) -> CommmandResult {
     println!("Deploying bridge program");
 
     let minimum_balance_for_rent_exemption = config
         .rpc_client
         .get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
 
-    let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
     let ix = initialize(
-        &p,
+        bridge,
         &config.owner.pubkey(),
-        RawKey {
-            x: [8; 32],
-            y_parity: true,
-        },
+        vec![[0u8; 20]],
         &BridgeConfig {
             vaa_expiration_time: 200000000,
             token_program: spl_token::id(),
@@ -110,25 +63,7 @@ fn command_deploy_bridge(config: &Config) -> CommmandResult {
     )?;
     println!("bridge: {}, ", ix.accounts[2].pubkey.to_string());
     println!("payer: {}, ", ix.accounts[3].pubkey.to_string());
-
-    let mut ix_c = create_account(
-        &config.owner.pubkey(),
-        &ix.accounts[2].pubkey,
-        100000000,
-        size_of::<Bridge>() as u64,
-        &p,
-    );
-    ix_c.accounts[1].is_signer = false;
-    let mut ix_c2 = create_account(
-        &config.owner.pubkey(),
-        &ix.accounts[3].pubkey,
-        100000000,
-        size_of::<GuardianSet>() as u64,
-        &p,
-    );
-    ix_c2.accounts[1].is_signer = false;
-    let mut transaction =
-        Transaction::new_with_payer(&[ix_c, ix_c2, ix], Some(&config.fee_payer.pubkey()));
+    let mut transaction = Transaction::new_with_payer(&[ix], Some(&config.fee_payer.pubkey()));
 
     let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
     check_fee_payer_balance(
@@ -141,6 +76,7 @@ fn command_deploy_bridge(config: &Config) -> CommmandResult {
 
 fn command_lock_tokens(
     config: &Config,
+    bridge: &Pubkey,
     account: Pubkey,
     token: Pubkey,
     amount: u64,
@@ -154,17 +90,16 @@ fn command_lock_tokens(
         .rpc_client
         .get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
 
-    let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
-    let bridge_key = Bridge::derive_bridge_id(&p)?;
+    let bridge_key = Bridge::derive_bridge_id(bridge)?;
 
     // Check whether we can find wrapped asset meta for the given token
-    let wrapped_key = Bridge::derive_wrapped_meta_id(&p, &bridge_key, &token)?;
+    let wrapped_key = Bridge::derive_wrapped_meta_id(bridge, &bridge_key, &token)?;
     let wrapped_info = config.rpc_client.get_account(&wrapped_key).or_else(Err)?;
     let wrapped_meta: &WrappedAssetMeta =
         Bridge::unpack_unchecked_immutable(wrapped_info.data.as_slice())?;
 
     let ix = transfer_out(
-        &p,
+        bridge,
         &config.owner.pubkey(),
         &account,
         &token,
@@ -200,26 +135,8 @@ fn command_lock_tokens(
         amount,
     )?;
 
-    // TODO remove create calls
-    let mut ix_c = create_account(
-        &config.owner.pubkey(),
-        &ix.accounts[4].pubkey,
-        100000000,
-        size_of::<TransferOutProposal>() as u64,
-        &p,
-    );
-    ix_c.accounts[1].is_signer = false;
-    let mut ix_c2 = create_account(
-        &config.owner.pubkey(),
-        &ix.accounts[7].pubkey,
-        100000000,
-        size_of::<Account>() as u64,
-        &spl_token::id(),
-    );
-    ix_c2.accounts[1].is_signer = false;
-
     let mut transaction =
-        Transaction::new_with_payer(&[ix_a, ix_c, ix_c2, ix], Some(&config.fee_payer.pubkey()));
+        Transaction::new_with_payer(&[ix_a, ix], Some(&config.fee_payer.pubkey()));
 
     let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
     check_fee_payer_balance(
@@ -230,15 +147,14 @@ fn command_lock_tokens(
     Ok(Some(transaction))
 }
 
-fn command_submit_vaa(config: &Config, vaa: &[u8]) -> CommmandResult {
+fn command_submit_vaa(config: &Config, bridge: &Pubkey, vaa: &[u8]) -> CommmandResult {
     println!("Submitting VAA");
 
     let minimum_balance_for_rent_exemption = config
         .rpc_client
         .get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
 
-    let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
-    let ix = post_vaa(&p, &config.owner.pubkey(), vaa)?;
+    let ix = post_vaa(bridge, &config.owner.pubkey(), vaa)?;
 
     let mut transaction = Transaction::new_with_payer(&[ix], Some(&config.fee_payer.pubkey()));
 
@@ -251,6 +167,36 @@ fn command_submit_vaa(config: &Config, vaa: &[u8]) -> CommmandResult {
     Ok(Some(transaction))
 }
 
+fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
+    let balance = config.rpc_client.get_balance(&config.fee_payer.pubkey())?;
+    if balance < required_balance {
+        Err(format!(
+            "Fee payer, {}, has insufficient balance: {} required, {} available",
+            config.fee_payer.pubkey(),
+            lamports_to_sol(required_balance),
+            lamports_to_sol(balance)
+        )
+        .into())
+    } else {
+        Ok(())
+    }
+}
+
+fn check_owner_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
+    let balance = config.rpc_client.get_balance(&config.owner.pubkey())?;
+    if balance < required_balance {
+        Err(format!(
+            "Owner, {}, has insufficient balance: {} required, {} available",
+            config.owner.pubkey(),
+            lamports_to_sol(required_balance),
+            lamports_to_sol(balance)
+        )
+        .into())
+    } else {
+        Ok(())
+    }
+}
+
 fn command_create_token(config: &Config, decimals: u8) -> CommmandResult {
     let token = Keypair::new();
     println!("Creating token {}", token.pubkey());
@@ -367,39 +313,12 @@ fn command_transfer(
         ui_amount, sender, recipient
     );
 
-    let sender_token_account = config
+    let sender_token_balance = config
         .rpc_client
-        .get_token_account_with_commitment(&sender, config.commitment_config)?
-        .value;
-    let recipient_token_account = config
-        .rpc_client
-        .get_token_account_with_commitment(&recipient, config.commitment_config)?
+        .get_token_account_balance_with_commitment(&sender, config.commitment_config)?
         .value;
 
-    let decimals = match (sender_token_account, recipient_token_account) {
-        (Some(sender_token_account), Some(recipient_token_account)) => {
-            if sender_token_account.mint != recipient_token_account.mint {
-                eprintln!("Error: token mismatch between sender and recipient");
-                exit(1)
-            }
-            get_decimals_for_token(config, &sender_token_account.mint.parse::<Pubkey>()?)?
-        }
-        (None, _) => {
-            eprintln!(
-                "Error: sender account is invalid or does not exist: {}",
-                sender
-            );
-            exit(1)
-        }
-        (Some(_), None) => {
-            eprintln!(
-                "Error: recipient account is invalid or does not exist: {}",
-                recipient
-            );
-            exit(1)
-        }
-    };
-    let amount = spl_token::ui_amount_to_amount(ui_amount, decimals);
+    let amount = spl_token::ui_amount_to_amount(ui_amount, sender_token_balance.decimals);
 
     let mut transaction = Transaction::new_with_payer(
         &[transfer(
@@ -422,25 +341,12 @@ fn command_transfer(
 fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommmandResult {
     println!("Burn {} tokens\n  Source: {}", ui_amount, source);
 
-    let source_token_account = config
+    let source_token_balance = config
         .rpc_client
-        .get_token_account_with_commitment(&source, config.commitment_config)?
+        .get_token_account_balance_with_commitment(&source, config.commitment_config)?
         .value;
 
-    let decimals = match source_token_account {
-        Some(source_token_account) => {
-            get_decimals_for_token(config, &source_token_account.mint.parse::<Pubkey>()?)?
-        }
-        None => {
-            eprintln!(
-                "Error: burn account is invalid or does not exist: {}",
-                source
-            );
-            exit(1)
-        }
-    };
-    let amount = spl_token::ui_amount_to_amount(ui_amount, decimals);
-
+    let amount = spl_token::ui_amount_to_amount(ui_amount, source_token_balance.decimals);
     let mut transaction = Transaction::new_with_payer(
         &[burn(
             &spl_token::id(),
@@ -469,24 +375,11 @@ fn command_mint(
         ui_amount, token, recipient
     );
 
-    let recipient_token_account = config
+    let recipient_token_balance = config
         .rpc_client
-        .get_token_account_with_commitment(&recipient, config.commitment_config)?
+        .get_token_account_balance_with_commitment(&recipient, config.commitment_config)?
         .value;
-
-    let decimals = match recipient_token_account {
-        Some(recipient_token_account) => {
-            get_decimals_for_token(config, &recipient_token_account.mint.parse::<Pubkey>()?)?
-        }
-        None => {
-            eprintln!(
-                "Error: recipient account is invalid or does not exist: {}",
-                recipient
-            );
-            exit(1)
-        }
-    };
-    let amount = spl_token::ui_amount_to_amount(ui_amount, decimals);
+    let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals);
 
     let mut transaction = Transaction::new_with_payer(
         &[mint_to(
@@ -575,7 +468,11 @@ fn command_balance(config: &Config, address: Pubkey) -> CommmandResult {
         .rpc_client
         .get_token_account_balance_with_commitment(&address, config.commitment_config)?
         .value;
-    println!("{}", balance.ui_amount);
+
+    println!("ui amount: {}", balance.ui_amount);
+    println!("decimals: {}", balance.decimals);
+    println!("amount: {}", balance.amount);
+
     Ok(None)
 }
 
@@ -607,16 +504,28 @@ fn command_accounts(config: &Config, token: Option<Pubkey>) -> CommmandResult {
 
     println!("Account                                      Token                                        Balance");
     println!("-------------------------------------------------------------------------------------------------");
-    for (address, account) in accounts {
-        let balance = match config
-            .rpc_client
-            .get_token_account_balance_with_commitment(&address, config.commitment_config)
-        {
-            Ok(response) => response.value.ui_amount.to_string(),
-            Err(err) => format!("{}", err),
-        };
-
-        println!("{:<44} {:<44} {}", address, account.mint, balance);
+    for keyed_account in accounts {
+        let address = keyed_account.pubkey;
+
+        if let UiAccountData::Json(parsed_account) = keyed_account.account.data {
+            if parsed_account.program != "spl-token" {
+                println!(
+                    "{:<44} Unsupported account program: {}",
+                    address, parsed_account.program
+                );
+            } else {
+                match serde_json::from_value(parsed_account.parsed) {
+                    Ok(TokenAccountType::Account(ui_token_account)) => println!(
+                        "{:<44} {:<44} {}",
+                        address, ui_token_account.mint, ui_token_account.token_amount.ui_amount
+                    ),
+                    Ok(_) => println!("{:<44} Unsupported token account", address),
+                    Err(err) => println!("{:<44} Account parse failure: {}", address, err),
+                }
+            }
+        } else {
+            println!("{:<44} Unsupported account data format", address);
+        }
     }
     Ok(None)
 }
@@ -901,16 +810,41 @@ fn main() {
                         .help("The address of the token account to unwrap"),
                 ),
         )
-        .subcommand(SubCommand::with_name("create-bridge").about("Create a new bridge"))
+        .subcommand(SubCommand::with_name("create-bridge")
+            .about("Create a new bridge")
+            .arg(
+                Arg::with_name("bridge")
+                    .long("bridge")
+                    .value_name("BRIDGE_KEY")
+                    .validator(is_pubkey_or_keypair)
+                    .takes_value(true)
+                    .index(1)
+                    .required(true)
+                    .help(
+                        "Specify the bridge program public key"
+                    ),
+            ))
         .subcommand(
             SubCommand::with_name("lock")
                 .about("Transfer tokens to another chain")
+                .arg(
+                    Arg::with_name("bridge")
+                        .long("bridge")
+                        .value_name("BRIDGE_KEY")
+                        .validator(is_pubkey_or_keypair)
+                        .takes_value(true)
+                        .index(1)
+                        .required(true)
+                        .help(
+                            "Specify the bridge program public key"
+                        ),
+                )
                 .arg(
                     Arg::with_name("sender")
                         .validator(is_pubkey_or_keypair)
                         .value_name("SENDER_TOKEN_ACCOUNT_ADDRESS")
                         .takes_value(true)
-                        .index(1)
+                        .index(2)
                         .required(true)
                         .help("The token account address of the sender"),
                 )
@@ -919,7 +853,7 @@ fn main() {
                         .validator(is_pubkey_or_keypair)
                         .value_name("TOKEN_ADDRESS")
                         .takes_value(true)
-                        .index(2)
+                        .index(3)
                         .required(true)
                         .help("The mint address"),
                 )
@@ -928,7 +862,7 @@ fn main() {
                         .validator(is_amount)
                         .value_name("AMOUNT")
                         .takes_value(true)
-                        .index(3)
+                        .index(4)
                         .required(true)
                         .help("Amount to transfer out"),
                 )
@@ -937,7 +871,7 @@ fn main() {
                         .validator(is_u8)
                         .value_name("CHAIN")
                         .takes_value(true)
-                        .index(4)
+                        .index(5)
                         .required(true)
                         .help("Chain to transfer to"),
                 )
@@ -946,7 +880,7 @@ fn main() {
                         .validator(is_u8)
                         .value_name("NONCE")
                         .takes_value(true)
-                        .index(5)
+                        .index(6)
                         .required(true)
                         .help("Nonce of the transfer"),
                 ),
@@ -954,12 +888,24 @@ fn main() {
         .subcommand(
             SubCommand::with_name("postvaa")
                 .about("Submit a VAA to the chain")
+                .arg(
+                    Arg::with_name("bridge")
+                        .long("bridge")
+                        .value_name("BRIDGE_KEY")
+                        .validator(is_pubkey_or_keypair)
+                        .takes_value(true)
+                        .index(1)
+                        .required(true)
+                        .help(
+                            "Specify the bridge program public key"
+                        ),
+                )
                 .arg(
                     Arg::with_name("vaa")
                         .validator(is_hex)
                         .value_name("HEX_VAA")
                         .takes_value(true)
-                        .index(1)
+                        .index(2)
                         .required(true)
                         .help("The vaa to be posted"),
                 )
@@ -1046,19 +992,26 @@ fn main() {
             let token = pubkey_of(arg_matches, "token");
             command_accounts(&config, token)
         }
-        ("create-bridge", Some(_arg_matches)) => command_deploy_bridge(&config),
+        ("create-bridge", Some(arg_matches)) => {
+            let bridge = pubkey_of(arg_matches, "bridge").unwrap();
+            command_deploy_bridge(&config, &bridge)
+        }
         ("lock", Some(arg_matches)) => {
+            let bridge = pubkey_of(arg_matches, "bridge").unwrap();
             let account = pubkey_of(arg_matches, "sender").unwrap();
             let amount = value_t_or_exit!(arg_matches, "amount", u64);
             let nonce = value_t_or_exit!(arg_matches, "nonce", u32);
             let chain = value_t_or_exit!(arg_matches, "chain", u8);
             let token = pubkey_of(arg_matches, "token").unwrap();
-            command_lock_tokens(&config, account, token, amount, chain, [0; 32], nonce)
+            command_lock_tokens(
+                &config, &bridge, account, token, amount, chain, [0; 32], nonce,
+            )
         }
         ("postvaa", Some(arg_matches)) => {
+            let bridge = pubkey_of(arg_matches, "bridge").unwrap();
             let vaa_string: String = value_of(arg_matches, "vaa").unwrap();
             let vaa = hex::decode(vaa_string).unwrap();
-            command_submit_vaa(&config, vaa.as_slice())
+            command_submit_vaa(&config, &bridge, vaa.as_slice())
         }
         _ => unreachable!(),
     }

+ 64 - 84
third_party/solana/Add_crypto_syscalls.patch

@@ -3,8 +3,8 @@ IDEA additional info:
 Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 <+>UTF-8
 ===================================================================
---- Cargo.lock	(revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
-+++ Cargo.lock	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
+--- Cargo.lock	(revision d84010e4afe5f79c812ff7da349460dc690a8392)
++++ Cargo.lock	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
 @@ -274,12 +274,22 @@
  source = "registry+https://github.com/rust-lang/crates.io-index"
  checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
@@ -15,14 +15,14 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
   "byteorder",
   "generic-array 0.12.3",
  ]
- 
+
 +[[package]]
 +name = "block-buffer"
 +version = "0.9.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
 +dependencies = [
-+ "block-padding 0.2.0",
++ "block-padding 0.2.1",
 + "generic-array 0.14.3",
 +]
 +
@@ -32,12 +32,12 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 @@ -289,6 +299,12 @@
   "byte-tools",
  ]
- 
+
 +[[package]]
 +name = "block-padding"
-+version = "0.2.0"
++version = "0.2.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "c98bfd7c112b6399fef97cc0614af1cd375b27a112e552ce60f94c1b5f13cb74"
++checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
 +
  [[package]]
  name = "bs58"
@@ -45,7 +45,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 @@ -633,6 +649,12 @@
   "lazy_static",
  ]
- 
+
 +[[package]]
 +name = "crunchy"
 +version = "0.2.2"
@@ -67,7 +67,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 @@ -725,6 +747,15 @@
   "generic-array 0.12.3",
  ]
- 
+
 +[[package]]
 +name = "digest"
 +version = "0.9.0"
@@ -98,12 +98,12 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 + "generic-array 0.12.3",
 + "hmac",
  ]
- 
+
  [[package]]
 @@ -1750,6 +1792,12 @@
   "ws",
  ]
- 
+
 +[[package]]
 +name = "keccak"
 +version = "0.1.0"
@@ -116,7 +116,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 @@ -1818,6 +1866,22 @@
   "libc",
  ]
- 
+
 +[[package]]
 +name = "libsecp256k1"
 +version = "0.3.5"
@@ -139,7 +139,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 @@ -2146,6 +2210,12 @@
  source = "registry+https://github.com/rust-lang/crates.io-index"
  checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
- 
+
 +[[package]]
 +name = "opaque-debug"
 +version = "0.3.0"
@@ -161,7 +161,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 - "opaque-debug",
 + "opaque-debug 0.2.3",
  ]
- 
+
  [[package]]
 @@ -3116,10 +3186,22 @@
  source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -187,9 +187,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 + "keccak",
 + "opaque-debug 0.3.0",
  ]
- 
+
  [[package]]
-@@ -3376,13 +3458,17 @@
+@@ -3376,12 +3458,16 @@
  name = "solana-bpf-loader-program"
  version = "1.4.0"
  dependencies = [
@@ -197,7 +197,6 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
   "bincode",
   "byteorder",
 + "hex",
-  "jemalloc-sys",
 + "libsecp256k1",
   "num-derive 0.3.0",
   "num-traits",
@@ -212,9 +211,9 @@ IDEA additional info:
 Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 <+>UTF-8
 ===================================================================
---- programs/bpf_loader/Cargo.toml	(revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
-+++ programs/bpf_loader/Cargo.toml	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
-@@ -18,6 +18,10 @@
+--- programs/bpf_loader/Cargo.toml	(revision d84010e4afe5f79c812ff7da349460dc690a8392)
++++ programs/bpf_loader/Cargo.toml	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
+@@ -17,6 +17,10 @@
  solana-sdk = { path = "../../sdk", version = "1.4.0" }
  solana_rbpf = "=0.1.28"
  thiserror = "1.0"
@@ -222,7 +221,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +sha3 = "0.9.1"
 +arrayref = "0.3.6"
 +hex = "0.4.2"
- 
+
  [dev-dependencies]
  rand = "0.7.3"
 Index: programs/bpf_loader/src/crypto.rs
@@ -230,8 +229,8 @@ IDEA additional info:
 Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 <+>UTF-8
 ===================================================================
---- programs/bpf_loader/src/crypto.rs	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
-+++ programs/bpf_loader/src/crypto.rs	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
+--- programs/bpf_loader/src/crypto.rs	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
++++ programs/bpf_loader/src/crypto.rs	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
 @@ -0,0 +1,171 @@
 +pub extern crate secp256k1;
 +
@@ -255,7 +254,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +
 +#[repr(C)]
 +pub struct EcrecoverOutput {
-+    pub address: [u8; 32],
++    pub address: [u8; 20],
 +}
 +
 +#[repr(C)]
@@ -409,27 +408,27 @@ IDEA additional info:
 Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 <+>UTF-8
 ===================================================================
---- programs/bpf_loader/src/lib.rs	(revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
-+++ programs/bpf_loader/src/lib.rs	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
-@@ -2,6 +2,10 @@
- pub mod allocator_bump;
- pub mod bpf_verifier;
+--- programs/bpf_loader/src/lib.rs	(revision d84010e4afe5f79c812ff7da349460dc690a8392)
++++ programs/bpf_loader/src/lib.rs	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
+@@ -4,6 +4,10 @@
+ pub mod deprecated;
+ pub mod serialization;
  pub mod syscalls;
 +pub mod crypto;
 +
 +#[macro_use]
 +extern crate arrayref;
- 
- use crate::{bpf_verifier::VerifierError, syscalls::SyscallError};
- use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
+
+ use crate::{
+     bpf_verifier::VerifierError,
 Index: programs/bpf_loader/src/syscalls.rs
 IDEA additional info:
 Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 <+>UTF-8
 ===================================================================
---- programs/bpf_loader/src/syscalls.rs	(revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
-+++ programs/bpf_loader/src/syscalls.rs	(revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
-@@ -1,10 +1,22 @@
+--- programs/bpf_loader/src/syscalls.rs	(revision d84010e4afe5f79c812ff7da349460dc690a8392)
++++ programs/bpf_loader/src/syscalls.rs	(revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
+@@ -1,10 +1,23 @@
 -use crate::{alloc, BPFError};
 -use alloc::Alloc;
 +use std::{
@@ -443,6 +442,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +};
 +
 +use secp256k1::{Error, PublicKey, RecoveryId, Signature};
++use sha3::Digest;
  use solana_rbpf::{
 -    ebpf::{EbpfError, SyscallObject, ELF_INSN_DUMP_OFFSET, MM_HEAP_START},
 -    memory_region::{translate_addr, MemoryRegion},
@@ -456,7 +456,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  use solana_runtime::message_processor::MessageProcessor;
  use solana_sdk::{
      account::Account,
-@@ -18,16 +30,17 @@
+@@ -18,16 +31,16 @@
      program_error::ProgramError,
      pubkey::{Pubkey, PubkeyError},
  };
@@ -480,13 +480,12 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +/// Simple bump allocator, never frees
 +use crate::allocator_bump::BPFAllocator;
 +use crate::crypto::{EcrecoverInput, EcrecoverOutput, SchnorrifyInput};
-+use sha3::Digest;
- 
+
  /// Error definitions
  #[derive(Debug, ThisError)]
-@@ -51,20 +64,13 @@
-     #[error("Cross-program invocation with unauthorized signer or writable account")]
-     PrivilegeEscalation,
+@@ -53,20 +66,13 @@
+     #[error("Unaligned pointer")]
+     UnalignedPointer,
  }
 +
  impl From<SyscallError> for EbpfError<BPFError> {
@@ -494,7 +493,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
          EbpfError::UserError(error.into())
      }
  }
- 
+
 -/// Program heap allocators are intended to allocate/free from a given
 -/// chunk of memory.  The specific allocator implementation is
 -/// selectable at build-time.
@@ -506,7 +505,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  /// Default program heap size, allocators
  /// are expected to enforce this
  const DEFAULT_HEAP_SIZE: usize = 32 * 1024;
-@@ -112,6 +118,20 @@
+@@ -114,6 +120,20 @@
              invoke_context: invoke_context.clone(),
          }),
      )?;
@@ -524,10 +523,10 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +            invoke_context: invoke_context.clone(),
 +        }),
 +    )?;
- 
+
      // Memory allocator
      let heap = vec![0_u8; DEFAULT_HEAP_SIZE];
-@@ -246,6 +266,7 @@
+@@ -256,6 +276,7 @@
  pub struct SyscallLog {
      logger: Rc<RefCell<dyn Logger>>,
  }
@@ -535,7 +534,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl SyscallObject<BPFError> for SyscallLog {
      fn call(
          &mut self,
-@@ -275,6 +296,7 @@
+@@ -285,6 +306,7 @@
  pub struct SyscallLogU64 {
      logger: Rc<RefCell<dyn Logger>>,
  }
@@ -543,7 +542,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl SyscallObject<BPFError> for SyscallLogU64 {
      fn call(
          &mut self,
-@@ -309,6 +331,7 @@
+@@ -319,6 +341,7 @@
  pub struct SyscallSolAllocFree {
      allocator: BPFAllocator,
  }
@@ -551,10 +550,10 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl SyscallObject<BPFError> for SyscallSolAllocFree {
      fn call(
          &mut self,
-@@ -363,6 +386,103 @@
+@@ -373,6 +396,105 @@
      Ok(0)
  }
- 
+
 +/// Verify a ETH optimized Schnorr Signature
 +pub struct SyscallEcrecover<'a> {
 +    invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
@@ -606,7 +605,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +        match secp256k1::recover(&secp256k1::Message::parse(&input.message), &signature,
 +                                 &recovery_id) {
 +            Ok(v) => {
-+                output.address = *sha3::Keccak256::digest(&v.serialize()).as_ref();
++                let mut addr = [0u8; 20];
++                addr.copy_from_slice(&sha3::Keccak256::digest(&v.serialize())[12..]);
++                output.address = addr;
 +            }
 +            Err(_) => {
 +                return Ok(0);
@@ -653,9 +654,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +}
 +
  // Cross-program invocation syscalls
- 
- pub type TranslatedAccounts<'a> = (Vec<Rc<RefCell<Account>>>, Vec<(&'a mut u64, &'a mut [u8])>);
-@@ -398,6 +518,7 @@
+
+ struct AccountReferences<'a> {
+@@ -415,6 +537,7 @@
      callers_keyed_accounts: &'a [KeyedAccount<'a>],
      invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
  }
@@ -663,7 +664,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl<'a> SyscallProcessInstruction<'a> for SyscallProcessInstructionRust<'a> {
      fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
          self.invoke_context
-@@ -419,7 +540,7 @@
+@@ -436,7 +559,7 @@
              ix.accounts.len(),
              ro_regions
          )?
@@ -672,7 +673,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
          let data = translate_slice!(u8, ix.data.as_ptr(), ix.data.len(), ro_regions)?.to_vec();
          Ok(Instruction {
              program_id: ix.program_id,
-@@ -518,6 +639,7 @@
+@@ -551,6 +674,7 @@
          }
      }
  }
@@ -680,7 +681,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl<'a> SyscallObject<BPFError> for SyscallProcessInstructionRust<'a> {
      fn call(
          &mut self,
-@@ -593,6 +715,7 @@
+@@ -626,6 +750,7 @@
      callers_keyed_accounts: &'a [KeyedAccount<'a>],
      invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
  }
@@ -688,7 +689,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl<'a> SyscallProcessInstruction<'a> for SyscallProcessSolInstructionC<'a> {
      fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
          self.invoke_context
-@@ -718,6 +841,7 @@
+@@ -763,6 +888,7 @@
          }
      }
  }
@@ -696,9 +697,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
  impl<'a> SyscallObject<BPFError> for SyscallProcessSolInstructionC<'a> {
      fn call(
          &mut self,
-@@ -769,10 +893,10 @@
+@@ -814,10 +940,10 @@
          }
- 
+
          if account.is_signer && // If message indicates account is signed
 -        !( // one of the following needs to be true:
 -            keyed_account.signer_key().is_some() // Signed in the parent instruction
@@ -711,28 +712,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
              return Err(SyscallError::PrivilegeEscalation.into());
          }
      }
-@@ -851,7 +975,7 @@
-                 return Err(SyscallError::InstructionError(
-                     InstructionError::AccountDataSizeChanged,
-                 )
--                .into());
-+                    .into());
-             }
-             data.clone_from_slice(&account.data);
-         }
-@@ -862,9 +986,10 @@
- 
- #[cfg(test)]
- mod tests {
--    use super::*;
-     use crate::tests::MockLogger;
- 
-+    use super::*;
-+
-     #[test]
-     fn test_translate() {
-         const START: u64 = 100;
-@@ -971,7 +1096,7 @@
+@@ -1034,7 +1160,7 @@
                  assert_eq!(string, "Gaggablaghblagh!");
                  Ok(42)
              })
@@ -740,13 +720,13 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
 +                .unwrap()
          );
      }
- 
-@@ -1003,7 +1128,7 @@
+
+@@ -1066,7 +1192,7 @@
              &[ro_region],
              &[rw_region],
          )
 -        .unwrap();
 +            .unwrap();
      }
- 
+
      #[test]

+ 4 - 4
third_party/solana/Dockerfile

@@ -6,13 +6,12 @@ RUN rustup component add rustfmt
 
 WORKDIR /usr/src/solana
 
-RUN git clone https://github.com/solana-labs/solana --depth=1 --branch master && \
-  cd solana && git checkout 6c5b8f324a6e668c4bf7555747fdb499974f0ac3
+RUN git clone https://github.com/jackcmay/solana --depth=1 --branch cpi-create-account && \
+  cd solana
 
 ADD *.patch .
 
-RUN cd solana && patch -p1 < ../Add_crypto_syscalls.patch
-RUN cd solana && curl -L https://patch-diff.githubusercontent.com/raw/solana-labs/solana/pull/11649.patch | patch -p1
+RUN cd solana && patch -p0 < ../Add_crypto_syscalls.patch
 
 RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \
     --mount=type=cache,target=solana/target \
@@ -23,4 +22,5 @@ RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo
     cp ./target/release/deps/*.so /opt/solana/deps
 
 ENV PATH="/opt/solana:${PATH}"
+ENV RUST_LOG="solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=trace,solana_bpf_loader=debug,solana_rbpf=debug"
 CMD ["/usr/src/solana/solana/run.sh"]