Update devnet and Solana program

This commit is contained in:
Hendrik Hofstadt 2020-08-16 13:21:10 +02:00
parent c8dae177e6
commit 49d2872d9c
18 changed files with 535 additions and 476 deletions

View File

@ -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

View File

@ -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
ethereum/.dockerignore Normal file
View File

@ -0,0 +1 @@
node_modules

2
solana/.dockerignore Normal file
View File

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

172
solana/Cargo.lock generated
View File

@ -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",
]

View File

@ -0,0 +1 @@
target

View File

@ -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"}

View File

@ -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"

View File

@ -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()?;

View File

@ -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()])
}
}

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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,
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,
],
signature_addr: [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
timestamp: 2837,
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,
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,
],
signature_addr: [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
timestamp: 2837,
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
solana/cli/.dockerignore Normal file
View File

@ -0,0 +1 @@
target

View File

@ -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"}

View File

@ -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),
};
for keyed_account in accounts {
let address = keyed_account.pubkey;
println!("{:<44} {:<44} {}", address, account.mint, balance);
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!(),
}

View File

@ -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"
@ -22,7 +22,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+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",
+]
+
@ -35,9 +35,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+[[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"
@ -189,7 +189,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
]
[[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"
@ -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> {
@ -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(),
}),
)?;
@ -527,7 +526,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
// 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,7 +550,7 @@ 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)
}
@ -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);
@ -654,8 +655,8 @@ 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,7 +697,7 @@ 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
@ -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)
})
@ -741,7 +721,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
);
}
@@ -1003,7 +1128,7 @@
@@ -1066,7 +1192,7 @@
&[ro_region],
&[rw_region],
)

View File

@ -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"]