diff --git a/Makefile b/Makefile index 590896d..aad4c32 100644 --- a/Makefile +++ b/Makefile @@ -177,7 +177,7 @@ go.sum: go.mod ############################################################################### test: test-unit -test-all: test-unit test-ledger-mock test-race test-cover +test-all: test-unit test-ledger-mock test-race TEST_PACKAGES=./... TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-race test-ledger test-race diff --git a/router/ibc_middleware.go b/router/ibc_middleware.go index 59d2e65..939aefb 100644 --- a/router/ibc_middleware.go +++ b/router/ibc_middleware.go @@ -119,6 +119,18 @@ func getDenomForThisChain(port, channel, counterpartyPort, counterpartyChannel, return transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom() } +// getBoolFromAny returns the bool value is any is a valid bool, otherwise false. +func getBoolFromAny(value any) bool { + if value == nil { + return false + } + boolVal, ok := value.(bool) + if !ok { + return false + } + return boolVal +} + // OnRecvPacket checks the memo field on this packet and if the metadata inside's root key indicates this packet // should be handled by the swap middleware it attempts to perform a swap. If the swap is successful // the underlying application's OnRecvPacket callback is invoked, an ack error is returned otherwise. @@ -136,40 +148,28 @@ func (im IBCMiddleware) OnRecvPacket( "sequence", packet.Sequence, "src-channel", packet.SourceChannel, "src-port", packet.SourcePort, "dst-channel", packet.DestinationChannel, "dst-port", packet.DestinationPort, - "amount", data.Amount, "denom", data.Denom, + "amount", data.Amount, "denom", data.Denom, "memo", data.Memo, ) - m := &types.PacketMetadata{} - err := json.Unmarshal([]byte(data.Memo), m) - if err != nil || m.Forward == nil { + d := make(map[string]interface{}) + err := json.Unmarshal([]byte(data.Memo), &d) + if err != nil || d["forward"] == nil { // not a packet that should be forwarded im.keeper.Logger(ctx).Debug("packetForwardMiddleware OnRecvPacket forward metadata does not exist") return im.app.OnRecvPacket(ctx, packet, relayer) } + m := &types.PacketMetadata{} + err = json.Unmarshal([]byte(data.Memo), m) + if err != nil { + return channeltypes.NewErrorAcknowledgement(fmt.Errorf("packetForwardMiddleware error parsing forward metadata, %s", err)) + } metadata := m.Forward - var processed, nonrefundable, disableDenomComposition bool goCtx := ctx.Context() - p := goCtx.Value(types.ProcessedKey{}) - nr := goCtx.Value(types.NonrefundableKey{}) - ddc := goCtx.Value(types.DisableDenomCompositionKey{}) - - if p != nil { - if pb, ok := p.(bool); ok { - processed = pb - } - } - if nr != nil { - if nrb, ok := p.(bool); ok { - nonrefundable = nrb - } - } - if ddc != nil { - if ddcb, ok := p.(bool); ok { - disableDenomComposition = ddcb - } - } + processed := getBoolFromAny(goCtx.Value(types.ProcessedKey{})) + nonrefundable := getBoolFromAny(goCtx.Value(types.NonrefundableKey{})) + disableDenomComposition := getBoolFromAny(goCtx.Value(types.DisableDenomCompositionKey{})) if err := metadata.Validate(); err != nil { return channeltypes.NewErrorAcknowledgement(err) @@ -203,10 +203,9 @@ func (im IBCMiddleware) OnRecvPacket( token := sdk.NewCoin(denomOnThisChain, amountInt) - var timeout time.Duration - if metadata.Timeout.Nanoseconds() > 0 { - timeout = metadata.Timeout - } else { + timeout := time.Duration(metadata.Timeout) + + if timeout.Nanoseconds() <= 0 { timeout = im.forwardTimeout } diff --git a/router/keeper/keeper.go b/router/keeper/keeper.go index 099d73a..7f1c0b1 100644 --- a/router/keeper/keeper.go +++ b/router/keeper/keeper.go @@ -100,7 +100,7 @@ func (k *Keeper) WriteAcknowledgementForForwardedPacket( ack channeltypes.Acknowledgement, ) error { // Lookup module by channel capability - _, cap, err := k.channelKeeper.LookupModuleByChannel(ctx, inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId) + _, chanCap, err := k.channelKeeper.LookupModuleByChannel(ctx, inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId) if err != nil { return errorsmod.Wrap(err, "could not retrieve module from port-id") } @@ -115,7 +115,7 @@ func (k *Keeper) WriteAcknowledgementForForwardedPacket( ackResult := fmt.Sprintf("packet forward failed after point of no return: %s", ack.GetError()) newAck := channeltypes.NewResultAcknowledgement([]byte(ackResult)) - return k.ics4Wrapper.WriteAcknowledgement(ctx, cap, channeltypes.Packet{ + return k.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, channeltypes.Packet{ Data: inFlightPacket.PacketData, Sequence: inFlightPacket.RefundSequence, SourcePort: inFlightPacket.PacketSrcPortId, @@ -183,7 +183,7 @@ func (k *Keeper) WriteAcknowledgementForForwardedPacket( } } - return k.ics4Wrapper.WriteAcknowledgement(ctx, cap, channeltypes.Packet{ + return k.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, channeltypes.Packet{ Data: inFlightPacket.PacketData, Sequence: inFlightPacket.RefundSequence, SourcePort: inFlightPacket.PacketSrcPortId, @@ -303,11 +303,13 @@ func (k *Keeper) ForwardTransferPacket( store.Set(key, bz) defer func() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "ibc", "transfer"}, - float32(token.Amount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, token.Denom)}, - ) + if token.Amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "ibc", "transfer"}, + float32(token.Amount.Int64()), + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, token.Denom)}, + ) + } telemetry.IncrCounterWithLabels( []string{"ibc", types.ModuleName, "send"}, diff --git a/router/module.go b/router/module.go index ba55f44..70507dc 100644 --- a/router/module.go +++ b/router/module.go @@ -36,10 +36,10 @@ func (AppModuleBasic) Name() string { } // RegisterLegacyAminoCodec implements AppModuleBasic interface -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} +func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {} // RegisterInterfaces registers module concrete types into protobuf Any. -func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {} +func (AppModuleBasic) RegisterInterfaces(_ codectypes.InterfaceRegistry) {} // DefaultGenesis returns default genesis state as raw bytes for the ibc // router module. @@ -48,7 +48,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { } // ValidateGenesis performs genesis state validation for the router module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { var gs types.GenesisState if err := cdc.UnmarshalJSON(bz, &gs); err != nil { return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) @@ -58,7 +58,7 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod } // RegisterRESTRoutes implements AppModuleBasic interface -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) {} +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-router module. func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { @@ -89,7 +89,7 @@ func NewAppModule(k *keeper.Keeper) AppModule { } // RegisterInvariants implements the AppModule interface -func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {} +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} // Route implements the AppModule interface func (am AppModule) Route() sdk.Route { @@ -131,17 +131,17 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw func (AppModule) ConsensusVersion() uint64 { return 1 } // BeginBlock implements the AppModule interface -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {} +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} // EndBlock implements the AppModule interface -func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { return []abci.ValidatorUpdate{} } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the router module. -func (AppModule) GenerateGenesisState(simState *module.SimulationState) {} +func (AppModule) GenerateGenesisState(_ *module.SimulationState) {} // ProposalContents doesn't return any content functions for governance proposals. func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { @@ -149,12 +149,12 @@ func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedP } // RandomizedParams creates randomized ibc-router param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { +func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { return nil } // RegisterStoreDecoder registers a decoder for router module's types -func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {} +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {} // WeightedOperations returns the all the router module operations with their respective weights. func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { diff --git a/router/module_test.go b/router/module_test.go index 5f505c3..64fd78d 100644 --- a/router/module_test.go +++ b/router/module_test.go @@ -17,8 +17,9 @@ import ( ) var ( - testDenom = "uatom" - testAmount = "100" + testDenom = "uatom" + testAmount = "100" + testAmount256 = "100000000000000000000" testSourcePort = "transfer" testSourceChannel = "channel-10" @@ -64,6 +65,36 @@ func transferPacket(t *testing.T, receiver string, metadata any) channeltypes.Pa } } +func transferPacket256(t *testing.T, receiver string, metadata any) channeltypes.Packet { + t.Helper() + transferPacket := transfertypes.FungibleTokenPacketData{ + Denom: testDenom, + Amount: testAmount256, + Receiver: receiver, + } + + if metadata != nil { + if mStr, ok := metadata.(string); ok { + transferPacket.Memo = mStr + } else { + memo, err := json.Marshal(metadata) + require.NoError(t, err) + transferPacket.Memo = string(memo) + } + } + + transferData, err := transfertypes.ModuleCdc.MarshalJSON(&transferPacket) + require.NoError(t, err) + + return channeltypes.Packet{ + SourcePort: testSourcePort, + SourceChannel: testSourceChannel, + DestinationPort: testDestinationPort, + DestinationChannel: testDestinationChannel, + Data: transferData, + } +} + func TestOnRecvPacket_EmptyPacket(t *testing.T) { ctl := gomock.NewController(t) defer ctl.Finish() @@ -138,6 +169,33 @@ func TestOnRecvPacket_NoForward(t *testing.T) { require.Equal(t, "test", string(expectedAck.GetResult())) } +func TestOnRecvPacket_NoMemo(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + setup := test.NewTestSetup(t, ctl) + ctx := setup.Initializer.Ctx + cdc := setup.Initializer.Marshaler + forwardMiddleware := setup.ForwardMiddleware + + // Test data + senderAccAddr := test.AccAddress() + packet := transferPacket(t, "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k", "{}") + + // Expected mocks + gomock.InOrder( + setup.Mocks.IBCModuleMock.EXPECT().OnRecvPacket(ctx, packet, senderAccAddr). + Return(channeltypes.NewResultAcknowledgement([]byte("test"))), + ) + + ack := forwardMiddleware.OnRecvPacket(ctx, packet, senderAccAddr) + require.True(t, ack.Success()) + + expectedAck := &channeltypes.Acknowledgement{} + err := cdc.UnmarshalJSON(ack.Acknowledgement(), expectedAck) + require.NoError(t, err) + require.Equal(t, "test", string(expectedAck.GetResult())) +} + func TestOnRecvPacket_RecvPacketFailed(t *testing.T) { ctl := gomock.NewController(t) defer ctl.Finish() @@ -227,6 +285,72 @@ func TestOnRecvPacket_ForwardNoFee(t *testing.T) { require.NoError(t, err) } +func TestOnRecvPacket_ForwardAmountInt256(t *testing.T) { + var err error + ctl := gomock.NewController(t) + defer ctl.Finish() + setup := test.NewTestSetup(t, ctl) + ctx := setup.Initializer.Ctx + cdc := setup.Initializer.Marshaler + forwardMiddleware := setup.ForwardMiddleware + + // Test data + const ( + hostAddr = "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs" + destAddr = "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k" + port = "transfer" + channel = "channel-0" + ) + denom := makeIBCDenom(testDestinationPort, testDestinationChannel, testDenom) + senderAccAddr := test.AccAddress() + + amount256, ok := sdk.NewIntFromString(testAmount256) + require.True(t, ok) + + testCoin := sdk.NewCoin(denom, amount256) + packetOrig := transferPacket256(t, hostAddr, &types.PacketMetadata{ + Forward: &types.ForwardMetadata{ + Receiver: destAddr, + Port: port, + Channel: channel, + }, + }) + packetFwd := transferPacket256(t, destAddr, nil) + + acknowledgement := channeltypes.NewResultAcknowledgement([]byte("test")) + successAck := cdc.MustMarshalJSON(&acknowledgement) + + // Expected mocks + gomock.InOrder( + setup.Mocks.IBCModuleMock.EXPECT().OnRecvPacket(ctx, packetOrig, senderAccAddr). + Return(acknowledgement), + + setup.Mocks.TransferKeeperMock.EXPECT().Transfer( + sdk.WrapSDKContext(ctx), + transfertypes.NewMsgTransfer( + port, + channel, + testCoin, + hostAddr, + destAddr, + keeper.DefaultTransferPacketTimeoutHeight, + uint64(ctx.BlockTime().UnixNano())+uint64(keeper.DefaultForwardTransferPacketTimeoutTimestamp.Nanoseconds()), + ), + ).Return(&transfertypes.MsgTransferResponse{Sequence: 0}, nil), + + setup.Mocks.IBCModuleMock.EXPECT().OnAcknowledgementPacket(ctx, packetFwd, successAck, senderAccAddr). + Return(nil), + ) + + // chain B with router module receives packet and forwards. ack should be nil so that it is not written yet. + ack := forwardMiddleware.OnRecvPacket(ctx, packetOrig, senderAccAddr) + require.Nil(t, ack) + + // ack returned from chain C + err = forwardMiddleware.OnAcknowledgementPacket(ctx, packetFwd, successAck, senderAccAddr) + require.NoError(t, err) +} + func TestOnRecvPacket_ForwardWithFee(t *testing.T) { var err error ctl := gomock.NewController(t) diff --git a/router/types/forward.go b/router/types/forward.go index 9384f8c..aba0068 100644 --- a/router/types/forward.go +++ b/router/types/forward.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "errors" "fmt" "time" @@ -14,17 +15,19 @@ type PacketMetadata struct { } type ForwardMetadata struct { - Receiver string `json:"receiver,omitempty"` - Port string `json:"port,omitempty"` - Channel string `json:"channel,omitempty"` - Timeout time.Duration `json:"timeout,omitempty"` - Retries *uint8 `json:"retries,omitempty"` + Receiver string `json:"receiver,omitempty"` + Port string `json:"port,omitempty"` + Channel string `json:"channel,omitempty"` + Timeout Duration `json:"timeout,omitempty"` + Retries *uint8 `json:"retries,omitempty"` // Using JSONObject so that objects for next property will not be mutated by golang's lexicographic key sort on map keys during Marshal. // Supports primitives for Unmarshal/Marshal so that an escaped JSON-marshaled string is also valid. Next *JSONObject `json:"next,omitempty"` } +type Duration time.Duration + func (m *ForwardMetadata) Validate() error { if m.Receiver == "" { return fmt.Errorf("failed to validate forward metadata. receiver cannot be empty") @@ -86,3 +89,28 @@ func (o JSONObject) MarshalJSON() ([]byte, error) { // primitive, return raw bytes. return o.primitive, nil } + +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Duration(d).Nanoseconds()) +} + +func (d *Duration) UnmarshalJSON(b []byte) error { + var v interface{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + switch value := v.(type) { + case float64: + *d = Duration(time.Duration(value)) + return nil + case string: + tmp, err := time.ParseDuration(value) + if err != nil { + return err + } + *d = Duration(tmp) + return nil + default: + return errors.New("invalid duration") + } +} diff --git a/router/types/forward_test.go b/router/types/forward_test.go index 36205fa..83120ef 100644 --- a/router/types/forward_test.go +++ b/router/types/forward_test.go @@ -31,3 +31,29 @@ func TestForwardMetadataUnmarshalJSONNext(t *testing.T) { require.NoError(t, err) require.Equal(t, `{"forward":{"receiver":"noble1l505zhahp24v5jsmps9vs5asah759fdce06sfp","port":"transfer","channel":"channel-0","timeout":0}}`, string(nextBz)) } + +func TestTimeoutUnmarshalString(t *testing.T) { + const memo = "{\"forward\":{\"receiver\":\"noble1f4cur2krsua2th9kkp7n0zje4stea4p9tu70u8\",\"port\":\"transfer\",\"channel\":\"channel-0\",\"timeout\":\"60s\"}}" + var packetMetadata types.PacketMetadata + + err := json.Unmarshal([]byte(memo), &packetMetadata) + require.NoError(t, err) + + timeoutBz, err := json.Marshal(packetMetadata.Forward.Timeout) + require.NoError(t, err) + + require.Equal(t, "60000000000", string(timeoutBz)) +} + +func TestTimeoutUnmarshalJSON(t *testing.T) { + const memo = "{\"forward\":{\"receiver\":\"noble1f4cur2krsua2th9kkp7n0zje4stea4p9tu70u8\",\"port\":\"transfer\",\"channel\":\"channel-0\",\"timeout\": 60000000000}}" + var packetMetadata types.PacketMetadata + + err := json.Unmarshal([]byte(memo), &packetMetadata) + require.NoError(t, err) + + timeoutBz, err := json.Marshal(packetMetadata.Forward.Timeout) + require.NoError(t, err) + + require.Equal(t, "60000000000", string(timeoutBz)) +} diff --git a/router/types/genesis.pb.go b/router/types/genesis.pb.go index 2201c4d..2e4ffd9 100644 --- a/router/types/genesis.pb.go +++ b/router/types/genesis.pb.go @@ -263,48 +263,48 @@ func init() { func init() { proto.RegisterFile("router/v1/genesis.proto", fileDescriptor_4940b763c55c4e0b) } var fileDescriptor_4940b763c55c4e0b = []byte{ - // 646 bytes of a gzipped FileDescriptorProto + // 647 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x54, 0x4d, 0x4f, 0xdb, 0x3e, 0x18, 0x6f, 0x4a, 0x29, 0xd4, 0x2d, 0x6f, 0xfe, 0xc3, 0x9f, 0x8c, 0x43, 0x5b, 0x55, 0x68, 0xab, - 0xc6, 0x9a, 0x08, 0x90, 0x26, 0xc4, 0x6d, 0x1d, 0x1b, 0xeb, 0xad, 0x4a, 0x39, 0x4d, 0x9a, 0x22, - 0x93, 0x3c, 0x4d, 0x23, 0x12, 0x3b, 0xb3, 0x9d, 0xb2, 0xee, 0x53, 0xec, 0xbc, 0xcb, 0xbe, 0x0e, - 0x47, 0x8e, 0xd3, 0x0e, 0xd5, 0x04, 0xdf, 0x80, 0x4f, 0x30, 0xc5, 0x4e, 0xa1, 0xd5, 0x76, 0x8a, - 0xfd, 0xfc, 0x5e, 0xfc, 0x7b, 0x9e, 0x58, 0x46, 0xbb, 0x9c, 0xa5, 0x12, 0xb8, 0x3d, 0x3e, 0xb4, - 0x03, 0xa0, 0x20, 0x42, 0x61, 0x25, 0x9c, 0x49, 0x86, 0x2b, 0x1a, 0xb0, 0xc6, 0x87, 0x7b, 0xdb, - 0x01, 0x0b, 0x98, 0xaa, 0xda, 0xd9, 0x4a, 0x13, 0x5a, 0xdf, 0x8b, 0xa8, 0x76, 0xae, 0x25, 0x03, - 0x49, 0x24, 0x60, 0x1b, 0x95, 0x13, 0xc2, 0x49, 0x2c, 0x4c, 0xa3, 0x69, 0xb4, 0xab, 0x47, 0x5b, - 0xd6, 0xa3, 0x85, 0xd5, 0x57, 0x40, 0xb7, 0x74, 0x33, 0x6d, 0x14, 0x9c, 0x9c, 0x86, 0xbf, 0xa2, - 0xad, 0x90, 0xba, 0xc3, 0x28, 0x0c, 0x46, 0xd2, 0x4d, 0x88, 0x77, 0x05, 0x52, 0x98, 0xc5, 0xe6, - 0x52, 0xbb, 0x7a, 0xf4, 0x6a, 0x4e, 0x3b, 0x7f, 0x88, 0xd5, 0xa3, 0xef, 0x15, 0xbf, 0xaf, 0xe9, - 0xef, 0xa8, 0xe4, 0x93, 0x6e, 0x33, 0xb3, 0x7d, 0x98, 0x36, 0xcc, 0x09, 0x89, 0xa3, 0xd3, 0xd6, - 0x5f, 0xa6, 0x2d, 0x67, 0x23, 0x5c, 0xd4, 0xed, 0x7d, 0x42, 0xdb, 0xff, 0xb2, 0xc2, 0x9b, 0x68, - 0xe9, 0x0a, 0x26, 0xaa, 0x83, 0x8a, 0x93, 0x2d, 0xb1, 0x8d, 0x96, 0xc7, 0x24, 0x4a, 0xc1, 0x2c, - 0xaa, 0xae, 0x9e, 0xcd, 0x25, 0x5b, 0x74, 0x70, 0x34, 0xef, 0xb4, 0x78, 0x62, 0xb4, 0xbe, 0xa0, - 0xb2, 0x6e, 0x19, 0x53, 0xb4, 0x3e, 0x04, 0x70, 0x13, 0xe0, 0x1e, 0x50, 0x49, 0x02, 0xd0, 0xde, - 0xdd, 0xf3, 0x2c, 0xf3, 0xaf, 0x69, 0xe3, 0x79, 0x10, 0xca, 0x51, 0x7a, 0x69, 0x79, 0x2c, 0xb6, - 0x3d, 0x26, 0x62, 0x26, 0xf2, 0x4f, 0x47, 0xf8, 0x57, 0xb6, 0x9c, 0x24, 0x20, 0xac, 0x33, 0xf0, - 0x1e, 0xa6, 0x8d, 0x1d, 0xdd, 0xdd, 0xa2, 0x5b, 0xcb, 0x59, 0x1b, 0x02, 0xf4, 0x9f, 0xf6, 0x3f, - 0x4a, 0x68, 0x7d, 0x31, 0x17, 0x7e, 0x8d, 0x76, 0x19, 0x0f, 0x83, 0x90, 0x92, 0xc8, 0x15, 0x40, - 0x7d, 0xe0, 0x2e, 0xf1, 0x7d, 0x0e, 0x42, 0xe4, 0x7d, 0xee, 0xcc, 0xe0, 0x81, 0x42, 0xdf, 0x68, - 0x10, 0xbf, 0x44, 0x5b, 0x1c, 0x86, 0x29, 0xf5, 0x5d, 0x6f, 0x44, 0x28, 0x85, 0xc8, 0x0d, 0x7d, - 0x35, 0x85, 0x8a, 0xb3, 0xa1, 0x81, 0xb7, 0xba, 0xde, 0xf3, 0xf1, 0x3e, 0x5a, 0xcf, 0xb9, 0x09, - 0xe3, 0x32, 0x23, 0x2e, 0x29, 0x62, 0x4d, 0x57, 0xfb, 0x8c, 0xcb, 0x9e, 0x8f, 0x0f, 0xd1, 0x8e, - 0xfe, 0x25, 0xae, 0xe0, 0xde, 0xbc, 0x6b, 0x49, 0x91, 0xb1, 0x06, 0x07, 0xdc, 0x7b, 0x32, 0x3e, - 0x40, 0x78, 0x4e, 0x32, 0x33, 0x5f, 0xd6, 0x29, 0x1e, 0xf9, 0xb9, 0xff, 0x09, 0x32, 0x73, 0xb2, - 0x0c, 0x63, 0x60, 0xa9, 0xfe, 0x0a, 0x49, 0xe2, 0xc4, 0x2c, 0x37, 0x8d, 0x76, 0xc9, 0xf9, 0x5f, - 0xe3, 0x17, 0x1a, 0xbe, 0x98, 0xa1, 0xf8, 0xe8, 0x31, 0xd9, 0x4c, 0x39, 0x82, 0x6c, 0x84, 0xe6, - 0x8a, 0x3a, 0xe9, 0xbf, 0x05, 0xd9, 0x07, 0x05, 0xe1, 0x06, 0xaa, 0xe6, 0x1a, 0x9f, 0x48, 0x62, - 0xae, 0x36, 0x8d, 0x76, 0xcd, 0x41, 0xba, 0x74, 0x46, 0x24, 0xc1, 0x2f, 0x50, 0x3e, 0x27, 0x57, - 0xc0, 0xe7, 0x14, 0xa8, 0x07, 0x66, 0x45, 0xa5, 0xc8, 0x67, 0x35, 0xc8, 0xab, 0xf8, 0x20, 0x9b, - 0xb4, 0xe4, 0x21, 0x08, 0x97, 0x43, 0x4c, 0x42, 0x1a, 0xd2, 0xc0, 0x44, 0x4d, 0xa3, 0xbd, 0xec, - 0x6c, 0xe6, 0x80, 0x33, 0xab, 0x63, 0x13, 0xad, 0xe4, 0x19, 0xcd, 0xaa, 0x72, 0x9b, 0x6d, 0xf1, - 0x3e, 0x5a, 0xa3, 0x8c, 0x6a, 0x6f, 0x72, 0x19, 0x81, 0x59, 0x6b, 0x1a, 0xed, 0x55, 0x67, 0xb1, - 0xd8, 0xf5, 0x6e, 0xee, 0xea, 0xc6, 0xed, 0x5d, 0xdd, 0xf8, 0x7d, 0x57, 0x37, 0xbe, 0xdd, 0xd7, - 0x0b, 0xb7, 0xf7, 0xf5, 0xc2, 0xcf, 0xfb, 0x7a, 0xe1, 0x63, 0x6f, 0xee, 0x2e, 0x0a, 0xc9, 0x09, - 0x0d, 0x20, 0x62, 0x63, 0xe8, 0x8c, 0x81, 0xca, 0x94, 0x83, 0xb0, 0x75, 0x6f, 0x9d, 0x21, 0xe3, - 0xd7, 0x84, 0xfb, 0x9d, 0x38, 0xf4, 0xfd, 0x08, 0xae, 0x09, 0x07, 0x7b, 0x7c, 0x6c, 0xe7, 0x2f, - 0x89, 0xba, 0xb2, 0x97, 0x65, 0xf5, 0x48, 0x1c, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x70, 0xb8, - 0x71, 0x32, 0x60, 0x04, 0x00, 0x00, + 0xc6, 0x9a, 0x08, 0xa6, 0x4d, 0x88, 0xdb, 0x3a, 0x36, 0xd6, 0x5b, 0x95, 0x72, 0x9a, 0x34, 0x45, + 0x26, 0x79, 0x9a, 0x46, 0x24, 0x76, 0x66, 0x3b, 0x65, 0xdd, 0xa7, 0xd8, 0x79, 0x97, 0x7d, 0x1d, + 0x8e, 0x1c, 0xa7, 0x1d, 0xaa, 0x09, 0xbe, 0x01, 0x9f, 0x60, 0x8a, 0x9d, 0x42, 0xab, 0xed, 0x14, + 0xfb, 0xf9, 0xbd, 0xf8, 0xf7, 0x3c, 0xb1, 0x8c, 0x76, 0x39, 0x4b, 0x25, 0x70, 0x7b, 0x7c, 0x68, + 0x07, 0x40, 0x41, 0x84, 0xc2, 0x4a, 0x38, 0x93, 0x0c, 0x57, 0x34, 0x60, 0x8d, 0x0f, 0xf7, 0xb6, + 0x03, 0x16, 0x30, 0x55, 0xb5, 0xb3, 0x95, 0x26, 0xb4, 0xbe, 0x17, 0x51, 0xed, 0x4c, 0x4b, 0x06, + 0x92, 0x48, 0xc0, 0x36, 0x2a, 0x27, 0x84, 0x93, 0x58, 0x98, 0x46, 0xd3, 0x68, 0x57, 0x8f, 0xb6, + 0xac, 0x07, 0x0b, 0xab, 0xaf, 0x80, 0x6e, 0xe9, 0x7a, 0xda, 0x28, 0x38, 0x39, 0x0d, 0x7f, 0x45, + 0x5b, 0x21, 0x75, 0x87, 0x51, 0x18, 0x8c, 0xa4, 0x9b, 0x10, 0xef, 0x12, 0xa4, 0x30, 0x8b, 0xcd, + 0xa5, 0x76, 0xf5, 0xe8, 0xc5, 0x9c, 0x76, 0xfe, 0x10, 0xab, 0x47, 0xdf, 0x2b, 0x7e, 0x5f, 0xd3, + 0xdf, 0x51, 0xc9, 0x27, 0xdd, 0x66, 0x66, 0x7b, 0x3f, 0x6d, 0x98, 0x13, 0x12, 0x47, 0x27, 0xad, + 0xbf, 0x4c, 0x5b, 0xce, 0x46, 0xb8, 0xa8, 0xdb, 0xfb, 0x84, 0xb6, 0xff, 0x65, 0x85, 0x37, 0xd1, + 0xd2, 0x25, 0x4c, 0x54, 0x07, 0x15, 0x27, 0x5b, 0x62, 0x1b, 0x2d, 0x8f, 0x49, 0x94, 0x82, 0x59, + 0x54, 0x5d, 0x3d, 0x99, 0x4b, 0xb6, 0xe8, 0xe0, 0x68, 0xde, 0x49, 0xf1, 0xd8, 0x68, 0x7d, 0x41, + 0x65, 0xdd, 0x32, 0xa6, 0x68, 0x7d, 0x08, 0xe0, 0x26, 0xc0, 0x3d, 0xa0, 0x92, 0x04, 0xa0, 0xbd, + 0xbb, 0x67, 0x59, 0xe6, 0x5f, 0xd3, 0xc6, 0xd3, 0x20, 0x94, 0xa3, 0xf4, 0xc2, 0xf2, 0x58, 0x6c, + 0x7b, 0x4c, 0xc4, 0x4c, 0xe4, 0x9f, 0x8e, 0xf0, 0x2f, 0x6d, 0x39, 0x49, 0x40, 0x58, 0xa7, 0xe0, + 0xdd, 0x4f, 0x1b, 0x3b, 0xba, 0xbb, 0x45, 0xb7, 0x96, 0xb3, 0x36, 0x04, 0xe8, 0x3f, 0xee, 0x7f, + 0x94, 0xd0, 0xfa, 0x62, 0x2e, 0xfc, 0x1a, 0xed, 0x32, 0x1e, 0x06, 0x21, 0x25, 0x91, 0x2b, 0x80, + 0xfa, 0xc0, 0x5d, 0xe2, 0xfb, 0x1c, 0x84, 0xc8, 0xfb, 0xdc, 0x99, 0xc1, 0x03, 0x85, 0xbe, 0xd1, + 0x20, 0x7e, 0x8e, 0xb6, 0x38, 0x0c, 0x53, 0xea, 0xbb, 0xde, 0x88, 0x50, 0x0a, 0x91, 0x1b, 0xfa, + 0x6a, 0x0a, 0x15, 0x67, 0x43, 0x03, 0x6f, 0x75, 0xbd, 0xe7, 0xe3, 0x7d, 0xb4, 0x9e, 0x73, 0x13, + 0xc6, 0x65, 0x46, 0x5c, 0x52, 0xc4, 0x9a, 0xae, 0xf6, 0x19, 0x97, 0x3d, 0x1f, 0x1f, 0xa2, 0x1d, + 0xfd, 0x4b, 0x5c, 0xc1, 0xbd, 0x79, 0xd7, 0x92, 0x22, 0x63, 0x0d, 0x0e, 0xb8, 0xf7, 0x68, 0x7c, + 0x80, 0xf0, 0x9c, 0x64, 0x66, 0xbe, 0xac, 0x53, 0x3c, 0xf0, 0x73, 0xff, 0x63, 0x64, 0xe6, 0x64, + 0x19, 0xc6, 0xc0, 0x52, 0xfd, 0x15, 0x92, 0xc4, 0x89, 0x59, 0x6e, 0x1a, 0xed, 0x92, 0xf3, 0xbf, + 0xc6, 0xcf, 0x35, 0x7c, 0x3e, 0x43, 0xf1, 0xd1, 0x43, 0xb2, 0x99, 0x72, 0x04, 0xd9, 0x08, 0xcd, + 0x15, 0x75, 0xd2, 0x7f, 0x0b, 0xb2, 0x0f, 0x0a, 0xc2, 0x0d, 0x54, 0xcd, 0x35, 0x3e, 0x91, 0xc4, + 0x5c, 0x6d, 0x1a, 0xed, 0x9a, 0x83, 0x74, 0xe9, 0x94, 0x48, 0x82, 0x9f, 0xa1, 0x7c, 0x4e, 0xae, + 0x80, 0xcf, 0x29, 0x50, 0x0f, 0xcc, 0x8a, 0x4a, 0x91, 0xcf, 0x6a, 0x90, 0x57, 0xf1, 0x41, 0x36, + 0x69, 0xc9, 0x43, 0x10, 0x2e, 0x87, 0x98, 0x84, 0x34, 0xa4, 0x81, 0x89, 0x9a, 0x46, 0x7b, 0xd9, + 0xd9, 0xcc, 0x01, 0x67, 0x56, 0xc7, 0x26, 0x5a, 0xc9, 0x33, 0x9a, 0x55, 0xe5, 0x36, 0xdb, 0xe2, + 0x7d, 0xb4, 0x46, 0x19, 0xd5, 0xde, 0xe4, 0x22, 0x02, 0xb3, 0xd6, 0x34, 0xda, 0xab, 0xce, 0x62, + 0xb1, 0xeb, 0x5d, 0xdf, 0xd6, 0x8d, 0x9b, 0xdb, 0xba, 0xf1, 0xfb, 0xb6, 0x6e, 0x7c, 0xbb, 0xab, + 0x17, 0x6e, 0xee, 0xea, 0x85, 0x9f, 0x77, 0xf5, 0xc2, 0xc7, 0xde, 0xdc, 0x5d, 0x14, 0x92, 0x13, + 0x1a, 0x40, 0xc4, 0xc6, 0xd0, 0x19, 0x03, 0x95, 0x29, 0x07, 0x61, 0xeb, 0xde, 0x3a, 0x43, 0xc6, + 0xaf, 0x08, 0xf7, 0x3b, 0x71, 0xe8, 0xfb, 0x11, 0x5c, 0x11, 0x0e, 0xf6, 0xf8, 0x95, 0x9d, 0xbf, + 0x24, 0xea, 0xca, 0x5e, 0x94, 0xd5, 0x23, 0xf1, 0xf2, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, + 0xe2, 0x80, 0x40, 0x60, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) {