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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 5 additions & 3 deletions .github/workflows/wormchain-icts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
outputs: type=docker,dest=${{ env.TAR_PATH }}

- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}
path: ${{ env.TAR_PATH }}
Expand All @@ -59,9 +59,11 @@ jobs:
# names of `make` commands to run tests
test:
- "ictest-cancel-upgrade"
- "ictest-slashing-params-update-vaa"
- "ictest-upgrade"
- "ictest-wormchain"
- "ictest-ibc-receiver"
# Disabled due to flakiness in CI.
# - "ictest-ibc-receiver"
- "ictest-validator-hotswap"
- "ictest-cw-wormhole"
fail-fast: false
Expand All @@ -77,7 +79,7 @@ jobs:
uses: actions/checkout@v4

- name: Download Tarball Artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ env.IMAGE_NAME }}
path: /tmp
Expand Down
50 changes: 50 additions & 0 deletions sdk/vaa/payloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ var (
ActionScheduleUpgrade GovernanceAction = 1
ActionCancelUpgrade GovernanceAction = 2
ActionSetIbcComposabilityMwContract GovernanceAction = 3
ActionSlashingParamsUpdate GovernanceAction = 4

// Accountant governance actions
ActionModifyBalance GovernanceAction = 1
Expand Down Expand Up @@ -193,6 +194,32 @@ type (
ContractAddr [32]byte
}

// BodyGatewaySlashingParamsUpdate 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.
BodyGatewaySlashingParamsUpdate struct {
SignedBlocksWindow uint64
MinSignedPerWindow uint64
DowntimeJailDuration uint64
SlashFractionDoubleSign uint64
SlashFractionDowntime uint64
}

// BodyCircleIntegrationUpdateWormholeFinality is a governance message to update the wormhole finality for Circle Integration.
BodyCircleIntegrationUpdateWormholeFinality struct {
TargetChainID ChainID
Expand Down Expand Up @@ -393,6 +420,29 @@ func (r *BodyGatewayIbcComposabilityMwContract) Deserialize(bz []byte) error {
return nil
}

func (b BodyGatewaySlashingParamsUpdate) Serialize() ([]byte, error) {
payload := new(bytes.Buffer)
MustWrite(payload, binary.BigEndian, b.SignedBlocksWindow)
MustWrite(payload, binary.BigEndian, b.MinSignedPerWindow)
MustWrite(payload, binary.BigEndian, b.DowntimeJailDuration)
MustWrite(payload, binary.BigEndian, b.SlashFractionDoubleSign)
MustWrite(payload, binary.BigEndian, b.SlashFractionDowntime)
return serializeBridgeGovernanceVaa(GatewayModuleStr, ActionSlashingParamsUpdate, ChainIDWormchain, payload.Bytes())
}

func (r *BodyGatewaySlashingParamsUpdate) Deserialize(bz []byte) error {
if len(bz) != 40 {
return fmt.Errorf("incorrect payload length, should be 40, is %d", len(bz))
}

r.SignedBlocksWindow = binary.BigEndian.Uint64(bz[0:8])
r.MinSignedPerWindow = binary.BigEndian.Uint64(bz[8:16])
r.DowntimeJailDuration = binary.BigEndian.Uint64(bz[16:24])
r.SlashFractionDoubleSign = binary.BigEndian.Uint64(bz[24:32])
r.SlashFractionDowntime = binary.BigEndian.Uint64(bz[32:40])
return nil
}

func (r BodyGatewayScheduleUpgrade) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write([]byte(r.Name))
Expand Down
58 changes: 58 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 @@ -363,6 +364,63 @@ func TestBodyGatewayIbcComposabilityMwContractDeserializeFailureTooLong(t *testi
require.ErrorContains(t, err, "incorrect payload length, should be 32, is 33")
}

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

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

expected := "00000000000000000000000000000000000000476174657761794d6f64756c65040c20000000000000006406f05b59d3b200000000008bb2c9700000b1a2bc2ec50000002386f26fc10000"
assert.Equal(t, expected, hex.EncodeToString(serializedBody))
}

const BodySlashingParamsUpdateBuf = "000000000000006406f05b59d3b200000000008bb2c9700000b1a2bc2ec50000002386f26fc10000"

func TestBodySlashingParamsUpdateDeserialize(t *testing.T) {
expected := BodyGatewaySlashingParamsUpdate{
SignedBlocksWindow: 100,
MinSignedPerWindow: 500000000000000000,
DowntimeJailDuration: uint64(600 * time.Second),
SlashFractionDoubleSign: 50000000000000000,
SlashFractionDowntime: 10000000000000000,
}
var payloadBody BodyGatewaySlashingParamsUpdate
bz, err := hex.DecodeString(BodySlashingParamsUpdateBuf)
require.NoError(t, err)
err = payloadBody.Deserialize(bz)
require.NoError(t, err)
assert.Equal(t, expected, payloadBody)
}

func TestBodySlashingParamsUpdateDeserializeFailureTooShort(t *testing.T) {
buf, err := hex.DecodeString(BodySlashingParamsUpdateBuf[0 : len(BodySlashingParamsUpdateBuf)-2])
require.NoError(t, err)

var actual BodyGatewaySlashingParamsUpdate
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 40, is 39")
}

func TestBodySlashingParamsUpdateDeserializeFailureTooLong(t *testing.T) {
buf, err := hex.DecodeString(BodySlashingParamsUpdateBuf + "00")
require.NoError(t, err)

var actual BodyGatewaySlashingParamsUpdate
err = actual.Deserialize(buf)
require.ErrorContains(t, err, "incorrect payload length, should be 40, is 41")
}

func TestBodyCoreRecoverChainIdSerialize(t *testing.T) {
expected := "00000000000000000000000000000000000000000000000000000000436f72650500000000000000000000000000000000000000000000000000000000000000010fa0"
BodyRecoverChainId := BodyRecoverChainId{
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
2 changes: 1 addition & 1 deletion wormchain/Dockerfile.ict
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ 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
COPY --from=builder /go/pkg/mod/github.com/!cosm!wasm/[email protected]/internal/api/* /usr/lib/

EXPOSE 26657
EXPOSE 26656
Expand Down
15 changes: 13 additions & 2 deletions wormchain/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,29 +90,40 @@ local-image: build/wormchaind
# Individual Tests ($$ is interpreted as $)
rm-testcache:
go clean -testcache
.PHONY: rm-testcache

ictest-cancel-upgrade: rm-testcache
cd interchaintest && go test -race -v -run ^TestCancelUpgrade$$ ./...
.PHONY: ictest-cancel-upgrade

ictest-malformed-payload: rm-testcache
cd interchaintest && go test -race -v -run ^TestMalformedPayload$$ ./...
.PHONY: ictest-malformed-payload

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

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

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

ictest-wormchain: rm-testcache
cd interchaintest && go test -race -v -run ^TestWormchain$$ ./...
.PHONY: ictest-wormchain

ictest-ibc-receiver: rm-testcache
cd interchaintest && go test -race -v -run ^TestIbcReceiver ./...
.PHONY: ictest-ibc-receiver

ictest-cw-wormhole: rm-testcache
cd interchaintest && go test -race -v -run ^TestCWWormhole ./...
.PHONY: ictest-cw-wormhole

ictest-validator-hotswap: rm-testcache
cd interchaintest && go test -race -v -run ^TestValidatorHotswap$$ ./...

.PHONY: ictest-cancel-upgrade ictest-malformed-payload ictest-upgrade-failure ictest-upgrade ictest-wormchain ictest-ibc-receiver ictest-cw-wormhole ictest-validator-hotswap
.PHONY: ictest-validator-hotswap
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
4 changes: 2 additions & 2 deletions wormchain/interchaintest/helpers/vaa.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,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 Expand Up @@ -58,7 +58,7 @@ func GenerateEmptyVAA(

payloadBz, err := vaa.EmptyPayloadVaa(moduleStr, action, chainID)
require.NoError(t, err)
v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)
v := GenerateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz)

v = signVaa(v, guardians)
vBz, err := v.Marshal()
Expand Down
Loading
Loading