Update devnet and Solana program
This commit is contained in:
parent
c8dae177e6
commit
49d2872d9c
1
Tiltfile
1
Tiltfile
|
@ -25,6 +25,7 @@ docker_build(
|
||||||
context = ".",
|
context = ".",
|
||||||
only = ["./proto", "./solana"],
|
only = ["./proto", "./solana"],
|
||||||
dockerfile = "Dockerfile.agent",
|
dockerfile = "Dockerfile.agent",
|
||||||
|
ignore = ["./solana/target","./solana/agent/target", "./solana/cli/target"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# solana local devnet
|
# solana local devnet
|
||||||
|
|
|
@ -14,6 +14,21 @@ spec:
|
||||||
selector:
|
selector:
|
||||||
app: solana-devnet
|
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
|
apiVersion: apps/v1
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -61,6 +76,9 @@ spec:
|
||||||
- containerPort: 8900
|
- containerPort: 8900
|
||||||
name: pubsub
|
name: pubsub
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
- containerPort: 9900
|
||||||
|
name: faucet
|
||||||
|
protocol: TCP
|
||||||
# volumeMounts:
|
# volumeMounts:
|
||||||
# - name: solana-devnet-data
|
# - name: solana-devnet-data
|
||||||
# mountPath: /data
|
# mountPath: /data
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
|
@ -0,0 +1,2 @@
|
||||||
|
target
|
||||||
|
bin
|
|
@ -43,7 +43,7 @@ dependencies = [
|
||||||
"solana-faucet",
|
"solana-faucet",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-transaction-status",
|
"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",
|
"thiserror",
|
||||||
"tokio 0.2.22",
|
"tokio 0.2.22",
|
||||||
"tonic",
|
"tonic",
|
||||||
|
@ -118,9 +118,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.36"
|
version = "0.1.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92"
|
checksum = "caae68055714ff28740f310927e04f2eba76ff580b16fb18ed90073ee71646f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
|
@ -232,7 +232,7 @@ version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-padding 0.2.0",
|
"block-padding 0.2.1",
|
||||||
"generic-array 0.14.4",
|
"generic-array 0.14.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -247,9 +247,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-padding"
|
name = "block-padding"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c98bfd7c112b6399fef97cc0614af1cd375b27a112e552ce60f94c1b5f13cb74"
|
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bs58"
|
name = "bs58"
|
||||||
|
@ -344,9 +344,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.13"
|
version = "0.4.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
|
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
@ -356,9 +356,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.2"
|
version = "2.33.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10040cdf04294b565d9e0319955430099ec3813a64c952b86a41200ad714ae48"
|
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"atty",
|
"atty",
|
||||||
|
@ -381,6 +381,7 @@ dependencies = [
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"solana-account-decoder",
|
||||||
"solana-clap-utils",
|
"solana-clap-utils",
|
||||||
"solana-cli-config",
|
"solana-cli-config",
|
||||||
"solana-client",
|
"solana-client",
|
||||||
|
@ -388,7 +389,7 @@ dependencies = [
|
||||||
"solana-logger",
|
"solana-logger",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"solana-transaction-status",
|
"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",
|
"thiserror",
|
||||||
"tungstenite 0.11.1",
|
"tungstenite 0.11.1",
|
||||||
"url",
|
"url",
|
||||||
|
@ -421,6 +422,23 @@ dependencies = [
|
||||||
"winapi-util",
|
"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]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -532,7 +550,7 @@ version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f4aa86af7b19b40ef9cbef761ed411a49f0afa06b7b6dcd3dfe2f96a3c546138"
|
checksum = "f4aa86af7b19b40ef9cbef761ed411a49f0afa06b7b6dcd3dfe2f96a3c546138"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console 0.11.3",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
@ -608,9 +626,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.5.3"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
|
@ -1033,7 +1051,7 @@ version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
|
checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console 0.12.0",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -1500,7 +1518,7 @@ dependencies = [
|
||||||
"cloudabi",
|
"cloudabi",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec 1.4.1",
|
"smallvec 1.4.2",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2013,9 +2031,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.114"
|
version = "1.0.115"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
@ -2031,9 +2049,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.114"
|
version = "1.0.115"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
|
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
|
@ -2147,9 +2165,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
|
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
|
@ -2165,28 +2183,32 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-account-decoder"
|
name = "solana-account-decoder"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87caa87fb0a2775180e617610c9878ada40e77d862d32c0aff4a6ed66280d58c"
|
checksum = "170e0bf8226d79ab2bdcb35230ada6af41a0eb5efe384d0e3b8ec4f9cc7ad269"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
|
"base64 0.12.3",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
"bv",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"solana-config-program",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
|
"solana-stake-program",
|
||||||
"solana-vote-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",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-clap-utils"
|
name = "solana-clap-utils"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2e94f2ed64c0b80bb502bd1fe00dc75f06d22addf71971bc634f748376a2c5e"
|
checksum = "f554b181647dbf8b0ddfe1578df396c7c9720641ed962580e7c36aedacb85d75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -2200,9 +2222,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-cli-config"
|
name = "solana-cli-config"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fff59e68df0fed618ebac0906739dcf66b0ba425d3d8ac252f71accb1a63fca0"
|
checksum = "8a0a49cc9480c5950611b15c74e081d3d4ff331bcc6e3bddca72debb6a054d1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -2214,9 +2236,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-client"
|
name = "solana-client"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "964ae6b8e4c10c7532f76f579749043ed332ee2ac0fd5ca78b77df74042ff5b0"
|
checksum = "4d0c2d24aa3247e87eb1418efe95baff7d50dd9714cf7cdd41d6fe07a5151155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bs58",
|
"bs58",
|
||||||
|
@ -2240,9 +2262,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-config-program"
|
name = "solana-config-program"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd4460626e2d6de0f2096485010eab0d4a0865d32356299b8bb9c9c93cf99e7b"
|
checksum = "6f48b715b669ba75edb1738352defc68b1b60ab3de5de2eae85d9c78f34bd01c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -2254,9 +2276,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-crate-features"
|
name = "solana-crate-features"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "66ce44be0cf411c28919c5d2af9b87dcaf7a631df66494eef1134e12fa8916b6"
|
checksum = "41045abbf3dd7ecb01db9851590cb2951df54d06f5f13667cfbc178497a9683b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
|
@ -2279,9 +2301,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-faucet"
|
name = "solana-faucet"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17b671ff5988c308e85466f6e2253cbe6679d67b7d1a10d60c4c9b2d45e07ae0"
|
checksum = "09940d08fe41cd1b9b733eb88fa8925ba0be9010de15d444c38b59b70a912647"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -2301,9 +2323,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-logger"
|
name = "solana-logger"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4c7ac685637629a11a6cd8d41f8b69c99f6deff8cf2a5ffdb1d5f659d81a7a4"
|
checksum = "912c9224a8be284f28b49f173b5e3a99fce7c82cfde819f8086adb2a1ac4f2b3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -2312,9 +2334,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-metrics"
|
name = "solana-metrics"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e15c16f8db726d70710b461b27911e9321c653eeed5b1250bebc74bbb110be1"
|
checksum = "553b78ee6975f361f521e08bd68fbbe2397d532a718acd2739184ccc9151f5a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"gethostname",
|
"gethostname",
|
||||||
|
@ -2326,9 +2348,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-net-utils"
|
name = "solana-net-utils"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ce583800adbcf6bc7dbdc1bcb973cde80c2c1996544f48c1786bb4b72cd5ed9"
|
checksum = "4fecbf069f3cccf86a23c1ff681cc87f032aee1f2ffb265b39f0625e93fdd192"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"bytes 0.4.12",
|
"bytes 0.4.12",
|
||||||
|
@ -2349,12 +2371,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-remote-wallet"
|
name = "solana-remote-wallet"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b0b488009a22dd0c21e7a26bdc2a31e990d0cd8161eb5bcc59e899bb3cbd158"
|
checksum = "419c020d8c1a7ac86d067195e093ac5c030e1b8547f0d70a391f5e973f58d312"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base32",
|
"base32",
|
||||||
"console",
|
"console 0.11.3",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"hidapi",
|
"hidapi",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2369,9 +2391,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk"
|
name = "solana-sdk"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5502cfd8063437ac2b289b525cff9c271f59f3c267be6e2f6e8256df842d0d96"
|
checksum = "d96fb797cf378f8c85ce4e37f45e2fdc75f3a27793e831b3cccd74b0c66e809d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -2408,9 +2430,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk-macro"
|
name = "solana-sdk-macro"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4ea42a0ab1199059e60b00bebd58156bc6a8c89672fbb78bd474d98c49d330c"
|
checksum = "0aad003e717fc4f1831494de7c5307d667a5c5d2fa22b3dfbedd34a6e61ed4ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
|
@ -2421,9 +2443,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-sdk-macro-frozen-abi"
|
name = "solana-sdk-macro-frozen-abi"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ddd83d11379007984161d413872ed8ba1f94c7625967d1a8de6f1e08215eede7"
|
checksum = "a0e77bab38b9683d7f0c87e4a860b9b752f81c6b1785d89b49cfd0296846dcb1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
|
@ -2434,9 +2456,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-stake-program"
|
name = "solana-stake-program"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fdc4f7c409612f5a032f5666aa00af973a91cb63a04c1990a88247d7fe0c3f8b"
|
checksum = "9c039393dbcb299e8a5c4cd4f3ea913d15c8ebb8d1efcc09f8e65887a1bb61af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2455,9 +2477,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-transaction-status"
|
name = "solana-transaction-status"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c15cafac36d23d432a5fb2bdee4bc8b4dcab353c3a11a2a8472f1184c225ebd"
|
checksum = "f536a6157febe5013ee456bc9fdb1eb8840c7371130b536a90704dc29bd2c01b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -2471,15 +2493,15 @@ dependencies = [
|
||||||
"solana-stake-program",
|
"solana-stake-program",
|
||||||
"solana-vote-program",
|
"solana-vote-program",
|
||||||
"spl-memo",
|
"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",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-version"
|
name = "solana-version"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb9849b17e4a632ae09d1dc6a94bd3adf42b4a21baca2703d190f4c9a23549b0"
|
checksum = "869fa3c53a1c0adb043c9ac317d80f3f09f76e9a436c2b9de81d9edf30dff788"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
|
@ -2492,9 +2514,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "solana-vote-program"
|
name = "solana-vote-program"
|
||||||
version = "1.3.1"
|
version = "1.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13bd63110b90df800b551d014005a59bd86d2fff5422851bc476f1099d7c30d1"
|
checksum = "ecd2e0c3a166eaa16bf1957db5e26fc72a5a3dd35cdc3a6e3216ef8b583e7d0f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2527,8 +2549,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-token"
|
name = "spl-token"
|
||||||
version = "1.0.6"
|
version = "1.0.8"
|
||||||
source = "git+https://github.com/solana-labs/solana-program-library#90cc4d3e7447de76d4526fe2574cf83eeacf164f"
|
source = "git+https://github.com/solana-labs/solana-program-library#b619da32aea7b2898d1fe2faf4cdc7dba99df164"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
"num-derive 0.3.1",
|
"num-derive 0.3.1",
|
||||||
|
@ -2540,12 +2562,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-token"
|
name = "spl-token"
|
||||||
version = "1.0.6"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07c8482ae4aac6bb7d73aef79df5fb403a16a0cfbe200442532cff6b98613383"
|
checksum = "7e8bee8b59279b46d0627490b544c3bc38e440ff4da9851a34a26ab0a24bfe7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cbindgen",
|
"cbindgen",
|
||||||
"num-derive 0.2.5",
|
"num-derive 0.3.1",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
|
@ -3193,9 +3215,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.18"
|
version = "0.1.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178"
|
checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"log",
|
"log",
|
||||||
|
@ -3205,9 +3227,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b"
|
checksum = "1fe233f4227389ab7df5b32649239da7ebe0b281824b4e84b342d04d3fd8c25e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.19",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
|
@ -3216,9 +3238,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.13"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d593f98af59ebc017c0648f0117525db358745a8894a8d684e185ba3f45954f9"
|
checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
@ -3287,9 +3309,9 @@ checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uint"
|
name = "uint"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "429ffcad8c8c15f874578c7337d156a3727eb4a1c2374c0ae937ad9a9b748c80"
|
checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"crunchy",
|
"crunchy",
|
||||||
|
@ -3582,7 +3604,7 @@ dependencies = [
|
||||||
"remove_dir_all",
|
"remove_dir_all",
|
||||||
"sha3",
|
"sha3",
|
||||||
"solana-sdk",
|
"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",
|
"thiserror",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
target
|
|
@ -9,10 +9,10 @@ tonic = "0.3.0"
|
||||||
tokio = { version = "0.2", features = ["rt-threaded", "time", "stream", "fs", "macros", "uds"] }
|
tokio = { version = "0.2", features = ["rt-threaded", "time", "stream", "fs", "macros", "uds"] }
|
||||||
prost = "0.6"
|
prost = "0.6"
|
||||||
prost-types = "0.6"
|
prost-types = "0.6"
|
||||||
solana-sdk = { version = "1.3.1" }
|
solana-sdk = { version = "1.3.3" }
|
||||||
solana-client = { version = "1.3.1" }
|
solana-client = { version = "1.3.3" }
|
||||||
solana-faucet = "1.3.1"
|
solana-faucet = "1.3.3"
|
||||||
solana-transaction-status = "1.3.1"
|
solana-transaction-status = "1.3.3"
|
||||||
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library" }
|
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library" }
|
||||||
wormhole-bridge = { path = "../bridge" }
|
wormhole-bridge = { path = "../bridge" }
|
||||||
primitive-types = {version ="0.7.2"}
|
primitive-types = {version ="0.7.2"}
|
||||||
|
|
|
@ -19,7 +19,7 @@ default = ["solana-sdk/default", "spl-token/default"]
|
||||||
num-derive = "0.2"
|
num-derive = "0.2"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
remove_dir_all = "=0.5.0"
|
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 }
|
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library", default-features = false, optional = true }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
//! Instruction types
|
//! Instruction types
|
||||||
|
|
||||||
|
use std::io::{Cursor, Read, Write};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
|
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction},
|
||||||
|
@ -10,10 +12,10 @@ use solana_sdk::{
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
use crate::error::Error::VAATooLong;
|
use crate::error::Error::VAATooLong;
|
||||||
use crate::instruction::BridgeInstruction::{CreateWrapped, Initialize, PostVAA, TransferOut};
|
use crate::instruction::BridgeInstruction::{CreateWrapped, Initialize, PostVAA, TransferOut};
|
||||||
use crate::state::{AssetMeta, Bridge, BridgeConfig};
|
use crate::state::{AssetMeta, Bridge, BridgeConfig};
|
||||||
use crate::syscalls::RawKey;
|
|
||||||
use crate::vaa::{VAABody, VAA};
|
use crate::vaa::{VAABody, VAA};
|
||||||
|
|
||||||
/// chain id of this chain
|
/// chain id of this chain
|
||||||
|
@ -36,7 +38,7 @@ pub type ForeignAddress = [u8; FOREIGN_ADDRESS_SIZE];
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct InitializePayload {
|
pub struct InitializePayload {
|
||||||
/// guardians that are allowed to sign mints
|
/// guardians that are allowed to sign mints
|
||||||
pub initial_guardian: RawKey,
|
pub initial_guardian: [[u8; 20]; 20],
|
||||||
/// config for the bridge
|
/// config for the bridge
|
||||||
pub config: BridgeConfig,
|
pub config: BridgeConfig,
|
||||||
}
|
}
|
||||||
|
@ -190,12 +192,19 @@ impl BridgeInstruction {
|
||||||
pub fn initialize(
|
pub fn initialize(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
sender: &Pubkey,
|
sender: &Pubkey,
|
||||||
initial_guardian: RawKey,
|
initial_guardian: Vec<[u8; 20]>,
|
||||||
config: &BridgeConfig,
|
config: &BridgeConfig,
|
||||||
) -> Result<Instruction, ProgramError> {
|
) -> 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 {
|
let data = BridgeInstruction::Initialize(InitializePayload {
|
||||||
config: *config,
|
config: *config,
|
||||||
initial_guardian,
|
initial_guardian: initial_g,
|
||||||
})
|
})
|
||||||
.serialize()?;
|
.serialize()?;
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,13 @@ use std::slice::Iter;
|
||||||
use num_traits::AsPrimitive;
|
use num_traits::AsPrimitive;
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
use solana_sdk::clock::Clock;
|
use solana_sdk::clock::Clock;
|
||||||
|
use solana_sdk::hash::Hasher;
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
#[cfg(not(target_arch = "bpf"))]
|
||||||
use solana_sdk::instruction::Instruction;
|
use solana_sdk::instruction::Instruction;
|
||||||
#[cfg(target_arch = "bpf")]
|
#[cfg(target_arch = "bpf")]
|
||||||
use solana_sdk::program::invoke_signed;
|
use solana_sdk::program::invoke_signed;
|
||||||
use solana_sdk::rent::Rent;
|
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::sysvar::Sysvar;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account_info::next_account_info, account_info::AccountInfo, entrypoint::ProgramResult, info,
|
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::*;
|
||||||
use crate::instruction::{BridgeInstruction, TransferOutPayload, VAAData, CHAIN_ID_SOLANA};
|
use crate::instruction::{BridgeInstruction, TransferOutPayload, VAAData, CHAIN_ID_SOLANA};
|
||||||
use crate::state::*;
|
use crate::state::*;
|
||||||
use crate::syscalls::RawKey;
|
|
||||||
use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
|
use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
|
||||||
|
|
||||||
/// Instruction processing logic
|
/// Instruction processing logic
|
||||||
|
@ -73,7 +73,7 @@ impl Bridge {
|
||||||
pub fn process_initialize(
|
pub fn process_initialize(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
initial_guardian_key: RawKey,
|
initial_guardian_key: [[u8; 20]; 20],
|
||||||
config: BridgeConfig,
|
config: BridgeConfig,
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
@ -126,7 +126,7 @@ impl Bridge {
|
||||||
guardian_info.is_initialized = true;
|
guardian_info.is_initialized = true;
|
||||||
guardian_info.index = 0;
|
guardian_info.index = 0;
|
||||||
guardian_info.creation_time = clock.unix_timestamp.as_();
|
guardian_info.creation_time = clock.unix_timestamp.as_();
|
||||||
guardian_info.pubkey = initial_guardian_key;
|
guardian_info.keys = initial_guardian_key;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -414,11 +414,11 @@ impl Bridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify VAA signature
|
// Verify VAA signature
|
||||||
if !vaa.verify(&guardian_set.pubkey) {
|
if !vaa.verify(&guardian_set.keys) {
|
||||||
return Err(Error::InvalidVAASignature.into());
|
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 {
|
match payload {
|
||||||
VAABody::UpdateGuardianSet(v) => Self::process_vaa_set_update(
|
VAABody::UpdateGuardianSet(v) => Self::process_vaa_set_update(
|
||||||
program_id,
|
program_id,
|
||||||
|
@ -522,7 +522,9 @@ impl Bridge {
|
||||||
// Set values on the new guardian set
|
// Set values on the new guardian set
|
||||||
guardian_set_new.is_initialized = true;
|
guardian_set_new.is_initialized = true;
|
||||||
guardian_set_new.index = b.new_index;
|
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;
|
guardian_set_new.creation_time = clock.unix_timestamp as u32;
|
||||||
|
|
||||||
// Update the bridge guardian set id
|
// Update the bridge guardian set id
|
||||||
|
@ -646,6 +648,7 @@ pub fn invoke_signed<'a>(
|
||||||
account_infos: &[AccountInfo<'a>],
|
account_infos: &[AccountInfo<'a>],
|
||||||
signers_seeds: &[&[&[u8]]],
|
signers_seeds: &[&[&[u8]]],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
|
let sys = solana_sdk::system_program::id();
|
||||||
let mut new_account_infos = vec![];
|
let mut new_account_infos = vec![];
|
||||||
for meta in instruction.accounts.iter() {
|
for meta in instruction.accounts.iter() {
|
||||||
for account_info in account_infos.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();
|
let mut new_account_info = account_info.clone();
|
||||||
for seeds in signers_seeds.iter() {
|
for seeds in signers_seeds.iter() {
|
||||||
let signer =
|
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 {
|
if *account_info.key == signer {
|
||||||
new_account_info.is_signer = true;
|
new_account_info.is_signer = true;
|
||||||
}
|
}
|
||||||
|
@ -833,8 +837,7 @@ impl Bridge {
|
||||||
program_id,
|
program_id,
|
||||||
);
|
);
|
||||||
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
let s: Vec<_> = seeds.iter().map(|item| item.as_slice()).collect();
|
||||||
//invoke_signed(&ix, accounts, &[s.as_slice()])
|
invoke_signed(&ix, accounts, &[s.as_slice()])
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ use zerocopy::AsBytes;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::instruction::{ForeignAddress, VAAData};
|
use crate::instruction::{ForeignAddress, VAAData};
|
||||||
use crate::syscalls::RawKey;
|
|
||||||
use crate::vaa::BodyTransfer;
|
use crate::vaa::BodyTransfer;
|
||||||
|
|
||||||
/// fee rate as a ratio
|
/// fee rate as a ratio
|
||||||
|
@ -28,7 +27,7 @@ pub struct GuardianSet {
|
||||||
/// index of the set
|
/// index of the set
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
/// public key of the threshold schnorr set
|
/// public key of the threshold schnorr set
|
||||||
pub pubkey: RawKey,
|
pub keys: [[u8; 20]; 20],
|
||||||
/// creation time
|
/// creation time
|
||||||
pub creation_time: u32,
|
pub creation_time: u32,
|
||||||
/// expiration time when VAAs issued by this set are no longer valid
|
/// 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> {
|
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();
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,47 @@
|
||||||
|
use solana_sdk::program_error::ProgramError;
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct SchnorrifyInput {
|
pub struct EcrecoverInput {
|
||||||
message: [u8; 32],
|
pub r: [u8; 32],
|
||||||
addr: [u8; 20],
|
pub s: [u8; 32],
|
||||||
signature: [u8; 32],
|
pub v: u8,
|
||||||
pub_key: RawKey,
|
pub message: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
|
pub struct EcrecoverOutput {
|
||||||
pub struct RawKey {
|
pub address: [u8; 20],
|
||||||
pub x: [u8; 32],
|
|
||||||
pub y_parity: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SchnorrifyInput {
|
impl EcrecoverInput {
|
||||||
pub fn new(
|
pub fn new(r: [u8; 32], s: [u8; 32], v: u8, message: [u8; 32]) -> EcrecoverInput {
|
||||||
pub_key: RawKey,
|
EcrecoverInput { r, s, v, message }
|
||||||
message: [u8; 32],
|
|
||||||
signature: [u8; 32],
|
|
||||||
addr: [u8; 20],
|
|
||||||
) -> SchnorrifyInput {
|
|
||||||
SchnorrifyInput {
|
|
||||||
message,
|
|
||||||
addr,
|
|
||||||
signature,
|
|
||||||
pub_key,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify an ETH optimized Schnorr signature
|
/// Verify an ETH optimized Schnorr signature
|
||||||
///
|
///
|
||||||
/// @param input - Input for signature verification
|
/// @param input - Input for signature verification
|
||||||
|
//#[cfg(target_arch = "bpf")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sol_verify_schnorr(input: &SchnorrifyInput) -> bool {
|
pub fn sol_syscall_ecrecover(input: &EcrecoverInput) -> Result<EcrecoverOutput, Error> {
|
||||||
let res = unsafe { sol_verify_ethschnorr(input as *const _ as *const u8) };
|
let mut output = EcrecoverOutput { address: [0; 20] };
|
||||||
|
let res = unsafe {
|
||||||
res == 1
|
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" {
|
extern "C" {
|
||||||
fn sol_verify_ethschnorr(input: *const u8) -> u64;
|
fn sol_ecrecover(input: *const u8, output: *mut u8) -> u64;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use sha3::Digest;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::error::Error::InvalidVAAFormat;
|
use crate::error::Error::InvalidVAAFormat;
|
||||||
use crate::state::AssetMeta;
|
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];
|
pub type ForeignAddress = [u8; 32];
|
||||||
|
|
||||||
|
@ -16,27 +16,33 @@ pub struct VAA {
|
||||||
// Header part
|
// Header part
|
||||||
pub version: u8,
|
pub version: u8,
|
||||||
pub guardian_set_index: u32,
|
pub guardian_set_index: u32,
|
||||||
pub signature_sig: [u8; 32],
|
pub signatures: Vec<Signature>,
|
||||||
pub signature_addr: [u8; 20],
|
|
||||||
|
|
||||||
// Body part
|
// Body part
|
||||||
pub timestamp: u32,
|
pub timestamp: u32,
|
||||||
pub payload: Option<VAABody>,
|
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 {
|
impl VAA {
|
||||||
pub fn new() -> VAA {
|
pub fn new() -> VAA {
|
||||||
return VAA {
|
return VAA {
|
||||||
version: 0,
|
version: 0,
|
||||||
guardian_set_index: 0,
|
guardian_set_index: 0,
|
||||||
signature_sig: [0; 32],
|
signatures: vec![],
|
||||||
signature_addr: [0; 20],
|
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
payload: None,
|
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() {
|
let body = match self.signature_body() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -50,9 +56,24 @@ impl VAA {
|
||||||
};
|
};
|
||||||
let hash = h.finalize().into();
|
let hash = h.finalize().into();
|
||||||
|
|
||||||
let schnorr_input =
|
for sig in self.signatures.iter() {
|
||||||
SchnorrifyInput::new(*guardian_key, hash, self.signature_sig, self.signature_addr);
|
let ecrecover_input = EcrecoverInput::new(sig.r, sig.s, sig.v, hash);
|
||||||
sol_verify_schnorr(&schnorr_input)
|
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> {
|
pub fn body_hash(&self) -> Result<[u8; 32], Error> {
|
||||||
|
@ -72,8 +93,15 @@ impl VAA {
|
||||||
|
|
||||||
v.write_u8(self.version)?;
|
v.write_u8(self.version)?;
|
||||||
v.write_u32::<BigEndian>(self.guardian_set_index)?;
|
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)?;
|
v.write_u32::<BigEndian>(self.timestamp)?;
|
||||||
|
|
||||||
let payload = self.payload.as_ref().ok_or(Error::InvalidVAAAction)?;
|
let payload = self.payload.as_ref().ok_or(Error::InvalidVAAAction)?;
|
||||||
|
@ -107,8 +135,20 @@ impl VAA {
|
||||||
|
|
||||||
v.version = rdr.read_u8()?;
|
v.version = rdr.read_u8()?;
|
||||||
v.guardian_set_index = rdr.read_u32::<BigEndian>()?;
|
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>()?;
|
v.timestamp = rdr.read_u32::<BigEndian>()?;
|
||||||
|
|
||||||
|
@ -120,7 +160,7 @@ impl VAA {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum VAABody {
|
pub enum VAABody {
|
||||||
UpdateGuardianSet(BodyUpdateGuardianSet),
|
UpdateGuardianSet(BodyUpdateGuardianSet),
|
||||||
Transfer(BodyTransfer),
|
Transfer(BodyTransfer),
|
||||||
|
@ -160,13 +200,13 @@ impl VAABody {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct BodyUpdateGuardianSet {
|
pub struct BodyUpdateGuardianSet {
|
||||||
pub new_index: u32,
|
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 struct BodyTransfer {
|
||||||
pub nonce: u32,
|
pub nonce: u32,
|
||||||
pub source_chain: u8,
|
pub source_chain: u8,
|
||||||
|
@ -179,35 +219,30 @@ pub struct BodyTransfer {
|
||||||
|
|
||||||
impl BodyUpdateGuardianSet {
|
impl BodyUpdateGuardianSet {
|
||||||
fn deserialize(data: &mut Cursor<&Vec<u8>>) -> Result<BodyUpdateGuardianSet, Error> {
|
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 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 {
|
Ok(BodyUpdateGuardianSet {
|
||||||
new_index,
|
new_index,
|
||||||
new_key: RawKey {
|
new_keys: keys,
|
||||||
x: new_key_x,
|
|
||||||
y_parity: new_key_y_parity,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self) -> Result<Vec<u8>, Error> {
|
fn serialize(&self) -> Result<Vec<u8>, Error> {
|
||||||
let mut v: Cursor<Vec<u8>> = Cursor::new(Vec::new());
|
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_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())
|
Ok(v.into_inner())
|
||||||
}
|
}
|
||||||
|
@ -268,16 +303,19 @@ mod tests {
|
||||||
use primitive_types::U256;
|
use primitive_types::U256;
|
||||||
|
|
||||||
use crate::state::AssetMeta;
|
use crate::state::AssetMeta;
|
||||||
use crate::syscalls::RawKey;
|
use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, Signature, VAABody, VAA};
|
||||||
use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_deserialize_vaa_transfer() {
|
fn serialize_deserialize_vaa_transfer() {
|
||||||
let vaa = VAA {
|
let vaa = VAA {
|
||||||
version: 8,
|
version: 8,
|
||||||
guardian_set_index: 3,
|
guardian_set_index: 3,
|
||||||
signature_sig: [7; 32],
|
signatures: vec![Signature {
|
||||||
signature_addr: [9; 20],
|
index: 1,
|
||||||
|
r: [2; 32],
|
||||||
|
s: [2; 32],
|
||||||
|
v: 7,
|
||||||
|
}],
|
||||||
timestamp: 83,
|
timestamp: 83,
|
||||||
payload: Some(VAABody::Transfer(BodyTransfer {
|
payload: Some(VAABody::Transfer(BodyTransfer {
|
||||||
nonce: 28,
|
nonce: 28,
|
||||||
|
@ -303,15 +341,16 @@ mod tests {
|
||||||
let vaa = VAA {
|
let vaa = VAA {
|
||||||
version: 8,
|
version: 8,
|
||||||
guardian_set_index: 3,
|
guardian_set_index: 3,
|
||||||
signature_sig: [7; 32],
|
signatures: vec![Signature {
|
||||||
signature_addr: [9; 20],
|
index: 1,
|
||||||
|
r: [2; 32],
|
||||||
|
s: [2; 32],
|
||||||
|
v: 7,
|
||||||
|
}],
|
||||||
timestamp: 83,
|
timestamp: 83,
|
||||||
payload: Some(VAABody::UpdateGuardianSet(BodyUpdateGuardianSet {
|
payload: Some(VAABody::UpdateGuardianSet(BodyUpdateGuardianSet {
|
||||||
new_index: 29,
|
new_index: 29,
|
||||||
new_key: RawKey {
|
new_keys: vec![],
|
||||||
x: [2; 32],
|
|
||||||
y_parity: true,
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -324,25 +363,29 @@ mod tests {
|
||||||
fn parse_given_guardian_set_update() {
|
fn parse_given_guardian_set_update() {
|
||||||
let vaa = VAA {
|
let vaa = VAA {
|
||||||
version: 1,
|
version: 1,
|
||||||
guardian_set_index: 9,
|
guardian_set_index: 0,
|
||||||
signature_sig: [
|
signatures: vec![Signature {
|
||||||
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,
|
index: 0,
|
||||||
0, 0, 0, 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],
|
s: [
|
||||||
timestamp: 2837,
|
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 {
|
payload: Some(VAABody::UpdateGuardianSet(BodyUpdateGuardianSet {
|
||||||
new_index: 2,
|
new_index: 1,
|
||||||
new_key: RawKey {
|
new_keys: vec![[
|
||||||
x: [
|
190, 250, 66, 157, 87, 205, 24, 183, 248, 164, 217, 26, 45, 169, 171, 74, 240,
|
||||||
34, 23, 130, 103, 189, 101, 144, 104, 196, 19, 115, 119, 37, 80, 123, 46,
|
93, 15, 190,
|
||||||
218, 191, 167, 75, 3, 40, 130, 168, 218, 203, 128, 99, 120, 238, 102, 1,
|
]],
|
||||||
],
|
|
||||||
y_parity: true,
|
|
||||||
},
|
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
let data = hex::decode("01000000090208000000000000000000000000000000000000000000000000000000000000010203040000000000000000000000000000000000000b15012522178267bd659068c413737725507b2edabfa74b032882a8dacb806378ee66010100000002").unwrap();
|
let data = hex::decode("010000000001003382c71a4c79e1518a6ce29c91569f6427a60a95696a3515b8c2340b6acffd723315bd1011aa779f22573882a4edfe1b8206548e134871a23f8ba0c1c7d0b5ed0100000bb801190000000101befa429d57cd18b7f8a4d91a2da9ab4af05d0fbe").unwrap();
|
||||||
let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
|
let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
|
||||||
assert_eq!(vaa, parsed_vaa);
|
assert_eq!(vaa, parsed_vaa);
|
||||||
|
|
||||||
|
@ -354,36 +397,43 @@ mod tests {
|
||||||
fn parse_given_transfer() {
|
fn parse_given_transfer() {
|
||||||
let vaa = VAA {
|
let vaa = VAA {
|
||||||
version: 1,
|
version: 1,
|
||||||
guardian_set_index: 9,
|
guardian_set_index: 0,
|
||||||
signature_sig: [
|
signatures: vec![Signature {
|
||||||
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,
|
index: 0,
|
||||||
0, 0, 0, 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],
|
s: [
|
||||||
timestamp: 2837,
|
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 {
|
payload: Some(VAABody::Transfer(BodyTransfer {
|
||||||
nonce: 38,
|
nonce: 53,
|
||||||
source_chain: 2,
|
source_chain: 1,
|
||||||
target_chain: 1,
|
target_chain: 2,
|
||||||
source_address: [
|
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,
|
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,
|
0, 0, 0, 0, 0, 0,
|
||||||
],
|
],
|
||||||
target_address: [
|
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, 144, 248, 191, 106, 71, 159, 50, 14, 173,
|
||||||
0, 0, 0, 0, 0, 0,
|
7, 68, 17, 164, 176, 231, 148, 78, 168, 201, 193,
|
||||||
],
|
],
|
||||||
asset: AssetMeta {
|
asset: AssetMeta {
|
||||||
address: [
|
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, 3, 71, 239, 52, 104, 123, 220, 159, 24,
|
||||||
0, 0, 0, 0, 0, 0, 0,
|
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();
|
let parsed_vaa = VAA::deserialize(data.as_slice()).unwrap();
|
||||||
assert_eq!(vaa, parsed_vaa);
|
assert_eq!(vaa, parsed_vaa);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
target
|
|
@ -8,13 +8,14 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
solana-clap-utils = { version = "1.3.1"}
|
solana-clap-utils = { version = "1.3.3"}
|
||||||
solana-cli-config = { version = "1.3.1" }
|
solana-cli-config = { version = "1.3.3" }
|
||||||
solana-logger = { version = "1.3.1" }
|
solana-logger = { version = "1.3.3" }
|
||||||
solana-sdk = { version = "1.3.1" }
|
solana-sdk = { version = "1.3.3" }
|
||||||
solana-client = { version = "1.3.1" }
|
solana-client = { version = "=1.3.3" }
|
||||||
solana-faucet = "1.3.1"
|
solana-faucet = "1.3.3"
|
||||||
solana-transaction-status = "1.3.1"
|
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" }
|
spl-token = { package = "spl-token", git = "https://github.com/solana-labs/solana-program-library" }
|
||||||
wormhole-bridge = { path = "../bridge" }
|
wormhole-bridge = { path = "../bridge" }
|
||||||
primitive-types = {version ="0.7.2"}
|
primitive-types = {version ="0.7.2"}
|
||||||
|
|
|
@ -31,9 +31,9 @@ use spl_token::{
|
||||||
state::{Account, Mint},
|
state::{Account, Mint},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use solana_account_decoder::{parse_token::TokenAccountType, UiAccountData};
|
||||||
use spl_bridge::instruction::*;
|
use spl_bridge::instruction::*;
|
||||||
use spl_bridge::state::*;
|
use spl_bridge::state::*;
|
||||||
use spl_bridge::syscalls::RawKey;
|
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
rpc_client: RpcClient,
|
rpc_client: RpcClient,
|
||||||
|
@ -45,64 +45,17 @@ struct Config {
|
||||||
type Error = Box<dyn std::error::Error>;
|
type Error = Box<dyn std::error::Error>;
|
||||||
type CommmandResult = Result<Option<Transaction>, Error>;
|
type CommmandResult = Result<Option<Transaction>, Error>;
|
||||||
|
|
||||||
fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> {
|
fn command_deploy_bridge(config: &Config, bridge: &Pubkey) -> CommmandResult {
|
||||||
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 {
|
|
||||||
println!("Deploying bridge program");
|
println!("Deploying bridge program");
|
||||||
|
|
||||||
let minimum_balance_for_rent_exemption = config
|
let minimum_balance_for_rent_exemption = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
||||||
|
|
||||||
let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
|
|
||||||
let ix = initialize(
|
let ix = initialize(
|
||||||
&p,
|
bridge,
|
||||||
&config.owner.pubkey(),
|
&config.owner.pubkey(),
|
||||||
RawKey {
|
vec![[0u8; 20]],
|
||||||
x: [8; 32],
|
|
||||||
y_parity: true,
|
|
||||||
},
|
|
||||||
&BridgeConfig {
|
&BridgeConfig {
|
||||||
vaa_expiration_time: 200000000,
|
vaa_expiration_time: 200000000,
|
||||||
token_program: spl_token::id(),
|
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!("bridge: {}, ", ix.accounts[2].pubkey.to_string());
|
||||||
println!("payer: {}, ", ix.accounts[3].pubkey.to_string());
|
println!("payer: {}, ", ix.accounts[3].pubkey.to_string());
|
||||||
|
let mut transaction = Transaction::new_with_payer(&[ix], Some(&config.fee_payer.pubkey()));
|
||||||
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 (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
||||||
check_fee_payer_balance(
|
check_fee_payer_balance(
|
||||||
|
@ -141,6 +76,7 @@ fn command_deploy_bridge(config: &Config) -> CommmandResult {
|
||||||
|
|
||||||
fn command_lock_tokens(
|
fn command_lock_tokens(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
|
bridge: &Pubkey,
|
||||||
account: Pubkey,
|
account: Pubkey,
|
||||||
token: Pubkey,
|
token: Pubkey,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
@ -154,17 +90,16 @@ fn command_lock_tokens(
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
||||||
|
|
||||||
let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
|
let bridge_key = Bridge::derive_bridge_id(bridge)?;
|
||||||
let bridge_key = Bridge::derive_bridge_id(&p)?;
|
|
||||||
|
|
||||||
// Check whether we can find wrapped asset meta for the given token
|
// 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_info = config.rpc_client.get_account(&wrapped_key).or_else(Err)?;
|
||||||
let wrapped_meta: &WrappedAssetMeta =
|
let wrapped_meta: &WrappedAssetMeta =
|
||||||
Bridge::unpack_unchecked_immutable(wrapped_info.data.as_slice())?;
|
Bridge::unpack_unchecked_immutable(wrapped_info.data.as_slice())?;
|
||||||
|
|
||||||
let ix = transfer_out(
|
let ix = transfer_out(
|
||||||
&p,
|
bridge,
|
||||||
&config.owner.pubkey(),
|
&config.owner.pubkey(),
|
||||||
&account,
|
&account,
|
||||||
&token,
|
&token,
|
||||||
|
@ -200,26 +135,8 @@ fn command_lock_tokens(
|
||||||
amount,
|
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 =
|
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()?;
|
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
|
||||||
check_fee_payer_balance(
|
check_fee_payer_balance(
|
||||||
|
@ -230,15 +147,14 @@ fn command_lock_tokens(
|
||||||
Ok(Some(transaction))
|
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");
|
println!("Submitting VAA");
|
||||||
|
|
||||||
let minimum_balance_for_rent_exemption = config
|
let minimum_balance_for_rent_exemption = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
.get_minimum_balance_for_rent_exemption(size_of::<Mint>())?;
|
||||||
|
|
||||||
let p = Pubkey::from_str("7AeSppn3AjaeYScZsnRf1ZRQvtyo4Ke5gx7PAJ3r7BFp").unwrap();
|
let ix = post_vaa(bridge, &config.owner.pubkey(), vaa)?;
|
||||||
let ix = post_vaa(&p, &config.owner.pubkey(), vaa)?;
|
|
||||||
|
|
||||||
let mut transaction = Transaction::new_with_payer(&[ix], Some(&config.fee_payer.pubkey()));
|
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))
|
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 {
|
fn command_create_token(config: &Config, decimals: u8) -> CommmandResult {
|
||||||
let token = Keypair::new();
|
let token = Keypair::new();
|
||||||
println!("Creating token {}", token.pubkey());
|
println!("Creating token {}", token.pubkey());
|
||||||
|
@ -367,39 +313,12 @@ fn command_transfer(
|
||||||
ui_amount, sender, recipient
|
ui_amount, sender, recipient
|
||||||
);
|
);
|
||||||
|
|
||||||
let sender_token_account = config
|
let sender_token_balance = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_token_account_with_commitment(&sender, config.commitment_config)?
|
.get_token_account_balance_with_commitment(&sender, config.commitment_config)?
|
||||||
.value;
|
|
||||||
let recipient_token_account = config
|
|
||||||
.rpc_client
|
|
||||||
.get_token_account_with_commitment(&recipient, config.commitment_config)?
|
|
||||||
.value;
|
.value;
|
||||||
|
|
||||||
let decimals = match (sender_token_account, recipient_token_account) {
|
let amount = spl_token::ui_amount_to_amount(ui_amount, sender_token_balance.decimals);
|
||||||
(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 mut transaction = Transaction::new_with_payer(
|
let mut transaction = Transaction::new_with_payer(
|
||||||
&[transfer(
|
&[transfer(
|
||||||
|
@ -422,25 +341,12 @@ fn command_transfer(
|
||||||
fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommmandResult {
|
fn command_burn(config: &Config, source: Pubkey, ui_amount: f64) -> CommmandResult {
|
||||||
println!("Burn {} tokens\n Source: {}", ui_amount, source);
|
println!("Burn {} tokens\n Source: {}", ui_amount, source);
|
||||||
|
|
||||||
let source_token_account = config
|
let source_token_balance = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_token_account_with_commitment(&source, config.commitment_config)?
|
.get_token_account_balance_with_commitment(&source, config.commitment_config)?
|
||||||
.value;
|
.value;
|
||||||
|
|
||||||
let decimals = match source_token_account {
|
let amount = spl_token::ui_amount_to_amount(ui_amount, source_token_balance.decimals);
|
||||||
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 mut transaction = Transaction::new_with_payer(
|
let mut transaction = Transaction::new_with_payer(
|
||||||
&[burn(
|
&[burn(
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
|
@ -469,24 +375,11 @@ fn command_mint(
|
||||||
ui_amount, token, recipient
|
ui_amount, token, recipient
|
||||||
);
|
);
|
||||||
|
|
||||||
let recipient_token_account = config
|
let recipient_token_balance = config
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_token_account_with_commitment(&recipient, config.commitment_config)?
|
.get_token_account_balance_with_commitment(&recipient, config.commitment_config)?
|
||||||
.value;
|
.value;
|
||||||
|
let amount = spl_token::ui_amount_to_amount(ui_amount, recipient_token_balance.decimals);
|
||||||
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 mut transaction = Transaction::new_with_payer(
|
let mut transaction = Transaction::new_with_payer(
|
||||||
&[mint_to(
|
&[mint_to(
|
||||||
|
@ -575,7 +468,11 @@ fn command_balance(config: &Config, address: Pubkey) -> CommmandResult {
|
||||||
.rpc_client
|
.rpc_client
|
||||||
.get_token_account_balance_with_commitment(&address, config.commitment_config)?
|
.get_token_account_balance_with_commitment(&address, config.commitment_config)?
|
||||||
.value;
|
.value;
|
||||||
println!("{}", balance.ui_amount);
|
|
||||||
|
println!("ui amount: {}", balance.ui_amount);
|
||||||
|
println!("decimals: {}", balance.decimals);
|
||||||
|
println!("amount: {}", balance.amount);
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,16 +504,28 @@ fn command_accounts(config: &Config, token: Option<Pubkey>) -> CommmandResult {
|
||||||
|
|
||||||
println!("Account Token Balance");
|
println!("Account Token Balance");
|
||||||
println!("-------------------------------------------------------------------------------------------------");
|
println!("-------------------------------------------------------------------------------------------------");
|
||||||
for (address, account) in accounts {
|
for keyed_account in accounts {
|
||||||
let balance = match config
|
let address = keyed_account.pubkey;
|
||||||
.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);
|
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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -901,16 +810,41 @@ fn main() {
|
||||||
.help("The address of the token account to unwrap"),
|
.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(
|
||||||
SubCommand::with_name("lock")
|
SubCommand::with_name("lock")
|
||||||
.about("Transfer tokens to another chain")
|
.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(
|
||||||
Arg::with_name("sender")
|
Arg::with_name("sender")
|
||||||
.validator(is_pubkey_or_keypair)
|
.validator(is_pubkey_or_keypair)
|
||||||
.value_name("SENDER_TOKEN_ACCOUNT_ADDRESS")
|
.value_name("SENDER_TOKEN_ACCOUNT_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(1)
|
.index(2)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The token account address of the sender"),
|
.help("The token account address of the sender"),
|
||||||
)
|
)
|
||||||
|
@ -919,7 +853,7 @@ fn main() {
|
||||||
.validator(is_pubkey_or_keypair)
|
.validator(is_pubkey_or_keypair)
|
||||||
.value_name("TOKEN_ADDRESS")
|
.value_name("TOKEN_ADDRESS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(2)
|
.index(3)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The mint address"),
|
.help("The mint address"),
|
||||||
)
|
)
|
||||||
|
@ -928,7 +862,7 @@ fn main() {
|
||||||
.validator(is_amount)
|
.validator(is_amount)
|
||||||
.value_name("AMOUNT")
|
.value_name("AMOUNT")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(3)
|
.index(4)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Amount to transfer out"),
|
.help("Amount to transfer out"),
|
||||||
)
|
)
|
||||||
|
@ -937,7 +871,7 @@ fn main() {
|
||||||
.validator(is_u8)
|
.validator(is_u8)
|
||||||
.value_name("CHAIN")
|
.value_name("CHAIN")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(4)
|
.index(5)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Chain to transfer to"),
|
.help("Chain to transfer to"),
|
||||||
)
|
)
|
||||||
|
@ -946,7 +880,7 @@ fn main() {
|
||||||
.validator(is_u8)
|
.validator(is_u8)
|
||||||
.value_name("NONCE")
|
.value_name("NONCE")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(5)
|
.index(6)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Nonce of the transfer"),
|
.help("Nonce of the transfer"),
|
||||||
),
|
),
|
||||||
|
@ -954,12 +888,24 @@ fn main() {
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("postvaa")
|
SubCommand::with_name("postvaa")
|
||||||
.about("Submit a VAA to the chain")
|
.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(
|
||||||
Arg::with_name("vaa")
|
Arg::with_name("vaa")
|
||||||
.validator(is_hex)
|
.validator(is_hex)
|
||||||
.value_name("HEX_VAA")
|
.value_name("HEX_VAA")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.index(1)
|
.index(2)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("The vaa to be posted"),
|
.help("The vaa to be posted"),
|
||||||
)
|
)
|
||||||
|
@ -1046,19 +992,26 @@ fn main() {
|
||||||
let token = pubkey_of(arg_matches, "token");
|
let token = pubkey_of(arg_matches, "token");
|
||||||
command_accounts(&config, 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)) => {
|
("lock", Some(arg_matches)) => {
|
||||||
|
let bridge = pubkey_of(arg_matches, "bridge").unwrap();
|
||||||
let account = pubkey_of(arg_matches, "sender").unwrap();
|
let account = pubkey_of(arg_matches, "sender").unwrap();
|
||||||
let amount = value_t_or_exit!(arg_matches, "amount", u64);
|
let amount = value_t_or_exit!(arg_matches, "amount", u64);
|
||||||
let nonce = value_t_or_exit!(arg_matches, "nonce", u32);
|
let nonce = value_t_or_exit!(arg_matches, "nonce", u32);
|
||||||
let chain = value_t_or_exit!(arg_matches, "chain", u8);
|
let chain = value_t_or_exit!(arg_matches, "chain", u8);
|
||||||
let token = pubkey_of(arg_matches, "token").unwrap();
|
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)) => {
|
("postvaa", Some(arg_matches)) => {
|
||||||
|
let bridge = pubkey_of(arg_matches, "bridge").unwrap();
|
||||||
let vaa_string: String = value_of(arg_matches, "vaa").unwrap();
|
let vaa_string: String = value_of(arg_matches, "vaa").unwrap();
|
||||||
let vaa = hex::decode(vaa_string).unwrap();
|
let vaa = hex::decode(vaa_string).unwrap();
|
||||||
command_submit_vaa(&config, vaa.as_slice())
|
command_submit_vaa(&config, &bridge, vaa.as_slice())
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ IDEA additional info:
|
||||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
<+>UTF-8
|
<+>UTF-8
|
||||||
===================================================================
|
===================================================================
|
||||||
--- Cargo.lock (revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
|
--- Cargo.lock (revision d84010e4afe5f79c812ff7da349460dc690a8392)
|
||||||
+++ Cargo.lock (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
+++ Cargo.lock (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
@@ -274,12 +274,22 @@
|
@@ -274,12 +274,22 @@
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||||
|
@ -22,7 +22,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||||
+dependencies = [
|
+dependencies = [
|
||||||
+ "block-padding 0.2.0",
|
+ "block-padding 0.2.1",
|
||||||
+ "generic-array 0.14.3",
|
+ "generic-array 0.14.3",
|
||||||
+]
|
+]
|
||||||
+
|
+
|
||||||
|
@ -35,9 +35,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
|
|
||||||
+[[package]]
|
+[[package]]
|
||||||
+name = "block-padding"
|
+name = "block-padding"
|
||||||
+version = "0.2.0"
|
+version = "0.2.1"
|
||||||
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
+source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
+checksum = "c98bfd7c112b6399fef97cc0614af1cd375b27a112e552ce60f94c1b5f13cb74"
|
+checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
||||||
+
|
+
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bs58"
|
name = "bs58"
|
||||||
|
@ -189,7 +189,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3376,13 +3458,17 @@
|
@@ -3376,12 +3458,16 @@
|
||||||
name = "solana-bpf-loader-program"
|
name = "solana-bpf-loader-program"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
@ -197,7 +197,6 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
"bincode",
|
"bincode",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
+ "hex",
|
+ "hex",
|
||||||
"jemalloc-sys",
|
|
||||||
+ "libsecp256k1",
|
+ "libsecp256k1",
|
||||||
"num-derive 0.3.0",
|
"num-derive 0.3.0",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
@ -212,9 +211,9 @@ IDEA additional info:
|
||||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
<+>UTF-8
|
<+>UTF-8
|
||||||
===================================================================
|
===================================================================
|
||||||
--- programs/bpf_loader/Cargo.toml (revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
|
--- programs/bpf_loader/Cargo.toml (revision d84010e4afe5f79c812ff7da349460dc690a8392)
|
||||||
+++ programs/bpf_loader/Cargo.toml (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
+++ programs/bpf_loader/Cargo.toml (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
@@ -18,6 +18,10 @@
|
@@ -17,6 +17,10 @@
|
||||||
solana-sdk = { path = "../../sdk", version = "1.4.0" }
|
solana-sdk = { path = "../../sdk", version = "1.4.0" }
|
||||||
solana_rbpf = "=0.1.28"
|
solana_rbpf = "=0.1.28"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
@ -230,8 +229,8 @@ IDEA additional info:
|
||||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
<+>UTF-8
|
<+>UTF-8
|
||||||
===================================================================
|
===================================================================
|
||||||
--- programs/bpf_loader/src/crypto.rs (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
--- programs/bpf_loader/src/crypto.rs (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
+++ programs/bpf_loader/src/crypto.rs (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
+++ programs/bpf_loader/src/crypto.rs (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
@@ -0,0 +1,171 @@
|
@@ -0,0 +1,171 @@
|
||||||
+pub extern crate secp256k1;
|
+pub extern crate secp256k1;
|
||||||
+
|
+
|
||||||
|
@ -255,7 +254,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+
|
+
|
||||||
+#[repr(C)]
|
+#[repr(C)]
|
||||||
+pub struct EcrecoverOutput {
|
+pub struct EcrecoverOutput {
|
||||||
+ pub address: [u8; 32],
|
+ pub address: [u8; 20],
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#[repr(C)]
|
+#[repr(C)]
|
||||||
|
@ -409,27 +408,27 @@ IDEA additional info:
|
||||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
<+>UTF-8
|
<+>UTF-8
|
||||||
===================================================================
|
===================================================================
|
||||||
--- programs/bpf_loader/src/lib.rs (revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
|
--- programs/bpf_loader/src/lib.rs (revision d84010e4afe5f79c812ff7da349460dc690a8392)
|
||||||
+++ programs/bpf_loader/src/lib.rs (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
+++ programs/bpf_loader/src/lib.rs (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
@@ -2,6 +2,10 @@
|
@@ -4,6 +4,10 @@
|
||||||
pub mod allocator_bump;
|
pub mod deprecated;
|
||||||
pub mod bpf_verifier;
|
pub mod serialization;
|
||||||
pub mod syscalls;
|
pub mod syscalls;
|
||||||
+pub mod crypto;
|
+pub mod crypto;
|
||||||
+
|
+
|
||||||
+#[macro_use]
|
+#[macro_use]
|
||||||
+extern crate arrayref;
|
+extern crate arrayref;
|
||||||
|
|
||||||
use crate::{bpf_verifier::VerifierError, syscalls::SyscallError};
|
use crate::{
|
||||||
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
bpf_verifier::VerifierError,
|
||||||
Index: programs/bpf_loader/src/syscalls.rs
|
Index: programs/bpf_loader/src/syscalls.rs
|
||||||
IDEA additional info:
|
IDEA additional info:
|
||||||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
<+>UTF-8
|
<+>UTF-8
|
||||||
===================================================================
|
===================================================================
|
||||||
--- programs/bpf_loader/src/syscalls.rs (revision 17645ee20c12b9f1e0002b0453b523f1f9ce0ecb)
|
--- programs/bpf_loader/src/syscalls.rs (revision d84010e4afe5f79c812ff7da349460dc690a8392)
|
||||||
+++ programs/bpf_loader/src/syscalls.rs (revision 5f9aa6f91128def4b9a6f75fc107a753156deb73)
|
+++ programs/bpf_loader/src/syscalls.rs (revision aa30fbafe08be98cfbea6772040d5f3b073877b0)
|
||||||
@@ -1,10 +1,22 @@
|
@@ -1,10 +1,23 @@
|
||||||
-use crate::{alloc, BPFError};
|
-use crate::{alloc, BPFError};
|
||||||
-use alloc::Alloc;
|
-use alloc::Alloc;
|
||||||
+use std::{
|
+use std::{
|
||||||
|
@ -443,6 +442,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+use secp256k1::{Error, PublicKey, RecoveryId, Signature};
|
+use secp256k1::{Error, PublicKey, RecoveryId, Signature};
|
||||||
|
+use sha3::Digest;
|
||||||
use solana_rbpf::{
|
use solana_rbpf::{
|
||||||
- ebpf::{EbpfError, SyscallObject, ELF_INSN_DUMP_OFFSET, MM_HEAP_START},
|
- ebpf::{EbpfError, SyscallObject, ELF_INSN_DUMP_OFFSET, MM_HEAP_START},
|
||||||
- memory_region::{translate_addr, MemoryRegion},
|
- 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_runtime::message_processor::MessageProcessor;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
@@ -18,16 +30,17 @@
|
@@ -18,16 +31,16 @@
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::{Pubkey, PubkeyError},
|
pubkey::{Pubkey, PubkeyError},
|
||||||
};
|
};
|
||||||
|
@ -480,13 +480,12 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+/// Simple bump allocator, never frees
|
+/// Simple bump allocator, never frees
|
||||||
+use crate::allocator_bump::BPFAllocator;
|
+use crate::allocator_bump::BPFAllocator;
|
||||||
+use crate::crypto::{EcrecoverInput, EcrecoverOutput, SchnorrifyInput};
|
+use crate::crypto::{EcrecoverInput, EcrecoverOutput, SchnorrifyInput};
|
||||||
+use sha3::Digest;
|
|
||||||
|
|
||||||
/// Error definitions
|
/// Error definitions
|
||||||
#[derive(Debug, ThisError)]
|
#[derive(Debug, ThisError)]
|
||||||
@@ -51,20 +64,13 @@
|
@@ -53,20 +66,13 @@
|
||||||
#[error("Cross-program invocation with unauthorized signer or writable account")]
|
#[error("Unaligned pointer")]
|
||||||
PrivilegeEscalation,
|
UnalignedPointer,
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
impl From<SyscallError> for EbpfError<BPFError> {
|
impl From<SyscallError> for EbpfError<BPFError> {
|
||||||
|
@ -506,7 +505,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
/// Default program heap size, allocators
|
/// Default program heap size, allocators
|
||||||
/// are expected to enforce this
|
/// are expected to enforce this
|
||||||
const DEFAULT_HEAP_SIZE: usize = 32 * 1024;
|
const DEFAULT_HEAP_SIZE: usize = 32 * 1024;
|
||||||
@@ -112,6 +118,20 @@
|
@@ -114,6 +120,20 @@
|
||||||
invoke_context: invoke_context.clone(),
|
invoke_context: invoke_context.clone(),
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
|
@ -527,7 +526,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
|
|
||||||
// Memory allocator
|
// Memory allocator
|
||||||
let heap = vec![0_u8; DEFAULT_HEAP_SIZE];
|
let heap = vec![0_u8; DEFAULT_HEAP_SIZE];
|
||||||
@@ -246,6 +266,7 @@
|
@@ -256,6 +276,7 @@
|
||||||
pub struct SyscallLog {
|
pub struct SyscallLog {
|
||||||
logger: Rc<RefCell<dyn Logger>>,
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
}
|
}
|
||||||
|
@ -535,7 +534,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
impl SyscallObject<BPFError> for SyscallLog {
|
impl SyscallObject<BPFError> for SyscallLog {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -275,6 +296,7 @@
|
@@ -285,6 +306,7 @@
|
||||||
pub struct SyscallLogU64 {
|
pub struct SyscallLogU64 {
|
||||||
logger: Rc<RefCell<dyn Logger>>,
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
}
|
}
|
||||||
|
@ -543,7 +542,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
impl SyscallObject<BPFError> for SyscallLogU64 {
|
impl SyscallObject<BPFError> for SyscallLogU64 {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -309,6 +331,7 @@
|
@@ -319,6 +341,7 @@
|
||||||
pub struct SyscallSolAllocFree {
|
pub struct SyscallSolAllocFree {
|
||||||
allocator: BPFAllocator,
|
allocator: BPFAllocator,
|
||||||
}
|
}
|
||||||
|
@ -551,7 +550,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
impl SyscallObject<BPFError> for SyscallSolAllocFree {
|
impl SyscallObject<BPFError> for SyscallSolAllocFree {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -363,6 +386,103 @@
|
@@ -373,6 +396,105 @@
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +605,9 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+ match secp256k1::recover(&secp256k1::Message::parse(&input.message), &signature,
|
+ match secp256k1::recover(&secp256k1::Message::parse(&input.message), &signature,
|
||||||
+ &recovery_id) {
|
+ &recovery_id) {
|
||||||
+ Ok(v) => {
|
+ 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(_) => {
|
+ Err(_) => {
|
||||||
+ return Ok(0);
|
+ return Ok(0);
|
||||||
|
@ -654,8 +655,8 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
+
|
+
|
||||||
// Cross-program invocation syscalls
|
// Cross-program invocation syscalls
|
||||||
|
|
||||||
pub type TranslatedAccounts<'a> = (Vec<Rc<RefCell<Account>>>, Vec<(&'a mut u64, &'a mut [u8])>);
|
struct AccountReferences<'a> {
|
||||||
@@ -398,6 +518,7 @@
|
@@ -415,6 +537,7 @@
|
||||||
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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> {
|
impl<'a> SyscallProcessInstruction<'a> for SyscallProcessInstructionRust<'a> {
|
||||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
||||||
self.invoke_context
|
self.invoke_context
|
||||||
@@ -419,7 +540,7 @@
|
@@ -436,7 +559,7 @@
|
||||||
ix.accounts.len(),
|
ix.accounts.len(),
|
||||||
ro_regions
|
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();
|
let data = translate_slice!(u8, ix.data.as_ptr(), ix.data.len(), ro_regions)?.to_vec();
|
||||||
Ok(Instruction {
|
Ok(Instruction {
|
||||||
program_id: ix.program_id,
|
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> {
|
impl<'a> SyscallObject<BPFError> for SyscallProcessInstructionRust<'a> {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -593,6 +715,7 @@
|
@@ -626,6 +750,7 @@
|
||||||
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
callers_keyed_accounts: &'a [KeyedAccount<'a>],
|
||||||
invoke_context: Rc<RefCell<&'a mut dyn InvokeContext>>,
|
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> {
|
impl<'a> SyscallProcessInstruction<'a> for SyscallProcessSolInstructionC<'a> {
|
||||||
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
fn get_context_mut(&self) -> Result<RefMut<&'a mut dyn InvokeContext>, EbpfError<BPFError>> {
|
||||||
self.invoke_context
|
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> {
|
impl<'a> SyscallObject<BPFError> for SyscallProcessSolInstructionC<'a> {
|
||||||
fn call(
|
fn call(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -769,10 +893,10 @@
|
@@ -814,10 +940,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if account.is_signer && // If message indicates account is signed
|
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());
|
return Err(SyscallError::PrivilegeEscalation.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -851,7 +975,7 @@
|
@@ -1034,7 +1160,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 @@
|
|
||||||
assert_eq!(string, "Gaggablaghblagh!");
|
assert_eq!(string, "Gaggablaghblagh!");
|
||||||
Ok(42)
|
Ok(42)
|
||||||
})
|
})
|
||||||
|
@ -741,7 +721,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,7 +1128,7 @@
|
@@ -1066,7 +1192,7 @@
|
||||||
&[ro_region],
|
&[ro_region],
|
||||||
&[rw_region],
|
&[rw_region],
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,13 +6,12 @@ RUN rustup component add rustfmt
|
||||||
|
|
||||||
WORKDIR /usr/src/solana
|
WORKDIR /usr/src/solana
|
||||||
|
|
||||||
RUN git clone https://github.com/solana-labs/solana --depth=1 --branch master && \
|
RUN git clone https://github.com/jackcmay/solana --depth=1 --branch cpi-create-account && \
|
||||||
cd solana && git checkout 6c5b8f324a6e668c4bf7555747fdb499974f0ac3
|
cd solana
|
||||||
|
|
||||||
ADD *.patch .
|
ADD *.patch .
|
||||||
|
|
||||||
RUN cd solana && patch -p1 < ../Add_crypto_syscalls.patch
|
RUN cd solana && patch -p0 < ../Add_crypto_syscalls.patch
|
||||||
RUN cd solana && curl -L https://patch-diff.githubusercontent.com/raw/solana-labs/solana/pull/11649.patch | patch -p1
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \
|
RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \
|
||||||
--mount=type=cache,target=solana/target \
|
--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
|
cp ./target/release/deps/*.so /opt/solana/deps
|
||||||
|
|
||||||
ENV PATH="/opt/solana:${PATH}"
|
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"]
|
CMD ["/usr/src/solana/solana/run.sh"]
|
||||||
|
|
Loading…
Reference in New Issue