diff --git a/.github/actions/build-docker-images-generic/action.yml b/.github/actions/build-docker-images-generic/action.yml new file mode 100644 index 0000000000..245ac8a631 --- /dev/null +++ b/.github/actions/build-docker-images-generic/action.yml @@ -0,0 +1,71 @@ +name: 'Build Docker Images' +description: 'Builds Docker images and pushes them to any repository.' +inputs: + DOCKER_FILENAME: + description: 'Name of the docker file to use for the build' + required: true + REPOSITORY_NAME: + description: 'Name of the Repository' + required: true + IMAGE_TAG: + description: 'Image Tag' + required: true + REGISTRY: + description: 'Docker or ORG you want to push to.' + required: true + DOCKER_ORG: + description: 'Docker ORG you want to push to.' + required: false + USERNAME: + description: 'Username for GitHub Container Registry' + required: true + TOKEN: + description: 'Token for GitHub Container Registry' + required: true + DOCKER_FILE_DIRECTORY: + description: 'Directory for your Dockerfile' + required: true + DOCKER_BUILD_KIT: + description: "whether or not to use docker build kit." + required: true + TAG_LATEST: + description: "should the pipeline tag latest" + required: true +runs: + using: "composite" + + steps: + - name: Set Environment Variables" + run: | + echo "DOCKER_BUILDKIT=${{ inputs.DOCKER_BUILD_KIT }}" >> $GITHUB_ENV + shell: bash + + - name: Log in to the Docker Registry + uses: docker/login-action@v2 + with: + registry: ${{ inputs.REGISTRY }} + username: ${{ inputs.USERNAME }} + password: ${{ inputs.TOKEN }} + + - name: Build, tag, and push images + shell: bash + working-directory: ${{ inputs.DOCKER_FILE_DIRECTORY }} + run: | + if [ ! -z "${{ inputs.DOCKER_ORG }}" ]; then + echo "DOCKER ORG SPECIFIED SO USE DOCKER HUB" + docker build -f ${{ inputs.DOCKER_FILENAME }} -t ${{ inputs.DOCKER_ORG }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} . + docker push ${{ inputs.DOCKER_ORG }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} + + if [ "${{ inputs.TAG_LATEST }}" == "true" ]; then + docker tag ${{ inputs.DOCKER_ORG }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} ${{ inputs.DOCKER_ORG }}/${{ inputs.REPOSITORY_NAME }}:latest + docker push ${{ inputs.DOCKER_ORG }}/${{ inputs.REPOSITORY_NAME }}:latest + fi + else + echo "DOCKER REGISTRY SPECIFIED WITH NO DOCKER_ORG USE NON ORG REGISTRIES" + docker build -f ${{ inputs.DOCKER_FILENAME }} -t ${{ inputs.REGISTRY }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} . + docker push ${{ inputs.REGISTRY }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} + if [ "${{ inputs.TAG_LATEST }}" == "true" ]; then + docker tag ${{ inputs.REGISTRY }}/${{ inputs.REPOSITORY_NAME }}:${{ inputs.IMAGE_TAG }} ${{ inputs.REGISTRY }}/${{ inputs.REPOSITORY_NAME }}:latest + docker push ${{ inputs.REGISTRY }}/${{ inputs.REPOSITORY_NAME }}:latest + fi + fi diff --git a/.github/workflows/docker-build-and-push.yml b/.github/workflows/docker-build-and-push.yml new file mode 100644 index 0000000000..6fc54ed7f9 --- /dev/null +++ b/.github/workflows/docker-build-and-push.yml @@ -0,0 +1,120 @@ +name: Zetacored-Docker-Build + +on: + pull_request: + types: + - closed + branches: + - 'main' + workflow_dispatch: + inputs: + version: + description: 'Docker Tag Version For Manual Execution' + required: false + default: '' + +concurrency: + group: Zetacored-Docker-Build + cancel-in-progress: false + +env: + DOCKER_REPO: "zeatcored" + DOCKER_ORG: "zetachain" + DOCKER_REGISTRY: "https://index.docker.io/v1/" + +jobs: + docker_build_ubuntu: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set Version from the PR title. + if: github.event_name == 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV} + + - name: Set Version for Hotfix Release from Input. + if: github.event_name != 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.inputs.version }}" >> ${GITHUB_ENV} + + - name: "BUILD:PUSH:MONITORING:DOCKER:IMAGE" + uses: ./.github/actions/build-docker-images-generic + with: + DOCKER_FILENAME: "Dockerfile" + REPOSITORY_NAME: "${{ env.DOCKER_REPO }}" + IMAGE_TAG: "ubuntu-${{ env.GITHUB_TAG_MAJOR_VERSION }}" + REGISTRY: "${{ env.DOCKER_REGISTRY }}" + DOCKER_ORG: "${{ env.DOCKER_ORG }}" + USERNAME: "${{ secrets.DOCKER_HUB_USERNAME }}" + TOKEN: "${{ secrets.DOCKERHUB_TOKEN }}" + DOCKER_FILE_DIRECTORY: "./" + DOCKER_BUILD_KIT: "0" + TAG_LATEST: "true" + + docker_build_mac: + runs-on: macos-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set Version from the PR title. + if: github.event_name == 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV} + + - name: Set Version for Hotfix Release from Input. + if: github.event_name != 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.inputs.version }}" >> ${GITHUB_ENV} + + - name: "BUILD:PUSH:MONITORING:DOCKER:IMAGE" + uses: ./.github/actions/build-docker-images-generic + with: + DOCKER_FILENAME: "Dockerfile" + REPOSITORY_NAME: "${{ env.DOCKER_REPO }}" + IMAGE_TAG: "mac-${{ env.GITHUB_TAG_MAJOR_VERSION }}" + REGISTRY: "${{ env.DOCKER_REGISTRY }}" + DOCKER_ORG: "${{ env.DOCKER_ORG }}" + USERNAME: "${{ secrets.DOCKER_HUB_USERNAME }}" + TOKEN: "${{ secrets.DOCKERHUB_TOKEN }}" + DOCKER_FILE_DIRECTORY: "./" + DOCKER_BUILD_KIT: "0" + TAG_LATEST: "false" + + docker_build_arm: + runs-on: buildjet-4vcpu-ubuntu-2204-arm + timeout-minutes: 30 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set Version from the PR title. + if: github.event_name == 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV} + + - name: Set Version for Hotfix Release from Input. + if: github.event_name != 'pull_request' + run: | + echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.inputs.version }}" >> ${GITHUB_ENV} + + - name: "BUILD:PUSH:MONITORING:DOCKER:IMAGE" + uses: ./.github/actions/build-docker-images-generic + with: + DOCKER_FILENAME: "Dockerfile" + REPOSITORY_NAME: "${{ env.DOCKER_REPO }}" + IMAGE_TAG: "arm-${{ env.GITHUB_TAG_MAJOR_VERSION }}" + REGISTRY: "${{ env.DOCKER_REGISTRY }}" + DOCKER_ORG: "${{ env.DOCKER_ORG }}" + USERNAME: "${{ secrets.DOCKER_HUB_USERNAME }}" + TOKEN: "${{ secrets.DOCKERHUB_TOKEN }}" + DOCKER_FILE_DIRECTORY: "./" + DOCKER_BUILD_KIT: "0" + TAG_LATEST: "false" \ No newline at end of file diff --git a/changelog.md b/changelog.md index b0f358b649..34fc9a3576 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,10 @@ ## Unreleased * `zetaclientd start` : 2 inputs required from stdin -* Added docker-compose and make commands for launching full nodes. `make mainnet-zetarpc-node` `make mainnet-bitcoind-node` + +### Docs + +* [1731](https://github.com/zeta-chain/node/pull/1731) added doc for hotkey and tss key-share password prompts. ### Features @@ -16,12 +19,13 @@ ### Fixes +* [1678](https://github.com/zeta-chain/node/issues/1678) - clean cached stale block to fix evm outtx hash mismatch * [1690](https://github.com/zeta-chain/node/issues/1690) - double watched gas prices and fix btc scheduler * [1687](https://github.com/zeta-chain/node/pull/1687) - only use EVM supported chains for gas stability pool * [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module * [1707](https://github.com/zeta-chain/node/issues/1707) - fix bitcoin fee rate estimation * [1712](https://github.com/zeta-chain/node/issues/1712) - increase EVM outtx inclusion timeout to 20 minutes -* [1733](https://github.com/zeta-chain/node/pull/1733)) - remove the unnecessary 2x multiplier in the convertGasToZeta RPC +* [1733](https://github.com/zeta-chain/node/pull/1733) - remove the unnecessary 2x multiplier in the convertGasToZeta RPC * [1721](https://github.com/zeta-chain/node/issues/1721) - zetaclient should provide bitcoin_chain_id when querying TSS address * [1744](https://github.com/zeta-chain/node/pull/1744) - added cmd to encrypt tss keyshare file, allowing empty tss password for backward compatibility. @@ -31,6 +35,8 @@ ### CI +* CI: adding pipeline to build and push docker images into dockerhub on release for ubuntu and macos. +* Added docker-compose and make commands for launching full nodes. `make mainnet-zetarpc-node` `make mainnet-bitcoind-node` * [1736](https://github.com/zeta-chain/node/pull/1736) - chore: add Ethermint endpoints to OpenAPI ### Chores diff --git a/docs/zetaclient/migration_v12.2->v12.3.md b/docs/zetaclient/migration_v12.2->v12.3.md new file mode 100644 index 0000000000..0ad72bd917 --- /dev/null +++ b/docs/zetaclient/migration_v12.2->v12.3.md @@ -0,0 +1,34 @@ +## Hot Key and TSS key-share Passwords + +### Zetaclient +Previously there were two environment variables being used to store passwords encrypting the tss key file and local operator keyring file: + +* HOTKEY_PASSWORD +* TSS_FRAGMENT_SEED + +With this new change, these variables will no longer be valid. +Instead, a series of prompts will appear asking for passwords using STDIN during the startup process. + +* Hot Key password +* TSS Key share password + +If your key files are already encrypted, you can use the same passwords you provided in the environment variables. + +**It's extremely important to take note of these passwords or commit them to memory.** + +### Hot Key + +#### File backend + +* The hot key will use the existing keyring that holds your operator key. The file will be encrypted with your existing password, +make sure to use this same password when starting the client. + +#### Test backend + +* You will still be prompted for a password, but you need to leave it blank which indicates the test backend is being used. + +### TSS Key-Share + +During key-gen, the password you enter will be used to encrypt the generated key-share file. The key data will be stored in +memory once the process is running. If the client needs to be restarted, this key-share file needs to be present on your +machine and will be decrypted using the password you've entered. \ No newline at end of file diff --git a/zetaclient/evm/evm_client.go b/zetaclient/evm/evm_client.go index 97b29495f6..db13df1f6f 100644 --- a/zetaclient/evm/evm_client.go +++ b/zetaclient/evm/evm_client.go @@ -799,6 +799,7 @@ func (ob *ChainClient) checkTxInclusion(tx *ethtypes.Transaction, blockNumber ui } txAtIndex := block.Transactions()[txIndex] if txAtIndex.Hash() != tx.Hash() { + ob.RemoveCachedBlock(blockNumber) // clean stale block from cache return fmt.Errorf("transaction at index %d has different hash %s, txHash %s nonce %d block %d", txIndex, txAtIndex.Hash().Hex(), tx.Hash(), tx.Nonce(), blockNumber) } @@ -810,6 +811,7 @@ func (ob *ChainClient) checkTxInclusion(tx *ethtypes.Transaction, blockNumber ui } txAtIndex := blockRPC.Transactions[txIndex] if ethcommon.HexToHash(txAtIndex.Hash) != tx.Hash() { + ob.RemoveCachedBlock(blockNumber) // clean stale block from cache return fmt.Errorf("transaction at index %d has different hash %s, txHash %s nonce %d block %d", txIndex, txAtIndex.Hash, tx.Hash(), tx.Nonce(), blockNumber) } @@ -1520,3 +1522,9 @@ func (ob *ChainClient) GetBlockByNumberCached(blockNumber uint64) (*ethtypes.Blo ob.blockCache.Add(blockNumber, block) return block, nil, false, false, nil } + +// RemoveCachedBlock remove block from cache +func (ob *ChainClient) RemoveCachedBlock(blockNumber uint64) { + ob.blockCache.Remove(blockNumber) + ob.blockCacheV3.Remove(blockNumber) +} diff --git a/zetaclient/evm/evm_client_test.go b/zetaclient/evm/evm_client_test.go new file mode 100644 index 0000000000..730cba83f9 --- /dev/null +++ b/zetaclient/evm/evm_client_test.go @@ -0,0 +1,37 @@ +package evm + +import ( + "math/big" + "testing" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + lru "github.com/hashicorp/golang-lru" + "github.com/stretchr/testify/require" +) + +func TestEVMBlockCache(t *testing.T) { + // create client + blockCache, err := lru.New(1000) + require.NoError(t, err) + blockCacheV3, err := lru.New(1000) + require.NoError(t, err) + ob := ChainClient{ + blockCache: blockCache, + blockCacheV3: blockCacheV3, + } + + // delete non-existing block should not panic + blockNumber := int64(10388180) + // #nosec G701 possible nummber + ob.RemoveCachedBlock(uint64(blockNumber)) + + // add a block + header := ðtypes.Header{ + Number: big.NewInt(blockNumber), + } + block := ethtypes.NewBlock(header, nil, nil, nil, nil) + ob.blockCache.Add(blockNumber, block) + + // delete the block should not panic + ob.RemoveCachedBlock(uint64(blockNumber)) +}