Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wormchain: add slashing params vaa #4194

Merged
merged 19 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/wormchain-icts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,52 @@ permissions:

env:
GO_VERSION: 1.21
TAR_PATH: /tmp/wormchain-docker-image.tar
IMAGE_NAME: wormchain-docker-image

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
cache-dependency-path: wormchain/interchaintest/go.sum

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and export
uses: docker/build-push-action@v5
with:
context: .
file: wormchain/Dockerfile.ict
tags: wormchain:local
outputs: type=docker,dest=${{ env.TAR_PATH }}

- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: ${{ env.IMAGE_NAME }}
path: ${{ env.TAR_PATH }}

e2e-tests:
needs: build-docker
runs-on: ubuntu-latest
strategy:
matrix:
# names of `make` commands to run tests
test:
- "ictest-cancel-upgrade"
- "ictest-slashing-params-update-vaa"
- "ictest-upgrade"
- "ictest-wormchain"
- "ictest-ibc-receiver"
Expand All @@ -42,6 +75,17 @@ jobs:
- name: checkout chain
uses: actions/checkout@v4

- name: Download Tarball Artifact
uses: actions/download-artifact@v3
with:
name: ${{ env.IMAGE_NAME }}
path: /tmp

- name: Load Docker Image
run: |
docker image load -i ${{ env.TAR_PATH }}
docker image ls -a

- name: Run Test
id: run_test
continue-on-error: true
Expand Down
56 changes: 51 additions & 5 deletions sdk/vaa/payloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ type GovernanceAction uint8
var (
// Wormhole core governance actions
// See e.g. GovernanceStructs.sol for semantic meaning of these
ActionContractUpgrade GovernanceAction = 1
ActionGuardianSetUpdate GovernanceAction = 2
ActionCoreSetMessageFee GovernanceAction = 3
ActionCoreTransferFees GovernanceAction = 4
ActionCoreRecoverChainId GovernanceAction = 5
ActionContractUpgrade GovernanceAction = 1
ActionGuardianSetUpdate GovernanceAction = 2
ActionCoreSetMessageFee GovernanceAction = 3
ActionCoreTransferFees GovernanceAction = 4
ActionCoreRecoverChainId GovernanceAction = 5
ActionSlashingParamsUpdate GovernanceAction = 6

// Wormchain cosmwasm/middleware governance actions
ActionStoreCode GovernanceAction = 1
Expand Down Expand Up @@ -127,6 +128,32 @@ type (
NewIndex uint32
}

// BodySlashingParamsUpdate is a governance message to update the slashing parameters on Wormchain.
//
// It is important to note that the slashing keeper only accepts `int64` values as input, so we need to convert
// the `uint64` values to `int64` before passing them to the keeper. This conversion can introduce overflow
// issues if the `uint64` values are too large. To combat this, the Wormchain CLI and the slashing keeper run
// validation checks on the new parameter values.
//
// Below documents the entire process of updating the slashing parameters:
// 1. The CLI command receives the new slashing parameters from the user as `uint64` values for `SignedBlocksWindow` and `DowntimeJailDuration` and as `string` values
// for `MinSignedPerWindow`, `SlashFractionDoubleSign`, and `SlashFractionDowntime`. The command accepts `string` values for ease of use when providing decimal values.
// 2. The CLI command converts the `string` values into `sdk.Dec` values and then into `uint64` values.
// 3. The CLI command validates that the `uint64` values are within the acceptable range for the slashing parameters.
// 4. The CLI command serializes the new slashing parameters into a governance VAA.
// 5. The governance VAA is signed & broadcasted to the Wormchain.
// 6. Wormchain deserializes the governance VAA and extracts every new slashing parameter as a uint64 value.
// 7. Wormchain converts the uint64 values to int64 values and passes them to the slashing keeper.
// 8. The slashing keeper runs validation checks on the new slashing parameters and throws an error if they are invalid.
// 9. If the new slashing parameters pass the validation checks, the slashing keeper updates its parameters.
BodySlashingParamsUpdate struct {
SignedBlocksWindow uint64
MinSignedPerWindow uint64
DowntimeJailDuration uint64
SlashFractionDoubleSign uint64
SlashFractionDowntime uint64
}

// BodyTokenBridgeRegisterChain is a governance message to register a chain on the token bridge
BodyTokenBridgeRegisterChain struct {
Module string
Expand Down Expand Up @@ -283,6 +310,25 @@ func (b BodyGuardianSetUpdate) Serialize() ([]byte, error) {
return buf.Bytes(), nil
}

func (b BodySlashingParamsUpdate) Serialize() ([]byte, error) {
buf := new(bytes.Buffer)

// Module
buf.Write(CoreModule)
// // Action
MustWrite(buf, binary.BigEndian, ActionSlashingParamsUpdate)
// // ChainID - 0 for universal
MustWrite(buf, binary.BigEndian, uint16(0))

MustWrite(buf, binary.BigEndian, b.SignedBlocksWindow)
MustWrite(buf, binary.BigEndian, b.MinSignedPerWindow)
MustWrite(buf, binary.BigEndian, b.DowntimeJailDuration)
MustWrite(buf, binary.BigEndian, b.SlashFractionDoubleSign)
MustWrite(buf, binary.BigEndian, b.SlashFractionDowntime)

return buf.Bytes(), nil
}

func (r BodyTokenBridgeRegisterChain) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
MustWrite(payload, binary.BigEndian, r.ChainID)
Expand Down
22 changes: 22 additions & 0 deletions sdk/vaa/payloads_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"reflect"
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -73,6 +74,27 @@ func TestBodyGuardianSetUpdateSerialize(t *testing.T) {
assert.Equal(t, expected, hex.EncodeToString(serializedBodyGuardianSetUpdate))
}

func TestBodySlashingParamsUpdateSerialize(t *testing.T) {
signedBlocksWindow := uint64(100)
minSignedPerWindow := uint64(500000000000000000)
downtimeJailDuration := uint64(600 * time.Second)
slashFractionDoubleSign := uint64(50000000000000000)
slashFractionDowntime := uint64(10000000000000000)

bodySlashingParamsUpdate := BodySlashingParamsUpdate{
SignedBlocksWindow: signedBlocksWindow,
MinSignedPerWindow: minSignedPerWindow,
DowntimeJailDuration: downtimeJailDuration,
SlashFractionDoubleSign: slashFractionDoubleSign,
SlashFractionDowntime: slashFractionDowntime,
}
serializedBody, err := bodySlashingParamsUpdate.Serialize()
require.NoError(t, err)

expected := "00000000000000000000000000000000000000000000000000000000436f7265060000000000000000006406f05b59d3b200000000008bb2c9700000b1a2bc2ec50000002386f26fc10000"
assert.Equal(t, expected, hex.EncodeToString(serializedBody))
}

func TestBodyTokenBridgeRegisterChainSerialize(t *testing.T) {
module := "test"
tests := []struct {
Expand Down
2 changes: 1 addition & 1 deletion wormchain/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ release/
testing/js/node_modules
!build
build/wormhole-chaind
build/wormchaind
build/wormchaind*
build/data
devnet/wormchain-*/data
devnet/wormchain-*/config/*.toml
Expand Down
40 changes: 40 additions & 0 deletions wormchain/Dockerfile.ict
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
FROM golang:1.22.5@sha256:86a3c48a61915a8c62c0e1d7594730399caa3feb73655dfe96c7bc17710e96cf AS builder

WORKDIR /app

# Install dependencies
RUN apt update && \
apt-get install -y \
build-essential \
ca-certificates \
curl

# Enable faster module downloading.
ENV GOPROXY https://proxy.golang.org

COPY ./wormchain/go.mod .
COPY ./wormchain/go.sum .
COPY ./sdk /sdk
RUN go mod download

COPY ./wormchain .

RUN make build/wormchaind

FROM golang:1.22.5@sha256:86a3c48a61915a8c62c0e1d7594730399caa3feb73655dfe96c7bc17710e96cf

WORKDIR /home/heighliner

COPY --from=builder /app/build/wormchaind /usr/bin

# copy over c bindings (libwasmvm.x86_64.so, etc)
COPY --from=builder /go/pkg/mod/github.com/!cosm!wasm/[email protected]/internal/api/* /usr/lib/

EXPOSE 26657
EXPOSE 26656
EXPOSE 6060
EXPOSE 9090
EXPOSE 1317
EXPOSE 4500

ENTRYPOINT [ "wormchaind" ]
9 changes: 8 additions & 1 deletion wormchain/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ clean:
## INTERCHAINTESTS ##
#####################

# Generate Wormchain Image
local-image: build/wormchaind
docker build -t wormchain:local -f Dockerfile.ict ..

# Individual Tests ($$ is interpreted as $)
rm-testcache:
go clean -testcache
Expand All @@ -93,6 +97,9 @@ ictest-cancel-upgrade: rm-testcache
ictest-malformed-payload: rm-testcache
cd interchaintest && go test -race -v -run ^TestMalformedPayload$$ ./...

ictest-slashing-params-update-vaa: rm-testcache
cd interchaintest && go test -race -v -run ^TestSlashingParamsUpdateVaa$$ ./...

ictest-upgrade-failure: rm-testcache
cd interchaintest && go test -race -v -run ^TestUpgradeFailure$$ ./...

Expand All @@ -105,4 +112,4 @@ ictest-wormchain: rm-testcache
ictest-ibc-receiver: rm-testcache
cd interchaintest && go test -race -v -run ^TestIbcReceiver ./...

.PHONY: ictest-cancel-upgrade ictest-malformed-payload ictest-upgrade-failure ictest-upgrade ictest-wormchain ictest-ibc-receiver
.PHONY: ictest-cancel-upgrade ictest-malformed-payload ictest-slashing-params-update-vaa ictest-upgrade-failure ictest-upgrade ictest-wormchain ictest-ibc-receiver
2 changes: 2 additions & 0 deletions wormchain/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,8 @@ func New(
app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
)
app.WormholeKeeper.SetSlashingKeeper(app.SlashingKeeper)

app.CrisisKeeper = crisiskeeper.NewKeeper(
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
)
Expand Down
6 changes: 3 additions & 3 deletions wormchain/interchaintest/helpers/gateway_governance_vaa.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func SetMiddlewareContract(
}
payloadBz, err := payload.Serialize()
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
v := GenerateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand All @@ -67,7 +67,7 @@ func ScheduleUpgrade(
}
payloadBz, err := payload.Serialize()
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payloadBz)
v := GenerateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payloadBz)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand All @@ -87,7 +87,7 @@ func CancelUpgrade(

payloadBz, err := vaa.EmptyPayloadVaa(vaa.GatewayModuleStr, vaa.ActionCancelUpgrade, vaa.ChainIDWormchain)
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
v := GenerateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand Down
6 changes: 3 additions & 3 deletions wormchain/interchaintest/helpers/ibc_translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func SubmitAllowlistInstantiateContract(
}
payloadBz, err := payload.Serialize(vaa.ActionAddWasmInstantiateAllowlist)
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
v := GenerateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand Down Expand Up @@ -83,7 +83,7 @@ func SubmitUpdateChainToChannelMapMsg(t *testing.T, allowlistChainID uint16, all
payload.Write(channelPadded.Bytes())
vaa.MustWrite(payload, binary.BigEndian, allowlistChainID)

v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payload.Bytes())
v := GenerateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payload.Bytes())
vBz, err := v.Marshal()
require.NoError(t, err)

Expand Down Expand Up @@ -162,7 +162,7 @@ func IbcTranslatorCompleteTransferAndConvertMsg(t *testing.T, emitterChainID uin
emitterBz[eIndex-1] = emitterAddr[i-1]
eIndex--
}
v := generateVaa(0, guardians, vaa.ChainID(emitterChainID), vaa.Address(emitterBz), payload)
v := GenerateVaa(0, guardians, vaa.ChainID(emitterChainID), vaa.Address(emitterBz), payload)
vBz, err := v.Marshal()
require.NoError(t, err)

Expand Down
2 changes: 1 addition & 1 deletion wormchain/interchaintest/helpers/instantiate_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func InstantiateContract(
code_id, err := strconv.ParseUint(codeId, 10, 64)
require.NoError(t, err)
payload := createWasmInstantiatePayload(code_id, label, message)
v := generateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
v := GenerateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand Down
2 changes: 1 addition & 1 deletion wormchain/interchaintest/helpers/migrate_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func MigrateContract(
code_id, err := strconv.ParseUint(codeId, 10, 64)
require.NoError(t, err)
payload := createWasmMigrationPayload(code_id, contractAddr, message)
v := generateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
v := GenerateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
vBz, err := v.Marshal()
require.NoError(t, err)
vHex := hex.EncodeToString(vBz)
Expand Down
2 changes: 1 addition & 1 deletion wormchain/interchaintest/helpers/store_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func StoreContract(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain,
}

payload := createWasmStoreCodePayload(content)
v := generateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
v := GenerateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
vBz, err := v.Marshal()
require.NoError(t, err)

Expand Down
4 changes: 2 additions & 2 deletions wormchain/interchaintest/helpers/token_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func TbRegisterChainMsg(t *testing.T, chainID uint16, emitterAddr string, guardi

payload, err := bodyTbRegisterChain.Serialize()
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
v := GenerateVaa(0, guardians, vaa.ChainID(vaa.GovernanceChain), vaa.Address(vaa.GovernanceEmitter), payload)
vBz, err := v.Marshal()
require.NoError(t, err)

Expand Down Expand Up @@ -106,7 +106,7 @@ func TbRegisterForeignAsset(t *testing.T, tokenAddr string, chainID uint16, emit
emitterBz[eIndex-1] = emitterAddr[i-1]
eIndex--
}
v := generateVaa(0, guardians, vaa.ChainID(chainID), vaa.Address(emitterBz), payload.Bytes())
v := GenerateVaa(0, guardians, vaa.ChainID(chainID), vaa.Address(emitterBz), payload.Bytes())
vBz, err := v.Marshal()
require.NoError(t, err)

Expand Down
2 changes: 1 addition & 1 deletion wormchain/interchaintest/helpers/vaa.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func signVaa(vaaToSign vaa.VAA, signers *guardians.ValSet) vaa.VAA {
return vaaToSign
}

func generateVaa(index uint32, signers *guardians.ValSet, emitterChain vaa.ChainID, emitterAddr vaa.Address, payload []byte) vaa.VAA {
func GenerateVaa(index uint32, signers *guardians.ValSet, emitterChain vaa.ChainID, emitterAddr vaa.Address, payload []byte) vaa.VAA {
v := vaa.VAA{
Version: uint8(1),
GuardianSetIndex: index,
Expand Down
4 changes: 4 additions & 0 deletions wormchain/interchaintest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func CreateChains(t *testing.T, wormchainVersion string, guardians guardians.Val
numWormchainVals := len(guardians.Vals)
wormchainConfig.Images[0].Version = wormchainVersion

if wormchainVersion == "local" {
wormchainConfig.Images[0].Repository = "wormchain"
}

// Create chain factory with wormchain
wormchainConfig.ModifyGenesis = ModifyGenesis(votingPeriod, maxDepositPeriod, guardians)

Expand Down
Loading
Loading