diff --git a/app/app.go b/app/app.go index 84b9a49253..7c4186af5c 100644 --- a/app/app.go +++ b/app/app.go @@ -567,7 +567,12 @@ func New( &app.FeeMarketKeeper, tracer, evmSs, - precompiles.StatefulContracts(&app.FungibleKeeper, appCodec, storetypes.TransientGasConfig()), + precompiles.StatefulContracts( + &app.FungibleKeeper, + app.StakingKeeper, + appCodec, + storetypes.TransientGasConfig(), + ), app.ConsensusParamsKeeper, aggregateAllKeys(keys, tKeys, memKeys), ) diff --git a/changelog.md b/changelog.md index b122d67d8d..5cade157f1 100644 --- a/changelog.md +++ b/changelog.md @@ -14,8 +14,9 @@ * [2681](https://github.com/zeta-chain/node/pull/2681) - implement `MsgUpdateERC20CustodyPauseStatus` to pause or unpause ERC20 Custody contract (to be used for the migration process for smart contract V2) * [2644](https://github.com/zeta-chain/node/pull/2644) - add created_timestamp to cctx status * [2673](https://github.com/zeta-chain/node/pull/2673) - add relayer key importer, encryption and decryption -* [2633](https://github.com/zeta-chain/node/pull/2633) - support for stateful precompiled contracts. +* [2633](https://github.com/zeta-chain/node/pull/2633) - support for stateful precompiled contracts * [2788](https://github.com/zeta-chain/node/pull/2788) - add common importable zetacored rpc package +* [2784](https://github.com/zeta-chain/node/pull/2784) - staking precompiled contract ### Refactor diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 40900872f4..fdde8e5840 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -309,7 +309,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if !skipPrecompiles { precompiledContractTests = []string{ - e2etests.TestZetaPrecompilesPrototypeName, + e2etests.TestPrecompilesPrototypeName, + e2etests.TestPrecompilesStakingName, } } diff --git a/codecov.yml b/codecov.yml index 474cfe97ee..fedb830848 100644 --- a/codecov.yml +++ b/codecov.yml @@ -81,3 +81,4 @@ ignore: - "precompiles/**/*.json" - "precompiles/**/*.sol" - "precompiles/prototype/IPrototype.go" + - "precompiles/staking/IStaking.go" diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 2dfdb123ba..ed762288bc 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -1,5 +1,7 @@ #!/bin/bash +# shellcheck disable=SC2317 + # The script run the zetae2e CLI to run local end-to-end tests # First argument is the command to run the local e2e # A second optional argument can be passed and can have the following value: @@ -24,6 +26,49 @@ get_zetacored_version() { exit 1 } +# Reads unquoted string value from config by its path +# Usage: config_str +config_str() { + yq -r "$1" config.yml +} + +# Sends Ether to the given address on Ethereum localnet +# Usage: fund_eth
[comment] +fund_eth() { + local address=$1 + local ether=$2 + local comment=${3:-} + + if [ -z "$comment" ]; then + echo "funding eth address $address with $ether eth" + else + echo "funding eth address $address ($comment) with $ether eth" + fi + + geth --exec \ + "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(${ether}, 'ether')})" \ + attach http://eth:8545 > /dev/null; +} + +# Combines fund_eth with config_str +# Usage: fund_eth_from_config [comment] +fund_eth_from_config() { + local config_key=$1 + local ether=$2 + local comment=${3:-} + + # Fetch the address from the config file using config_str + # shellcheck disable=SC2155 + local address=$(config_str "$config_key") + if [ -z "$address" ]; then + echo "Error: Address not found for key $config_key" + return 1 + fi + + # Call fund_eth with the fetched address, ether amount, and optional comment + fund_eth "$address" "$ether" "$comment" +} + # Wait for authorized_keys file to exist (generated by zetacore0) while [ ! -f ~/.ssh/authorized_keys ]; do echo "Waiting for authorized_keys file to exist..." @@ -42,85 +87,62 @@ sleep 2 ### Create the accounts and fund them with Ether on local Ethereum network # unlock the default account account -address=$(yq -r '.default_account.evm_address' config.yml) -echo "funding deployer address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.default_account.evm_address' 10000 "deployer" # unlock erc20 tester accounts -address=$(yq -r '.additional_accounts.user_erc20.evm_address' config.yml) -echo "funding erc20 address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_erc20.evm_address' 10000 "ERC20 tester" # unlock zeta tester accounts -address=$(yq -r '.additional_accounts.user_zeta_test.evm_address' config.yml) -echo "funding zeta tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_zeta_test.evm_address' 10000 "zeta tester" # unlock zevm message passing tester accounts -address=$(yq -r '.additional_accounts.user_zevm_mp_test.evm_address' config.yml) -echo "funding zevm mp tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_zevm_mp_test.evm_address' 10000 "zevm mp tester" # unlock bitcoin tester accounts -address=$(yq -r '.additional_accounts.user_bitcoin.evm_address' config.yml) -echo "funding bitcoin tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_bitcoin.evm_address' 10000 "bitcoin tester" # unlock solana tester accounts -address=$(yq -r '.additional_accounts.user_solana.evm_address' config.yml) -echo "funding solana tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_solana.evm_address' 10000 "solana tester" # unlock ethers tester accounts -address=$(yq -r '.additional_accounts.user_ether.evm_address' config.yml) -echo "funding ether tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_ether.evm_address' 10000 "ether tester" # unlock miscellaneous tests accounts -address=$(yq -r '.additional_accounts.user_misc.evm_address' config.yml) -echo "funding misc tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_misc.evm_address' 10000 "misc tester" # unlock admin erc20 tests accounts -address=$(yq -r '.additional_accounts.user_admin.evm_address' config.yml) -echo "funding admin tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_admin.evm_address' 10000 "admin tester" # unlock migration tests accounts -address=$(yq -r '.additional_accounts.user_migration.evm_address' config.yml) -echo "funding migration tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_migration.evm_address' 10000 "migration tester" # unlock v2 ethers tests accounts -address=$(yq -r '.additional_accounts.user_v2_ether.evm_address' config.yml) -echo "funding v2 ethers tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_v2_ether.evm_address' 10000 "V2 ethers tester" # unlock v2 erc20 tests accounts -address=$(yq -r '.additional_accounts.user_v2_erc20.evm_address' config.yml) -echo "funding v2 erc20 tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_v2_erc20.evm_address' 10000 "V2 ERC20 tester" # unlock v2 ethers revert tests accounts -address=$(yq -r '.additional_accounts.user_v2_ether_revert.evm_address' config.yml) -echo "funding v2 ethers revert tester address ${address} with 10000 Ether" -geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null +fund_eth_from_config '.additional_accounts.user_v2_ether_revert.evm_address' 10000 "V2 ethers revert tester" # unlock v2 erc20 revert tests accounts -address=$(yq -r '.additional_accounts.user_v2_erc20_revert.evm_address' config.yml) -echo "funding v2 erc20 revert tester address ${address} with 10000 Ether" +fund_eth_from_config '.additional_accounts.user_v2_erc20_revert.evm_address' 10000 "V2 ERC20 revert tester" + +# unlock precompile tests accounts +address=$(yq -r '.additional_accounts.user_precompile.evm_address' config.yml) +echo "funding precompile tester address ${address} with 10000 Ether" geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 > /dev/null # unlock local solana relayer accounts if host solana > /dev/null; then - solana_url=$(yq -r '.rpcs.solana' config.yml) + solana_url=$(config_str '.rpcs.solana') solana config set --url "$solana_url" > /dev/null - relayer=$(yq -r '.observer_relayer_accounts.relayer_accounts[0].solana_address' config.yml) + relayer=$(config_str '.observer_relayer_accounts.relayer_accounts[0].solana_address') echo "funding solana relayer address ${relayer} with 100 SOL" solana airdrop 100 "$relayer" > /dev/null - relayer=$(yq -r '.observer_relayer_accounts.relayer_accounts[1].solana_address' config.yml) + relayer=$(config_str '.observer_relayer_accounts.relayer_accounts[1].solana_address') echo "funding solana relayer address ${relayer} with 100 SOL" solana airdrop 100 "$relayer" > /dev/null fi diff --git a/contrib/localnet/scripts/import-data.sh b/contrib/localnet/scripts/import-data.sh index 52b18945fd..955d42e62a 100755 --- a/contrib/localnet/scripts/import-data.sh +++ b/contrib/localnet/scripts/import-data.sh @@ -10,6 +10,6 @@ echo "NETWORK: ${NETWORK}" rm -rf ~/.zetacored/genesis_data mkdir -p ~/.zetacored/genesis_data echo "Download Latest State Export" -LATEST_EXPORT_URL=$(curl https://snapshots.zetachain.com/latest-state-export | jq -r ."${NETWORK}") +LATEST_EXPORT_URL=$(curl https://snapshots.rpc.zetachain.com/${NETWORK}/state/latest.json | jq -r '.snapshots[0].link') echo "LATEST EXPORT URL: ${LATEST_EXPORT_URL}" wget -q ${LATEST_EXPORT_URL} -O ~/.zetacored/genesis_data/exported-genesis.json diff --git a/contrib/localnet/scripts/start-zetacored.sh b/contrib/localnet/scripts/start-zetacored.sh index f1d3e11872..a7cf53021f 100755 --- a/contrib/localnet/scripts/start-zetacored.sh +++ b/contrib/localnet/scripts/start-zetacored.sh @@ -254,6 +254,9 @@ then # migration tester address=$(yq -r '.additional_accounts.user_migration.bech32_address' /root/config.yml) zetacored add-genesis-account "$address" 100000000000000000000000000azeta +# precompiles tester + address=$(yq -r '.additional_accounts.user_precompile.bech32_address' /root/config.yml) + zetacored add-genesis-account "$address" 100000000000000000000000000azeta # v2 ether tester address=$(yq -r '.additional_accounts.user_v2_ether.bech32_address' /root/config.yml) zetacored add-genesis-account "$address" 100000000000000000000000000azeta diff --git a/docs/openapi/openapi.go b/docs/openapi/openapi.go index 187dbbe7ce..eba900acb5 100644 --- a/docs/openapi/openapi.go +++ b/docs/openapi/openapi.go @@ -2,22 +2,21 @@ package openapi import ( "embed" - "html/template" "net/http" "github.com/gorilla/mux" ) const ( - apiFile = "openapi.swagger.yaml" - templateFile = "template.tpl" + apiFile = "openapi.swagger.yaml" + htmlFile = "openapi.html" ) //go:embed openapi.swagger.yaml var staticFS embed.FS -//go:embed template.tpl -var templateFS embed.FS +//go:embed openapi.html +var html []byte func RegisterOpenAPIService(router *mux.Router) { router.Handle("/"+apiFile, http.FileServer(http.FS(staticFS))) @@ -25,19 +24,8 @@ func RegisterOpenAPIService(router *mux.Router) { } func openAPIHandler() http.HandlerFunc { - tmpl, err := template.ParseFS(templateFS, templateFile) - if err != nil { - panic(err) - } - return func(w http.ResponseWriter, _ *http.Request) { - err := tmpl.Execute(w, struct { - URL string - }{ - "/" + apiFile, - }) - if err != nil { - http.Error(w, "Failed to render template", http.StatusInternalServerError) - } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + _, _ = w.Write(html) } } diff --git a/docs/openapi/template.tpl b/docs/openapi/openapi.html similarity index 94% rename from docs/openapi/template.tpl rename to docs/openapi/openapi.html index 63b89df478..37fbfb2a16 100644 --- a/docs/openapi/template.tpl +++ b/docs/openapi/openapi.html @@ -20,7 +20,7 @@