From 057b195d654ae43e8f8f567c48bcaff5c72b075e Mon Sep 17 00:00:00 2001 From: eloylp Date: Fri, 19 Apr 2024 18:54:39 -0500 Subject: [PATCH 01/10] Add workflow for ampd deployment --- .github/workflows/ampd-deployment.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/ampd-deployment.yml diff --git a/.github/workflows/ampd-deployment.yml b/.github/workflows/ampd-deployment.yml new file mode 100644 index 000000000..e1cbfda43 --- /dev/null +++ b/.github/workflows/ampd-deployment.yml @@ -0,0 +1,67 @@ +name: Ampd deployment +on: + push: + branches: + - "main" + paths: + - "ampd/**" + +env: + # If one change any variable of this env block, all of them needs to be aligned, as + # we cannot re-user them. + IMAGE_NAME: ampd + IMAGE_VERSION: ${{ github.sha }} + IMAGE_ID: solanaaxelartestnetregistry.azurecr.io/solana-axelar/ampd + DEPLOYING_IMAGE_FQDN: solanaaxelartestnetregistry.azurecr.io/solana-axelar/ampd:${{ github.sha }} + +jobs: + + docker-image: + needs: code-checks + runs-on: ubuntu-latest + name: "Build and push docker image" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: true + cache-on-failure: true + workspaces: "ampd -> target" + shared-key: "ampd" + + - name: Build image + run: docker build . --file ampd/Dockerfile --tag $IMAGE_NAME --tag latest + + - name: Login to Azure Container Registry + uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.ACR_REGISTRY_NAME }}.azurecr.io + username: ${{ secrets.AZ_SP_CLIENT_ID }} + password: ${{ secrets.AZ_SP_CLIENT_SECRET }} + + - name: Push image + run: | + docker tag $IMAGE_NAME $IMAGE_ID:$IMAGE_VERSION + docker tag $IMAGE_NAME $IMAGE_ID:latest + docker push $DEPLOYING_IMAGE_FQDN + + deployment: + needs: docker-image + runs-on: ubuntu-latest + name: "Deploy to k8s cluster" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: azure/setup-kubectl@v2.0 + + - uses: Azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBE_CONFIG }} + context: solanaaxelartestnetk8s + + - name: Deploy image in k8s + run: kubectl set image deployment/ampd ampd=${{ env.DEPLOYING_IMAGE_FQDN }} \ No newline at end of file From fa5264e1141a6ca3b4705f26c4b5f12ab60b6518 Mon Sep 17 00:00:00 2001 From: eloylp Date: Mon, 29 Apr 2024 14:54:10 -0500 Subject: [PATCH 02/10] be able to test the ci in the current branch --- .github/workflows/ampd-deployment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ampd-deployment.yml b/.github/workflows/ampd-deployment.yml index e1cbfda43..6a11eb6ce 100644 --- a/.github/workflows/ampd-deployment.yml +++ b/.github/workflows/ampd-deployment.yml @@ -2,7 +2,7 @@ name: Ampd deployment on: push: branches: - - "main" + - "ampd-deployment-k8s" paths: - "ampd/**" From b99d5db7098393cdc26d0bb1055bc84f2fb4e05b Mon Sep 17 00:00:00 2001 From: eloylp Date: Mon, 29 Apr 2024 14:58:05 -0500 Subject: [PATCH 03/10] Add dummy type for the CI --- ampd/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index e70b1ee4d..dbb58dc1b 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -103,3 +103,6 @@ curve25519-dalek = { git = "https://github.com/dalek-cryptography/curve25519-dal ahash = "=0.8.6" [lints] workspace = true + + +## dummy change for trigger the CI \ No newline at end of file From 9f59867fc3360465206a81379c4d551c3f2e00df Mon Sep 17 00:00:00 2001 From: eloylp Date: Mon, 29 Apr 2024 15:06:15 -0500 Subject: [PATCH 04/10] Fix ci dependency error --- .github/workflows/ampd-deployment.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ampd-deployment.yml b/.github/workflows/ampd-deployment.yml index 6a11eb6ce..6d4f33db3 100644 --- a/.github/workflows/ampd-deployment.yml +++ b/.github/workflows/ampd-deployment.yml @@ -15,9 +15,7 @@ env: DEPLOYING_IMAGE_FQDN: solanaaxelartestnetregistry.azurecr.io/solana-axelar/ampd:${{ github.sha }} jobs: - docker-image: - needs: code-checks runs-on: ubuntu-latest name: "Build and push docker image" steps: @@ -64,4 +62,4 @@ jobs: context: solanaaxelartestnetk8s - name: Deploy image in k8s - run: kubectl set image deployment/ampd ampd=${{ env.DEPLOYING_IMAGE_FQDN }} \ No newline at end of file + run: kubectl set image deployment/ampd ampd=${{ env.DEPLOYING_IMAGE_FQDN }} From 1b1d891eef7350e8ccb92a249b6b1d4d88cda43b Mon Sep 17 00:00:00 2001 From: eloylp Date: Mon, 29 Apr 2024 15:07:16 -0500 Subject: [PATCH 05/10] ci trigger2 --- ampd/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index dbb58dc1b..b4724701f 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -105,4 +105,4 @@ ahash = "=0.8.6" workspace = true -## dummy change for trigger the CI \ No newline at end of file +## dummy change for trigger the CI2 From 1192a03a5ce059419e40dca1e9946b3e231d9993 Mon Sep 17 00:00:00 2001 From: eloylp Date: Mon, 29 Apr 2024 15:21:54 -0500 Subject: [PATCH 06/10] Move dependency for public fetching --- Cargo.lock | 99 +++++++++++++++++++++++++++++++++---------------- ampd/Cargo.toml | 5 +-- 2 files changed, 68 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cade1a4ec..bb0b86f66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,7 +115,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -140,7 +140,7 @@ dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -803,19 +803,29 @@ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axelar-message-primitives" version = "0.1.0" -source = "git+ssh://git@github.com/eigerco/solana-axelar.git?branch=poc#f6f328fd17c39ba09e53219dd837b91483d10a66" +source = "git+https://github.com/eigerco/solana-axelar.git#7a44db9c243afb4eac4890f8f56e31cc9d9f7f11" dependencies = [ + "anyhow", + "bcs", + "bnum", "borsh 1.4.0", + "bytemuck", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", + "cosmwasm-schema 2.0.2", + "ethers-core", "hex", + "itertools 0.12.1", + "libsecp256k1 0.7.1", + "sha3 0.10.8", "solana-program", + "thiserror", ] [[package]] name = "axelar-wasm-std" version = "0.1.0" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -840,7 +850,7 @@ name = "axelar-wasm-std" version = "0.1.0" source = "git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f#c0904e1c72c99a174a93b5f6c18b30f52d20b71f" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -1890,7 +1900,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -1919,7 +1929,7 @@ source = "git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c9 dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -1942,7 +1952,7 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-storage-plus 1.2.0", "error-stack", @@ -2141,7 +2151,20 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ - "cosmwasm-schema-derive", + "cosmwasm-schema-derive 1.5.3", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dbdb5800ca67f2f2f938d67db59a7c5434af133c3e508779a4df7a9b5d533b" +dependencies = [ + "cosmwasm-schema-derive 2.0.2", "schemars", "serde", "serde_json", @@ -2159,6 +2182,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmwasm-schema-derive" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ee47cf29f7688ebfa6ade8ddabcf51fc153f1157a3b46f5b4b1ce7a0316fdf" +dependencies = [ + "proc-macro2 1.0.79", + "quote 1.0.35", + "syn 1.0.109", +] + [[package]] name = "cosmwasm-std" version = "1.5.3" @@ -2411,7 +2445,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ae0b69fa7679de78825b4edeeec045066aa2b2c4b6e063d80042e565bb4da5c" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw2 0.15.1", "schemars", @@ -2426,7 +2460,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw2 1.1.2", "schemars", @@ -2441,7 +2475,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5abb8ecea72e09afff830252963cb60faf945ce6cef2c20a43814516082653da" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-storage-plus 0.15.1", "schemars", @@ -2454,7 +2488,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-storage-plus 1.2.0", "schemars", @@ -3950,7 +3984,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -3975,7 +4009,7 @@ dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -3994,7 +4028,7 @@ name = "gateway-api" version = "0.1.0" dependencies = [ "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", ] [[package]] @@ -4082,7 +4116,7 @@ dependencies = [ [[package]] name = "gmp-gateway" version = "0.1.0" -source = "git+ssh://git@github.com/eigerco/solana-axelar.git?branch=poc#f6f328fd17c39ba09e53219dd837b91483d10a66" +source = "git+https://github.com/eigerco/solana-axelar.git#7a44db9c243afb4eac4890f8f56e31cc9d9f7f11" dependencies = [ "anyhow", "axelar-message-primitives", @@ -4093,6 +4127,7 @@ dependencies = [ "borsh 1.4.0", "bytemuck", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", + "cosmwasm-schema 2.0.2", "cosmwasm-std", "hex", "itertools 0.12.1", @@ -4681,7 +4716,7 @@ dependencies = [ "axelar-wasm-std-derive 0.1.0", "connection-router 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -5269,7 +5304,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -5757,7 +5792,7 @@ dependencies = [ "axelar-wasm-std-derive 0.1.0", "connection-router-api", "cosmwasm-crypto", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -5786,7 +5821,7 @@ dependencies = [ "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "cosmwasm-crypto", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -5812,7 +5847,7 @@ dependencies = [ "axelar-wasm-std-derive 0.1.0", "bcs", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -5849,7 +5884,7 @@ dependencies = [ "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "bcs", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -6032,7 +6067,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-storage-plus 1.2.0", "error-stack", @@ -7129,7 +7164,7 @@ dependencies = [ [[package]] name = "program-utils" version = "0.1.0" -source = "git+ssh://git@github.com/eigerco/solana-axelar.git?branch=poc#f6f328fd17c39ba09e53219dd837b91483d10a66" +source = "git+https://github.com/eigerco/solana-axelar.git#7a44db9c243afb4eac4890f8f56e31cc9d9f7f11" dependencies = [ "borsh 1.4.0", "solana-program", @@ -7720,7 +7755,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", @@ -7739,7 +7774,7 @@ source = "git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c9 dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cw-storage-plus 1.2.0", "error-stack", @@ -8467,7 +8502,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -8489,7 +8524,7 @@ dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", @@ -8630,7 +8665,7 @@ dependencies = [ name = "signature-verifier-api" version = "0.1.0" dependencies = [ - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "error-stack", @@ -11291,7 +11326,7 @@ dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", "connection-router-api", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-multi-test", @@ -11317,7 +11352,7 @@ dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "axelar-wasm-std-derive 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "cosmwasm-schema", + "cosmwasm-schema 1.5.3", "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index b4724701f..c57751665 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -74,7 +74,7 @@ url = "2.3.1" valuable = { version = "0.1.0", features = ["derive"] } valuable-serde = { version = "0.1.0", features = ["std"] } voting-verifier = { workspace = true } -gmp-gateway = { git = "ssh://git@github.com/eigerco/solana-axelar.git", branch = "poc" } +gmp-gateway = { git = "https://github.com/eigerco/solana-axelar.git" } lru = "0.12.3" [dev-dependencies] @@ -103,6 +103,3 @@ curve25519-dalek = { git = "https://github.com/dalek-cryptography/curve25519-dal ahash = "=0.8.6" [lints] workspace = true - - -## dummy change for trigger the CI2 From f085785542045aee51d88fdf5e074e28a963a463 Mon Sep 17 00:00:00 2001 From: eloylp Date: Tue, 30 Apr 2024 16:13:25 -0500 Subject: [PATCH 07/10] Align Solana code with latest solana-axelar changes --- Cargo.lock | 1 + ampd/Cargo.toml | 1 + ampd/src/handlers/solana_verify_msg.rs | 2 +- ampd/src/handlers/solana_verify_worker_set.rs | 35 ++--- ampd/src/solana/msg_verifier.rs | 32 +++-- ampd/src/solana/ws_verifier.rs | 134 +++--------------- 6 files changed, 56 insertions(+), 149 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb0b86f66..d9fc5d763 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -219,6 +219,7 @@ name = "ampd" version = "0.1.0" dependencies = [ "async-trait", + "axelar-message-primitives", "axelar-wasm-std 0.1.0", "base64 0.21.7", "bcs", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index c57751665..35438d611 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -75,6 +75,7 @@ valuable = { version = "0.1.0", features = ["derive"] } valuable-serde = { version = "0.1.0", features = ["std"] } voting-verifier = { workspace = true } gmp-gateway = { git = "https://github.com/eigerco/solana-axelar.git" } +axelar-message-primitives = { git = "https://github.com/eigerco/solana-axelar.git" } lru = "0.12.3" [dev-dependencies] diff --git a/ampd/src/handlers/solana_verify_msg.rs b/ampd/src/handlers/solana_verify_msg.rs index bef1088b6..a797bb133 100644 --- a/ampd/src/handlers/solana_verify_msg.rs +++ b/ampd/src/handlers/solana_verify_msg.rs @@ -273,7 +273,7 @@ mod test { let expiration = 100u64; let (_, rx) = watch::channel(expiration - 1); let source_chain = ChainName::from_str("solana").unwrap(); - let poll_started_source_chain = ChainName::from_str("other_chain").unwrap(); // A different, unexpected source chain. + let poll_started_source_chain = ChainName::from_str("otherchain").unwrap(); // A different, unexpected source chain. // Prepare the message verifier and the vote broadcaster let mut broadcast_client = MockBroadcasterClient::new(); diff --git a/ampd/src/handlers/solana_verify_worker_set.rs b/ampd/src/handlers/solana_verify_worker_set.rs index 970222474..7b9e058be 100644 --- a/ampd/src/handlers/solana_verify_worker_set.rs +++ b/ampd/src/handlers/solana_verify_worker_set.rs @@ -1,5 +1,7 @@ +use std::borrow::Cow; use std::convert::TryInto; +use axelar_message_primitives::command::TransferOperatorshipCommand; use cosmrs::cosmwasm::MsgExecuteContract; use error_stack::ResultExt; use serde::Deserialize; @@ -194,10 +196,17 @@ where let gw_event = parse_gateway_event(&sol_tx).map_err(|_| Error::DeserializeEvent)?; - let pub_key = match gw_event { - GatewayEvent::OperatorshipTransferred { - info_account_address, - } => info_account_address, + let operators = match gw_event { + GatewayEvent::OperatorshipTransferred(Cow::Owned(TransferOperatorshipCommand { + operators, + weights, + quorum, + .. + })) => axelar_message_primitives::command::Operators::new( + operators, + weights.into_iter().map(axelar_message_primitives::command::U256::from).collect(), + axelar_message_primitives::command::U256::from(quorum), + ), _ => { error!( tx_signature = sol_tx_signature.to_string(), @@ -208,21 +217,7 @@ where } }; - let account_data = match self.rpc_client.get_account_data(&pub_key).await { - Ok(data) => data, - Err(err) => { - error!( - tx_signature = sol_tx_signature.to_string(), - pub_key = pub_key.to_string(), - poll_id = poll_id.to_string(), - err = format!("Error fetching account data: {}", err), - ); - return self.broadcast_vote(poll_id, Vote::FailedOnChain).await; - } - }; - - let vote = - verify_worker_set(&source_gateway_address, &sol_tx, &worker_set, &account_data).await; + let vote = verify_worker_set(&source_gateway_address, &sol_tx, &worker_set, &operators).await; self.broadcast_vote(poll_id, vote).await } } @@ -299,7 +294,7 @@ mod tests { let handler = Handler::new( worker.clone(), voting_verifier.clone(), - ChainName::from_str("not_matching_chain").unwrap(), + ChainName::from_str("notmatchingchain").unwrap(), rpc_client, broadcast_client, rx, diff --git a/ampd/src/solana/msg_verifier.rs b/ampd/src/solana/msg_verifier.rs index a8bb7ef5c..46e0abe08 100644 --- a/ampd/src/solana/msg_verifier.rs +++ b/ampd/src/solana/msg_verifier.rs @@ -1,23 +1,23 @@ use axelar_wasm_std::voting::Vote; -use gmp_gateway::events::GatewayEvent; +use gmp_gateway::events::{CallContract, GatewayEvent}; use solana_transaction_status::{ option_serializer::OptionSerializer, EncodedConfirmedTransactionWithStatusMeta, }; -use std::sync::Arc; +use std::{borrow::Cow, sync::Arc}; use tracing::error; use crate::handlers::solana_verify_msg::Message; -impl PartialEq<&Message> for GatewayEvent { +impl PartialEq<&Message> for GatewayEvent<'_> { fn eq(&self, msg: &&Message) -> bool { match self { - GatewayEvent::CallContract { + GatewayEvent::CallContract(Cow::Owned(CallContract { sender, destination_chain, destination_address, payload: _, payload_hash, - } => { + })) => { let event_dest_addr = String::from_utf8(destination_address.to_owned()); let event_dest_chain = String::from_utf8(destination_chain.to_owned()); @@ -31,6 +31,10 @@ impl PartialEq<&Message> for GatewayEvent { _ => false, } } + + fn ne(&self, other: &&Message) -> bool { + !self.eq(other) + } } pub fn verify_message( @@ -137,7 +141,6 @@ fn find_first_log_message_match( mod tests { use base64::{engine::general_purpose, Engine}; use borsh::BorshSerialize; - use gmp_gateway::types::PubkeyWrapper; use std::str::FromStr; @@ -172,7 +175,6 @@ mod tests { let payload_hash: [u8; 32] = [0; 32]; let source_gateway_address: String = "sol_gateway_addr".to_string(); let source_pubkey = Pubkey::from([0; 32]); - let source_address = PubkeyWrapper::from(source_pubkey); // Code below helps on generating the program log line for adding in the // tests/solana_tx.json file and use it as test fixture. See the "logMessages" field @@ -199,7 +201,7 @@ mod tests { event_index: 0, destination_address: destination_address.clone(), destination_chain: ChainName::from_str(&destination_chain).unwrap(), - source_address: source_address.to_string(), + source_address: source_pubkey.to_string(), payload_hash, }; @@ -207,19 +209,19 @@ mod tests { } fn get_tx_log_message( - sender: PubkeyWrapper, + sender: Pubkey, destination_chain: Vec, destination_address: Vec, payload: Vec, payload_hash: [u8; 32], ) -> String { - let event = gmp_gateway::events::GatewayEvent::CallContract { + let event = gmp_gateway::events::GatewayEvent::CallContract(Cow::Owned(CallContract { sender, destination_chain, destination_address, payload, payload_hash, - }; + })); let mut event_data = Vec::new(); event.serialize(&mut event_data).unwrap(); @@ -253,7 +255,7 @@ mod tests { #[test] fn should_not_verify_msg_if_destination_chain_does_not_match() { let (gateway_address, _, tx, mut msg) = get_matching_msg_and_tx_block(); - msg.destination_chain = ChainName::from_str("bad_chain").unwrap(); + msg.destination_chain = ChainName::from_str("badchain").unwrap(); assert_eq!( Vote::FailedOnChain, verify_message(&gateway_address, Arc::new(tx), &msg) @@ -263,7 +265,7 @@ mod tests { #[test] fn should_not_verify_msg_if_source_address_does_not_match() { let (source_gateway_address, _, tx, mut msg) = get_matching_msg_and_tx_block(); - msg.source_address = PubkeyWrapper::from(Pubkey::from([13; 32])).to_string(); + msg.source_address = Pubkey::from([13; 32]).to_string(); assert_eq!( Vote::FailedOnChain, verify_message(&source_gateway_address, Arc::new(tx), &msg) @@ -318,7 +320,7 @@ mod tests { fn not_matching_tx_log_message(msg: &Message) -> String { get_tx_log_message( - PubkeyWrapper::from(Pubkey::from_str(&msg.source_address).unwrap()), + Pubkey::from_str(&msg.source_address).unwrap(), "abr".as_bytes().to_vec(), msg.destination_address.clone().into_bytes(), Vec::new(), @@ -328,7 +330,7 @@ mod tests { fn matching_tx_log_message(msg: &Message) -> String { get_tx_log_message( - PubkeyWrapper::from(Pubkey::from_str(&msg.source_address).unwrap()), + Pubkey::from_str(&msg.source_address).unwrap(), msg.destination_chain.to_string().into_bytes(), msg.destination_address.clone().into_bytes(), Vec::new(), diff --git a/ampd/src/solana/ws_verifier.rs b/ampd/src/solana/ws_verifier.rs index c21173483..345b2953a 100644 --- a/ampd/src/solana/ws_verifier.rs +++ b/ampd/src/solana/ws_verifier.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; +use axelar_message_primitives::command::Operators; use axelar_wasm_std::voting::Vote; -use gmp_gateway::types::operator::Operators; use solana_transaction_status::EncodedConfirmedTransactionWithStatusMeta; use thiserror::Error; use tracing::{error, info}; @@ -43,7 +43,7 @@ pub async fn verify_worker_set( source_gateway_address: &String, sol_tx: &EncodedConfirmedTransactionWithStatusMeta, worker_set: &WorkerSetConfirmation, - account_data: &Vec, + onchain_operators: &Operators, ) -> Vote { let ui_tx = match &sol_tx.transaction.transaction { solana_transaction_status::EncodedTransaction::Json(tx) => tx, @@ -80,43 +80,15 @@ pub async fn verify_worker_set( return Vote::FailedOnChain; } - let onchain_operators = match parse_onchain_operators(account_data) { - Ok(ops) => ops, - Err(err) => { - info!(tx_id = &worker_set.tx_id, err = err.to_string()); - return Vote::FailedOnChain; - } - }; - - if worker_set.operators == onchain_operators { + if worker_set.operators == *onchain_operators { Vote::SucceededOnChain } else { Vote::FailedOnChain } } -fn parse_onchain_operators(account_data: &Vec) -> Result { - if account_data.is_empty() { - return Err(VerificationError::ParsingError( - "Solana account is empty.".to_string(), - )); - } - - let operators = match borsh::de::from_slice::(account_data) { - Ok(ops) => ops, - Err(err) => { - return Err(VerificationError::ParsingError(format!( - "Cannot borsh decode account data: {}", - err - ))) - } - }; - - Ok(operators) -} - -impl PartialEq for solana_verify_worker_set::Operators { - fn eq(&self, aw_ops: &gmp_gateway::types::operator::Operators) -> bool { +impl PartialEq for solana_verify_worker_set::Operators { + fn eq(&self, aw_ops: &Operators) -> bool { if self.threshold != *aw_ops.threshold() { return false; } @@ -157,7 +129,9 @@ impl PartialEq for solana_verify_worker .iter() .zip(aw_ops.weights()) .try_for_each(|(address, weight)| { - let Some((axelar_address, axelar_weight)) = addresses_weights.get_key_value(address.as_ref()) else { + let Some((axelar_address, axelar_weight)) = + addresses_weights.get_key_value(address.as_ref()) + else { return Err(()); }; @@ -174,7 +148,7 @@ impl PartialEq for solana_verify_worker } } -impl PartialEq for gmp_gateway::types::u256::U256 { +impl PartialEq for axelar_message_primitives::command::U256 { fn eq(&self, loc_u256: &crate::types::U256) -> bool { let mut b: [u8; 32] = [0; 32]; loc_u256.to_little_endian(&mut b); @@ -182,8 +156,8 @@ impl PartialEq for gmp_gateway::types::u256::U256 { } } -impl PartialEq for crate::types::U256 { - fn eq(&self, aw_u256: &gmp_gateway::types::u256::U256) -> bool { +impl PartialEq for crate::types::U256 { + fn eq(&self, aw_u256: &axelar_message_primitives::command::U256) -> bool { let mut b: [u8; 32] = [0; 32]; self.to_little_endian(&mut b); aw_u256.to_le_bytes() == b @@ -195,87 +169,21 @@ mod tests { use crate::handlers::solana_verify_worker_set::Operators; use super::*; - use borsh::BorshSerialize; + use axelar_message_primitives::{command::U256, Address}; use cosmwasm_std::Uint256; - use gmp_gateway::types::{address::Address, u256::U256}; use std::convert::TryFrom; - #[test] - fn test_correct_deserialization_auth_weight_operators() { - let onchain_operators = gmp_gateway::types::operator::Operators::new( - vec![ - Address::try_from( - "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756d", - ) - .unwrap(), - Address::try_from( - "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756e", - ) - .unwrap(), - ], - vec![U256::from(100u8), U256::from(200u8)], - U256::from(1u8), - ); - - let mut op_buff = Vec::new(); - onchain_operators.serialize(&mut op_buff).unwrap(); - - assert_eq!( - onchain_operators, - parse_onchain_operators(&op_buff).unwrap() - ) - } - - #[test] - fn test_incorrect_deserialization_auth_weight_operators_failing_index() { - assert_eq!( - parse_onchain_operators(&vec![]), - Err(VerificationError::ParsingError( - "Solana account is empty.".to_string() - )) - ) - } - - #[test] - fn test_incorrect_deserialization_auth_weight_operators_failing_borsh_deserialization() { - let onchain_operators = gmp_gateway::types::operator::Operators::new( - vec![ - Address::try_from( - "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756d", - ) - .unwrap(), - Address::try_from( - "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756e", - ) - .unwrap(), - ], - vec![U256::from(100u8), U256::from(200u8)], - U256::from(1u8), - ); - - let mut op_buff = Vec::new(); - onchain_operators.serialize(&mut op_buff).unwrap(); - op_buff[0] = 1; // We mangle the data in order to borsh to fail. - - assert_eq!( - parse_onchain_operators(&op_buff), - Err(VerificationError::ParsingError( - "Cannot borsh decode account data: failed to fill whole buffer".to_string() - )) - ); - } - #[test] fn test_verify_worker_set_operators_data_happy_path() { let (ops, sol_ops) = matching_axelar_operators_and_onchain_operators(); - assert!(&ops == &sol_ops) + assert!(ops == sol_ops) } #[test] fn test_verify_worker_set_operators_data_fails_not_eq_threshold() { let (mut ops, sol_ops) = matching_axelar_operators_and_onchain_operators(); ops.threshold = crate::types::U256::from(Uint256::MAX); - assert!(&ops != &sol_ops) + assert!(ops != sol_ops) } #[test] @@ -293,7 +201,7 @@ mod tests { crate::types::U256::from(Uint256::from_u128(200)), ), ]; - assert!(&ops != &sol_ops) + assert!(ops != sol_ops) } #[test] @@ -309,14 +217,14 @@ mod tests { crate::types::U256::from(Uint256::from_u128(1)), // here is a different weight than expected. ), ]; - assert!(&ops != &sol_ops) + assert!(ops != sol_ops) } #[test] fn test_verify_worker_set_operators_data_fails_not_same_elements() { let (ops, _) = matching_axelar_operators_and_onchain_operators(); - let sol_ops = gmp_gateway::types::operator::Operators::new( + let sol_ops = axelar_message_primitives::command::Operators::new( vec![ Address::try_from( "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756d", @@ -331,12 +239,12 @@ mod tests { U256::from(1u8), ); - assert!(&ops != &sol_ops) + assert!(ops != sol_ops) } fn matching_axelar_operators_and_onchain_operators( - ) -> (Operators, gmp_gateway::types::operator::Operators) { - let onchain_operators = gmp_gateway::types::operator::Operators::new( + ) -> (Operators, axelar_message_primitives::command::Operators) { + let onchain_operators = axelar_message_primitives::command::Operators::new( vec![ Address::try_from( "03f57d1a813febaccbe6429603f9ec57969511b76cd680452dba91fa01f54e756d", @@ -373,7 +281,7 @@ mod tests { #[test] fn comparing_u256_and_aw_u256_works() { let u256 = crate::types::U256::from(Uint256::MAX); - let aw_u256 = gmp_gateway::types::u256::U256::from_le_bytes([255; 32]); // Does not have a U256::MAX + let aw_u256 = axelar_message_primitives::command::U256::from_le_bytes([255; 32]); // Does not have a U256::MAX assert!(u256 == aw_u256); } } From 89c1c6e61f05dbaf592fabd31d4cddd76d1d5063 Mon Sep 17 00:00:00 2001 From: eloylp Date: Tue, 30 Apr 2024 16:24:46 -0500 Subject: [PATCH 08/10] Fix clippy warnings --- ampd/src/handlers/solana_verify_msg.rs | 6 +++--- ampd/src/handlers/solana_verify_worker_set.rs | 2 +- ampd/src/solana/rpc.rs | 3 ++- ampd/src/solana/ws_verifier.rs | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ampd/src/handlers/solana_verify_msg.rs b/ampd/src/handlers/solana_verify_msg.rs index a797bb133..e52b964a2 100644 --- a/ampd/src/handlers/solana_verify_msg.rs +++ b/ampd/src/handlers/solana_verify_msg.rs @@ -3,7 +3,7 @@ use connection_router_api::ChainName; use cosmrs::cosmwasm::MsgExecuteContract; use error_stack::ResultExt; use futures::stream::FuturesOrdered; -use futures::{StreamExt, TryStreamExt}; +use futures::StreamExt; use serde::Deserialize; use solana_sdk::signature::Signature; use solana_transaction_status::UiTransactionEncoding; @@ -138,7 +138,7 @@ where } }, }; - Ok(verify_message(source_gateway_address, sol_tx, &msg)) + Ok(verify_message(source_gateway_address, sol_tx, msg)) } } @@ -186,7 +186,7 @@ where let mut votes: Vec = Vec::new(); - let mut ord_fut: FuturesOrdered<_> = messages + let mut ord_fut: FuturesOrdered<_> = messages .iter() .map(|msg| self.process_message(msg, &source_gateway_address)) .collect(); diff --git a/ampd/src/handlers/solana_verify_worker_set.rs b/ampd/src/handlers/solana_verify_worker_set.rs index 7b9e058be..3f7709426 100644 --- a/ampd/src/handlers/solana_verify_worker_set.rs +++ b/ampd/src/handlers/solana_verify_worker_set.rs @@ -126,7 +126,7 @@ where source_chain, source_gateway_address, expires_at, - confirmation_height: _, + confirmation_height, participants, worker_set, } = match event.try_into() as error_stack::Result<_, _> { diff --git a/ampd/src/solana/rpc.rs b/ampd/src/solana/rpc.rs index ef5d752a3..c7846cfc7 100644 --- a/ampd/src/solana/rpc.rs +++ b/ampd/src/solana/rpc.rs @@ -39,7 +39,8 @@ impl RpcCacheWrapper { Ok(tx) } - + + #[cfg(test)] pub async fn entries(&self) -> usize { self.tx_cache.read().await.len() } diff --git a/ampd/src/solana/ws_verifier.rs b/ampd/src/solana/ws_verifier.rs index 345b2953a..3d3f46b89 100644 --- a/ampd/src/solana/ws_verifier.rs +++ b/ampd/src/solana/ws_verifier.rs @@ -168,7 +168,7 @@ impl PartialEq for crate::types::U256 mod tests { use crate::handlers::solana_verify_worker_set::Operators; - use super::*; + use axelar_message_primitives::{command::U256, Address}; use cosmwasm_std::Uint256; use std::convert::TryFrom; From e77d253a5c0ffb18277c5f9f7dd5c19f93737667 Mon Sep 17 00:00:00 2001 From: eloylp Date: Tue, 30 Apr 2024 17:27:47 -0500 Subject: [PATCH 09/10] Add periodic tofnd dependency k8 deployment --- .github/workflows/tofnd-deployment.yml | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/tofnd-deployment.yml diff --git a/.github/workflows/tofnd-deployment.yml b/.github/workflows/tofnd-deployment.yml new file mode 100644 index 000000000..8ccc4e54f --- /dev/null +++ b/.github/workflows/tofnd-deployment.yml @@ -0,0 +1,58 @@ +# This automatically deploy the tofnd dependency in our docker registry: +# https://github.com/axelarnetwork/tofnd + +name: tofnd deployment +on: + schedule: + - cron: "30 22 * * *" + +env: + # If one change any variable of this env block, all of them needs to be aligned, as + # we cannot re-user them. + IMAGE_NAME: tofnd + IMAGE_VERSION: ${{ github.sha }} + IMAGE_ID: solanaaxelartestnetregistry.azurecr.io/solana-axelar/tofnd + DEPLOYING_IMAGE_FQDN: solanaaxelartestnetregistry.azurecr.io/solana-axelar/tofnd:${{ github.sha }} + +jobs: + docker-image: + runs-on: ubuntu-latest + name: "Build and push docker image" + steps: + - name: Checkout repository + run: git clone https://github.com/axelarnetwork/tofnd && cd tofnd + + - name: Build image + run: docker build . --tag $IMAGE_NAME --tag latest + + - name: Login to Azure Container Registry + uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.ACR_REGISTRY_NAME }}.azurecr.io + username: ${{ secrets.AZ_SP_CLIENT_ID }} + password: ${{ secrets.AZ_SP_CLIENT_SECRET }} + + - name: Push image + run: | + docker tag $IMAGE_NAME $IMAGE_ID:$IMAGE_VERSION + docker tag $IMAGE_NAME $IMAGE_ID:latest + docker push $DEPLOYING_IMAGE_FQDN + + deployment: + needs: docker-image + runs-on: ubuntu-latest + name: "Deploy to k8s cluster" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - uses: azure/setup-kubectl@v2.0 + + - uses: Azure/k8s-set-context@v2 + with: + method: kubeconfig + kubeconfig: ${{ secrets.KUBE_CONFIG }} + context: solanaaxelartestnetk8s + + - name: Deploy image in k8s + run: kubectl set image deployment/ampd tofnd=${{ env.DEPLOYING_IMAGE_FQDN }} From 5a1809b8b1d939aae628d0373210d2a9cc383ec9 Mon Sep 17 00:00:00 2001 From: eloylp Date: Tue, 30 Apr 2024 17:46:59 -0500 Subject: [PATCH 10/10] Add periodic dependency check for ampd It will try to build the ampd binary periodically. We have some git dependencies without version fixing and that we want to maintain in that way because we are still adjusting many things and we want it to be "liquid". --- .../workflows/ampd-periodic-main-build.yml | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/ampd-periodic-main-build.yml diff --git a/.github/workflows/ampd-periodic-main-build.yml b/.github/workflows/ampd-periodic-main-build.yml new file mode 100644 index 000000000..5456a06d8 --- /dev/null +++ b/.github/workflows/ampd-periodic-main-build.yml @@ -0,0 +1,26 @@ +name: Ampd binary periodic build +on: + schedule: + # 7 am in the morning. If there are errors due to dependencies, engineers will be notified. + # We are not fixing versions because everything is liquid right now. + - cron: "0 07 * * *" + +jobs: + build: + runs-on: ubuntu-latest + name: "Build the code" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initially do not cache deps, do a fresh build from zero. + + # - uses: Swatinem/rust-cache@v2 + # with: + # cache-all-crates: true + # cache-on-failure: true + # workspaces: "ampd -> target" + # shared-key: "ampd" + + - name: Build the code + run: cd ampd && cargo build