From be1012c8d14090d6625a8b854b1e5904089ea133 Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Sat, 7 Nov 2020 00:57:07 +1000 Subject: [PATCH 01/57] remove cast to int64 for amount multiplied by PowerReduction --- x/slashing/handler_test.go | 8 ++++---- x/slashing/keeper/keeper_test.go | 2 +- x/staking/handler_test.go | 10 +++++----- x/staking/keeper/slash_test.go | 14 ++++++------- x/staking/keeper/validator_test.go | 32 +++++++++++++++--------------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index c392bde585..17cd16b896 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -214,10 +214,10 @@ func TestHandleAbsentValidator(t *testing.T) { validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, stakingtypes.Unbonding, validator.GetStatus()) - slashAmt := amt.ToDec().Mul(app.SlashingKeeper.SlashFractionDowntime(ctx)).RoundInt64() + slashAmt := amt.ToDec().Mul(app.SlashingKeeper.SlashFractionDowntime(ctx)).RoundInt() // validator should have been slashed - require.Equal(t, amt.Int64()-slashAmt, validator.GetTokens().Int64()) + require.True(t, amt.Sub(slashAmt).Equal(validator.GetTokens())) // 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator) height++ @@ -233,7 +233,7 @@ func TestHandleAbsentValidator(t *testing.T) { // validator should not have been slashed any more, since it was already jailed validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - require.Equal(t, amt.Int64()-slashAmt, validator.GetTokens().Int64()) + require.True(t, amt.Sub(slashAmt).Equal(validator.GetTokens())) // unrevocation should fail prior to jail expiration res, err := slh(ctx, types.NewMsgUnjail(addr)) @@ -254,7 +254,7 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, stakingtypes.Bonded, validator.GetStatus()) // validator should have been slashed - require.Equal(t, amt.Int64()-slashAmt, app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount.Int64()) + require.True(t, amt.Sub(slashAmt).Equal(app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount)) // Validator start height should not have been changed info, found = app.SlashingKeeper.GetValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) diff --git a/x/slashing/keeper/keeper_test.go b/x/slashing/keeper/keeper_test.go index 035090341c..076dd16735 100644 --- a/x/slashing/keeper/keeper_test.go +++ b/x/slashing/keeper/keeper_test.go @@ -117,7 +117,7 @@ func TestHandleNewValidator(t *testing.T) { require.Equal(t, stakingtypes.Bonded, validator.GetStatus()) bondPool := app.StakingKeeper.GetBondedPool(ctx) expTokens := sdk.TokensFromConsensusPower(100) - require.Equal(t, expTokens.Int64(), app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount.Int64()) + require.True(t, expTokens.Equal(app.BankKeeper.GetBalance(ctx, bondPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)).Amount)) } // Test a jailed validator being "down" twice diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 34a8cd78e7..c1feb8f5ee 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -281,7 +281,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.Equal(t, bondAmount, bond.Shares.RoundInt()) bondedTokens := app.StakingKeeper.TotalBondedTokens(ctx) - require.Equal(t, bondAmount.Int64(), bondedTokens.Int64()) + require.True(t, bondAmount.Equal(bondedTokens)) for i := int64(0); i < 5; i++ { ctx = ctx.WithBlockHeight(i) @@ -436,13 +436,13 @@ func TestIncrementsMsgUnbond(t *testing.T) { gotDelegatorShares := validator.DelegatorShares.RoundInt() gotDelegatorAcc := app.BankKeeper.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount - require.Equal(t, expBond.Int64(), gotBond.Int64(), + require.True(t, expBond.Equal(gotBond), "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", i, expBond, gotBond, validator, bond) - require.Equal(t, expDelegatorShares.Int64(), gotDelegatorShares.Int64(), + require.True(t, expDelegatorShares.Equal(gotDelegatorShares), "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorShares, gotDelegatorShares, validator, bond) - require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(), + require.True(t, expDelegatorAcc.Equal(gotDelegatorAcc), "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorAcc, gotDelegatorAcc, validator, bond) } @@ -740,7 +740,7 @@ func TestRedelegationPeriod(t *testing.T) { // balance should have been subtracted after creation amt2 := app.BankKeeper.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount - require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") + require.True(t, amt1.Sub(sdk.NewInt(10)).Equal(amt2), "expected coins to be subtracted") tstaking.CreateValidator(validatorAddr2, PKs[1], 10, true) bal1 := app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 4bee623004..356c022e4e 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -90,13 +90,13 @@ func TestSlashUnbondingDelegation(t *testing.T) { // unbonding started prior to the infraction height, stakw didn't contribute slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(0))) // after the expiration time, no longer eligible for slashing ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(10, 0)}) app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(0))) // test valid slash, before expiration timestamp and to which stake contributed notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) @@ -104,7 +104,7 @@ func TestSlashUnbondingDelegation(t *testing.T) { ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(0, 0)}) app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(5))) ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.Len(t, ubd.Entries, 1) @@ -116,7 +116,7 @@ func TestSlashUnbondingDelegation(t *testing.T) { require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance) newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) - require.Equal(t, int64(5), diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Int64()) + require.True(t, diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Equal(sdk.NewInt(5))) } // tests slashRedelegation @@ -147,7 +147,7 @@ func TestSlashRedelegation(t *testing.T) { validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1]) require.True(t, found) slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(0))) // after the expiration time, no longer eligible for slashing ctx = ctx.WithBlockHeader(tmproto.Header{Time: time.Unix(10, 0)}) @@ -155,7 +155,7 @@ func TestSlashRedelegation(t *testing.T) { validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) require.True(t, found) slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(0))) balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) @@ -165,7 +165,7 @@ func TestSlashRedelegation(t *testing.T) { validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) require.True(t, found) slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) + require.True(t, slashAmount.Equal(sdk.NewInt(5))) rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) require.Len(t, rd.Entries, 1) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index c28b6db358..5bf9ee247e 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -349,19 +349,19 @@ func TestGetValidatorSortingUnmixed(t *testing.T) { app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} + amts := []sdk.Int{ + sdk.NewIntFromUint64(0), + sdk.PowerReduction.MulRaw(100), + sdk.PowerReduction, + sdk.PowerReduction.MulRaw(400), + sdk.PowerReduction.MulRaw(200)} n := len(amts) var validators [5]types.Validator for i, amt := range amts { validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i]) validators[i].Status = types.Bonded - validators[i].Tokens = sdk.NewInt(amt) - validators[i].DelegatorShares = sdk.NewDec(amt) + validators[i].Tokens = amt + validators[i].DelegatorShares = sdk.NewDecFromInt(amt) keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) } @@ -445,19 +445,19 @@ func TestGetValidatorSortingMixed(t *testing.T) { app.StakingKeeper.SetParams(ctx, params) // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} + amts := []sdk.Int{ + sdk.NewIntFromUint64(0), + sdk.PowerReduction.MulRaw(100), + sdk.PowerReduction, + sdk.PowerReduction.MulRaw(400), + sdk.PowerReduction.MulRaw(200)} var validators [5]types.Validator for i, amt := range amts { validators[i] = teststaking.NewValidator(t, sdk.ValAddress(addrs[i]), PKs[i]) - validators[i].DelegatorShares = sdk.NewDec(amt) + validators[i].DelegatorShares = sdk.NewDecFromInt(amt) validators[i].Status = types.Bonded - validators[i].Tokens = sdk.NewInt(amt) + validators[i].Tokens = amt keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) } From ebb7698339cb548dc6543f589748cd2ba503f59e Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Tue, 10 Nov 2020 00:14:10 +1000 Subject: [PATCH 02/57] status update for power reduction test --- x/staking/common_test.go | 4 +-- x/staking/genesis_test.go | 2 +- x/staking/handler_test.go | 76 +++++++++++++++++++++++---------------- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 30072c7b58..640fd2e2e1 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -48,8 +48,8 @@ func getBaseSimappWithCustomKeeper() (*codec.LegacyAmino, *simapp.SimApp, sdk.Co } // generateAddresses generates numAddrs of normal AccAddrs and ValAddrs -func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount int64) ([]sdk.AccAddress, []sdk.ValAddress) { - addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(accAmount)) +func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount sdk.Int) ([]sdk.AccAddress, []sdk.ValAddress) { + addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, accAmount) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) return addrDels, addrVals diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 64306de276..2e50e2f6a7 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -21,7 +21,7 @@ import ( func bootstrapGenesisTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() - addrDels, _ := generateAddresses(app, ctx, numAddrs, 10000) + addrDels, _ := generateAddresses(app, ctx, numAddrs, sdk.NewInt(10000)) amt := sdk.TokensFromConsensusPower(power) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index c1feb8f5ee..e2ba458e63 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -24,7 +24,7 @@ import ( "github.com/golang/protobuf/proto" ) -func bootstrapHandlerGenesisTest(t *testing.T, power int64, numAddrs int, accAmount int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { +func bootstrapHandlerGenesisTest(t *testing.T, power int64, numAddrs int, accAmount sdk.Int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() addrDels, addrVals := generateAddresses(app, ctx, numAddrs, accAmount) @@ -44,7 +44,7 @@ func bootstrapHandlerGenesisTest(t *testing.T, power int64, numAddrs int, accAmo func TestValidatorByPowerIndex(t *testing.T) { initPower := int64(1000000) - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, sdk.TokensFromConsensusPower(initPower)) validatorAddr, validatorAddr3 := valAddrs[0], valAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -121,7 +121,7 @@ func TestValidatorByPowerIndex(t *testing.T) { func TestDuplicatesMsgCreateValidator(t *testing.T) { initPower := int64(1000000) - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, sdk.TokensFromConsensusPower(initPower)) addr1, addr2 := valAddrs[0], valAddrs[1] pk1, pk2 := PKs[0], PKs[1] @@ -164,7 +164,8 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { } func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, sdk.TokensFromConsensusPower(initPower)) ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ Validator: &tmproto.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}}, }) @@ -178,7 +179,8 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { } func TestLegacyValidatorDelegations(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 100000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) valAddr := valAddrs[0] @@ -258,7 +260,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { func TestIncrementsMsgDelegate(t *testing.T) { initPower := int64(1000) initBond := sdk.TokensFromConsensusPower(initPower) - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) params := app.StakingKeeper.GetParams(ctx) validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] @@ -281,7 +283,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.Equal(t, bondAmount, bond.Shares.RoundInt()) bondedTokens := app.StakingKeeper.TotalBondedTokens(ctx) - require.True(t, bondAmount.Equal(bondedTokens)) + require.Equal(t, bondAmount.Int64(), bondedTokens.Int64()) for i := int64(0); i < 5; i++ { ctx = ctx.WithBlockHeight(i) @@ -317,7 +319,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { initPower := int64(100) initBond := sdk.TokensFromConsensusPower(100) - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, 1000000000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, sdk.TokensFromConsensusPower(initPower)) validatorAddr := valAddrs[0] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -349,7 +351,7 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { initPower := int64(100) initBond := sdk.TokensFromConsensusPower(100) - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) validatorAddr := valAddrs[0] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -379,7 +381,7 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { func TestIncrementsMsgUnbond(t *testing.T) { initPower := int64(1000) - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) params := app.StakingKeeper.GetParams(ctx) denom := params.BondDenom @@ -436,13 +438,13 @@ func TestIncrementsMsgUnbond(t *testing.T) { gotDelegatorShares := validator.DelegatorShares.RoundInt() gotDelegatorAcc := app.BankKeeper.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount - require.True(t, expBond.Equal(gotBond), + require.Equal(t, expBond.Int64(), gotBond.Int64(), "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", i, expBond, gotBond, validator, bond) - require.True(t, expDelegatorShares.Equal(gotDelegatorShares), + require.Equal(t, expDelegatorShares.Int64(), gotDelegatorShares.Int64(), "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorShares, gotDelegatorShares, validator, bond) - require.True(t, expDelegatorAcc.Equal(gotDelegatorAcc), + require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(), "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorAcc, gotDelegatorAcc, validator, bond) } @@ -468,7 +470,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { func TestMultipleMsgCreateValidator(t *testing.T) { initPower := int64(1000) initTokens := sdk.TokensFromConsensusPower(initPower) - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, 1000000000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, sdk.TokensFromConsensusPower(initPower)) params := app.StakingKeeper.GetParams(ctx) blockTime := time.Now().UTC() @@ -499,7 +501,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) { balanceGot := app.BankKeeper.GetBalance(ctx, delegatorAddrs[i], params.BondDenom).Amount require.Equal(t, i+1, len(validators), "expected %d validators got %d, validators: %v", i+1, len(validators), validators) - require.Equal(t, amt, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", 10, val.DelegatorShares) + require.Equal(t, amt, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", amt, val.DelegatorShares) require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) } @@ -536,7 +538,8 @@ func TestMultipleMsgCreateValidator(t *testing.T) { } func TestMultipleMsgDelegate(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 50, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 50, sdk.TokensFromConsensusPower(initPower)) validatorAddr, delegatorAddrs := valAddrs[0], delAddrs[1:] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) var amount int64 = 10 @@ -569,7 +572,8 @@ func TestMultipleMsgDelegate(t *testing.T) { } func TestJailValidator(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) var amt int64 = 10 @@ -607,7 +611,8 @@ func TestJailValidator(t *testing.T) { } func TestValidatorQueue(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -653,7 +658,8 @@ func TestValidatorQueue(t *testing.T) { } func TestUnbondingPeriod(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, sdk.TokensFromConsensusPower(initPower)) validatorAddr := valAddrs[0] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -691,7 +697,8 @@ func TestUnbondingPeriod(t *testing.T) { } func TestUnbondingFromUnbondingValidator(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -723,7 +730,8 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { } func TestRedelegationPeriod(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) validatorAddr, validatorAddr2 := valAddrs[0], valAddrs[1] denom := app.StakingKeeper.GetParams(ctx).BondDenom tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -740,7 +748,7 @@ func TestRedelegationPeriod(t *testing.T) { // balance should have been subtracted after creation amt2 := app.BankKeeper.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount - require.True(t, amt1.Sub(sdk.NewInt(10)).Equal(amt2), "expected coins to be subtracted") + require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") tstaking.CreateValidator(validatorAddr2, PKs[1], 10, true) bal1 := app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) @@ -773,7 +781,8 @@ func TestRedelegationPeriod(t *testing.T) { } func TestTransitiveRedelegation(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, sdk.TokensFromConsensusPower(initPower)) val1, val2, val3 := valAddrs[0], valAddrs[1], valAddrs[2] blockTime := time.Now().UTC() @@ -806,7 +815,8 @@ func TestTransitiveRedelegation(t *testing.T) { } func TestMultipleRedelegationAtSameTime(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) valAddr := valAddrs[0] valAddr2 := valAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -849,7 +859,8 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { } func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, sdk.TokensFromConsensusPower(initPower)) valAddr := valAddrs[0] valAddr2 := valAddrs[1] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -895,7 +906,8 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { } func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, sdk.TokensFromConsensusPower(initPower)) valAddr := valAddrs[0] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -934,7 +946,8 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { } func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, sdk.TokensFromConsensusPower(initPower)) valAddr := valAddrs[0] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -981,7 +994,8 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { } func TestUnbondingWhenExcessValidators(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + initPower := int64(1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, sdk.TokensFromConsensusPower(initPower)) val1 := valAddrs[0] val2 := valAddrs[1] val3 := valAddrs[2] @@ -1020,7 +1034,8 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { } func TestBondUnbondRedelegateSlashTwice(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, sdk.TokensFromConsensusPower(initPower)) valA, valB, del := valAddrs[0], valAddrs[1], delAddrs[2] consAddr0 := sdk.ConsAddress(PKs[0].Address()) tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) @@ -1124,7 +1139,8 @@ func TestInvalidMsg(t *testing.T) { } func TestInvalidCoinDenom(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + initPower := int64(1000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, sdk.TokensFromConsensusPower(initPower)) valA, valB, delAddr := valAddrs[0], valAddrs[1], delAddrs[2] tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) From 7bc08c419c3f53201c0c86a12bfba52488f1386e Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Tue, 10 Nov 2020 23:05:15 +1000 Subject: [PATCH 03/57] Disable telemetry.SetGaugeWithLabels when amount overflow int64 && Update CreateValidator, CreateValidatorMsg, Delegate helper functions to fix int64 overflow --- x/staking/handler_test.go | 68 ++++++++++++++++----------------- x/staking/keeper/msg_server.go | 36 +++++++++-------- x/staking/teststaking/helper.go | 12 +++--- 3 files changed, 60 insertions(+), 56 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index e2ba458e63..75be49f036 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -140,13 +140,13 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { assert.Equal(t, types.Description{}, validator.Description) // two validators can't have the same operator address - tstaking.CreateValidator(addr1, pk2, valTokens.Int64(), false) + tstaking.CreateValidator(addr1, pk2, valTokens, false) // two validators can't have the same pubkey - tstaking.CreateValidator(addr2, pk1, valTokens.Int64(), false) + tstaking.CreateValidator(addr2, pk1, valTokens, false) // must have different pubkey and operator - tstaking.CreateValidator(addr2, pk2, valTokens.Int64(), true) + tstaking.CreateValidator(addr2, pk2, valTokens, true) // must end-block updates, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -175,7 +175,7 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // invalid pukKey type should not be allowed - tstaking.CreateValidator(addr, invalidPk, 10, false) + tstaking.CreateValidator(addr, invalidPk, sdk.NewInt(10), false) } func TestLegacyValidatorDelegations(t *testing.T) { @@ -201,7 +201,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { require.Equal(t, bondAmount, validator.BondedTokens()) // delegate tokens to the validator - tstaking.Delegate(delAddr, valAddr, bondAmount.Int64()) + tstaking.Delegate(delAddr, valAddr, bondAmount) // verify validator bonded shares validator = tstaking.CheckValidator(valAddr, types.Bonded, false) @@ -230,7 +230,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) // verify the validator can still self-delegate - tstaking.Delegate(sdk.AccAddress(valAddr), valAddr, bondAmount.Int64()) + tstaking.Delegate(sdk.AccAddress(valAddr), valAddr, bondAmount) // verify validator bonded shares validator, found = app.StakingKeeper.GetValidator(ctx, valAddr) @@ -242,7 +242,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { app.StakingKeeper.Unjail(ctx, valConsAddr) // verify the validator can now accept delegations - tstaking.Delegate(delAddr, valAddr, bondAmount.Int64()) + tstaking.Delegate(delAddr, valAddr, bondAmount) // verify validator bonded shares validator, found = app.StakingKeeper.GetValidator(ctx, valAddr) @@ -283,12 +283,12 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.Equal(t, bondAmount, bond.Shares.RoundInt()) bondedTokens := app.StakingKeeper.TotalBondedTokens(ctx) - require.Equal(t, bondAmount.Int64(), bondedTokens.Int64()) + require.Equal(t, bondAmount, bondedTokens) for i := int64(0); i < 5; i++ { ctx = ctx.WithBlockHeight(i) tstaking.Ctx = ctx - tstaking.Delegate(delegatorAddr, validatorAddr, bondAmount.Int64()) + tstaking.Delegate(delegatorAddr, validatorAddr, bondAmount) //Check that the accounts and the bond account have the appropriate values validator, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) @@ -325,7 +325,7 @@ func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // create validator - msgCreateValidator := tstaking.CreateValidatorMsg(validatorAddr, PKs[0], initBond.Int64()) + msgCreateValidator := tstaking.CreateValidatorMsg(validatorAddr, PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) tstaking.Handle(msgCreateValidator, true) @@ -356,7 +356,7 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // create validator - msgCreateValidator := tstaking.CreateValidatorMsg(validatorAddr, PKs[0], initBond.Int64()) + msgCreateValidator := tstaking.CreateValidatorMsg(validatorAddr, PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) tstaking.Handle(msgCreateValidator, true) @@ -393,7 +393,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { // initial balance amt1 := app.BankKeeper.GetBalance(ctx, delegatorAddr, denom).Amount - tstaking.Delegate(delegatorAddr, validatorAddr, initBond.Int64()) + tstaking.Delegate(delegatorAddr, validatorAddr, initBond) // balance should have been subtracted after delegation amt2 := app.BankKeeper.GetBalance(ctx, delegatorAddr, denom).Amount @@ -438,13 +438,13 @@ func TestIncrementsMsgUnbond(t *testing.T) { gotDelegatorShares := validator.DelegatorShares.RoundInt() gotDelegatorAcc := app.BankKeeper.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount - require.Equal(t, expBond.Int64(), gotBond.Int64(), + require.Equal(t, expBond, gotBond, "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", i, expBond, gotBond, validator, bond) - require.Equal(t, expDelegatorShares.Int64(), gotDelegatorShares.Int64(), + require.Equal(t, expDelegatorShares, gotDelegatorShares, "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorShares, gotDelegatorShares, validator, bond) - require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(), + require.Equal(t, expDelegatorAcc, gotDelegatorAcc, "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", i, expDelegatorAcc, gotDelegatorAcc, validator, bond) } @@ -491,7 +491,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) { // bond them all amt := sdk.TokensFromConsensusPower(10) for i, validatorAddr := range validatorAddrs { - tstaking.CreateValidator(validatorAddr, PKs[i], amt.Int64(), true) + tstaking.CreateValidator(validatorAddr, PKs[i], amt, true) // verify that the account is bonded validators := app.StakingKeeper.GetValidators(ctx, 100) require.Equal(t, (i + 1), len(validators)) @@ -545,11 +545,11 @@ func TestMultipleMsgDelegate(t *testing.T) { var amount int64 = 10 // first make a validator - tstaking.CreateValidator(validatorAddr, PKs[0], amount, true) + tstaking.CreateValidator(validatorAddr, PKs[0], sdk.NewInt(amount), true) // delegate multiple parties for _, delegatorAddr := range delegatorAddrs { - tstaking.Delegate(delegatorAddr, validatorAddr, 10) + tstaking.Delegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) tstaking.CheckDelegator(delegatorAddr, validatorAddr, true) } @@ -579,8 +579,8 @@ func TestJailValidator(t *testing.T) { var amt int64 = 10 // create the validator and delegate - tstaking.CreateValidator(validatorAddr, PKs[0], amt, true) - tstaking.Delegate(delegatorAddr, validatorAddr, amt) + tstaking.CreateValidator(validatorAddr, PKs[0], sdk.NewInt(amt), true) + tstaking.Delegate(delegatorAddr, validatorAddr, sdk.NewInt(amt)) // unbond the validators bond portion unamt := sdk.NewInt(amt) @@ -607,7 +607,7 @@ func TestJailValidator(t *testing.T) { tstaking.Ctx = ctx // verify that the pubkey can now be reused - tstaking.CreateValidator(validatorAddr, PKs[0], amt, true) + tstaking.CreateValidator(validatorAddr, PKs[0], sdk.NewInt(amt), true) } func TestValidatorQueue(t *testing.T) { @@ -623,7 +623,7 @@ func TestValidatorQueue(t *testing.T) { // create the validator and make a bond amt := tstaking.CreateValidatorWithValPower(validatorAddr, PKs[0], 10, true) - tstaking.Delegate(delegatorAddr, validatorAddr, amt.Int64()) + tstaking.Delegate(delegatorAddr, validatorAddr, amt) staking.EndBlocker(ctx, app.StakingKeeper) // unbond the all self-delegation to put validator in unbonding state @@ -703,8 +703,8 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // create the validator and delegate - tstaking.CreateValidator(validatorAddr, PKs[0], 10, true) - tstaking.Delegate(delegatorAddr, validatorAddr, 10) + tstaking.CreateValidator(validatorAddr, PKs[0], sdk.NewInt(10), true) + tstaking.Delegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) // unbond the validators bond portion unbondAmt := sdk.NewInt(10) @@ -744,13 +744,13 @@ func TestRedelegationPeriod(t *testing.T) { amt1 := app.BankKeeper.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount // create the validators - tstaking.CreateValidator(validatorAddr, PKs[0], 10, true) + tstaking.CreateValidator(validatorAddr, PKs[0], sdk.NewInt(10), true) // balance should have been subtracted after creation amt2 := app.BankKeeper.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount - require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") + require.Equal(t, amt1.Sub(sdk.NewInt(10)), amt2, "expected coins to be subtracted") - tstaking.CreateValidator(validatorAddr2, PKs[1], 10, true) + tstaking.CreateValidator(validatorAddr2, PKs[1], sdk.NewInt(10), true) bal1 := app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) // begin redelegate @@ -790,9 +790,9 @@ func TestTransitiveRedelegation(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // create the validators - tstaking.CreateValidator(val1, PKs[0], 10, true) - tstaking.CreateValidator(val2, PKs[1], 10, true) - tstaking.CreateValidator(val3, PKs[2], 10, true) + tstaking.CreateValidator(val1, PKs[0], sdk.NewInt(10), true) + tstaking.CreateValidator(val2, PKs[1], sdk.NewInt(10), true) + tstaking.CreateValidator(val3, PKs[2], sdk.NewInt(10), true) // begin redelegate redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) @@ -828,7 +828,7 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { // create the validators valTokens := tstaking.CreateValidatorWithValPower(valAddr, PKs[0], 10, true) - tstaking.CreateValidator(valAddr2, PKs[1], valTokens.Int64(), true) + tstaking.CreateValidator(valAddr2, PKs[1], valTokens, true) // end block to bond them staking.EndBlocker(ctx, app.StakingKeeper) @@ -872,7 +872,7 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // create the validators valTokens := tstaking.CreateValidatorWithValPower(valAddr, PKs[0], 10, true) - tstaking.CreateValidator(valAddr2, PKs[1], valTokens.Int64(), true) + tstaking.CreateValidator(valAddr2, PKs[1], valTokens, true) // end block to bond them staking.EndBlocker(ctx, app.StakingKeeper) @@ -1041,10 +1041,10 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) valTokens := tstaking.CreateValidatorWithValPower(valA, PKs[0], 10, true) - tstaking.CreateValidator(valB, PKs[1], valTokens.Int64(), true) + tstaking.CreateValidator(valB, PKs[1], valTokens, true) // delegate 10 stake - tstaking.Delegate(del, valA, valTokens.Int64()) + tstaking.Delegate(del, valA, valTokens) // apply Tendermint updates updates, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 472a96c485..0d00e7fbc5 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -209,14 +209,16 @@ func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*typ return nil, err } - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "delegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", msg.Type()}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() + if msg.Amount.Amount.IsInt64() { + defer func() { + telemetry.IncrCounter(1, types.ModuleName, "delegate") + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", msg.Type()}, + float32(msg.Amount.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, + ) + }() + } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -325,14 +327,16 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) ( return nil, err } - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "undelegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", msg.Type()}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() + if msg.Amount.Amount.IsInt64() { + defer func() { + telemetry.IncrCounter(1, types.ModuleName, "undelegate") + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", msg.Type()}, + float32(msg.Amount.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, + ) + }() + } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( diff --git a/x/staking/teststaking/helper.go b/x/staking/teststaking/helper.go index c0ba45bb1a..e5e770f239 100644 --- a/x/staking/teststaking/helper.go +++ b/x/staking/teststaking/helper.go @@ -32,8 +32,8 @@ func NewHelper(t *testing.T, ctx sdk.Context, k keeper.Keeper) *Helper { } // CreateValidator calls handler to create a new staking validator -func (sh *Helper) CreateValidator(addr sdk.ValAddress, pk crypto.PubKey, stakeAmount int64, ok bool) { - coin := sdk.NewCoin(sh.Denom, sdk.NewInt(stakeAmount)) +func (sh *Helper) CreateValidator(addr sdk.ValAddress, pk crypto.PubKey, stakeAmount sdk.Int, ok bool) { + coin := sdk.NewCoin(sh.Denom, stakeAmount) sh.createValidator(addr, pk, coin, ok) } @@ -47,8 +47,8 @@ func (sh *Helper) CreateValidatorWithValPower(addr sdk.ValAddress, pk crypto.Pub } // CreateValidatorMsg returns a message used to create validator in this service. -func (sh *Helper) CreateValidatorMsg(addr sdk.ValAddress, pk crypto.PubKey, stakeAmount int64) *stakingtypes.MsgCreateValidator { - coin := sdk.NewCoin(sh.Denom, sdk.NewInt(stakeAmount)) +func (sh *Helper) CreateValidatorMsg(addr sdk.ValAddress, pk crypto.PubKey, stakeAmount sdk.Int) *stakingtypes.MsgCreateValidator { + coin := sdk.NewCoin(sh.Denom, stakeAmount) msg, err := stakingtypes.NewMsgCreateValidator(addr, pk, coin, stakingtypes.Description{}, sh.Commission, sdk.OneInt()) require.NoError(sh.t, err) return msg @@ -61,8 +61,8 @@ func (sh *Helper) createValidator(addr sdk.ValAddress, pk crypto.PubKey, coin sd } // Delegate calls handler to delegate stake for a validator -func (sh *Helper) Delegate(delegator sdk.AccAddress, val sdk.ValAddress, amount int64) { - coin := sdk.NewCoin(sh.Denom, sdk.NewInt(amount)) +func (sh *Helper) Delegate(delegator sdk.AccAddress, val sdk.ValAddress, amount sdk.Int) { + coin := sdk.NewCoin(sh.Denom, amount) msg := stakingtypes.NewMsgDelegate(delegator, val, coin) sh.Handle(msg, true) } From cc96ee3a3b11a458a664feca8130aa0f9301261b Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Wed, 11 Nov 2020 00:40:25 +1000 Subject: [PATCH 04/57] fix staking cli, grcp_query, keeper test for power reduction --- x/staking/client/cli/cli_test.go | 10 +++++----- x/staking/client/cli/tx.go | 5 +++-- x/staking/client/cli/tx_test.go | 10 +++++----- x/staking/client/rest/grpc_query_test.go | 7 ++++--- x/staking/keeper/grpc_query_test.go | 12 ++++++++---- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/x/staking/client/cli/cli_test.go b/x/staking/client/cli/cli_test.go index 2b66da867c..12b4084a4e 100644 --- a/x/staking/client/cli/cli_test.go +++ b/x/staking/client/cli/cli_test.go @@ -381,7 +381,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryDelegations() { &types.QueryDelegatorDelegationsResponse{}, &types.QueryDelegatorDelegationsResponse{ DelegationResponses: types.DelegationResponses{ - types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDec(100000000), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000))), + types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), }, Pagination: &query.PageResponse{}, }, @@ -437,7 +437,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryDelegationsTo() { &types.QueryValidatorDelegationsResponse{}, &types.QueryValidatorDelegationsResponse{ DelegationResponses: types.DelegationResponses{ - types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDec(100000000), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000))), + types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), }, Pagination: &query.PageResponse{}, }, @@ -891,8 +891,8 @@ func (s *IntegrationTestSuite) TestGetCmdQueryPool() { fmt.Sprintf("--%s=text", tmcli.OutputFlag), fmt.Sprintf("--%s=1", flags.FlagHeight), }, - `bonded_tokens: "200000000" -not_bonded_tokens: "0"`, + fmt.Sprintf(`bonded_tokens: "%s" +not_bonded_tokens: "0"`, cli.DefaultTokens.Mul(sdk.NewInt(2)).String()), }, { "with json", @@ -900,7 +900,7 @@ not_bonded_tokens: "0"`, fmt.Sprintf("--%s=json", tmcli.OutputFlag), fmt.Sprintf("--%s=1", flags.FlagHeight), }, - `{"not_bonded_tokens":"0","bonded_tokens":"200000000"}`, + fmt.Sprintf(`{"not_bonded_tokens":"0","bonded_tokens":"%s"}`, cli.DefaultTokens.Mul(sdk.NewInt(2)).String()), }, } for _, tc := range testCases { diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index ab486c5a98..b46cef2bf8 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -17,9 +17,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) +// default values var ( - defaultTokens = sdk.TokensFromConsensusPower(100) - defaultAmount = defaultTokens.String() + sdk.DefaultBondDenom + DefaultTokens = sdk.TokensFromConsensusPower(100) + defaultAmount = DefaultTokens.String() + sdk.DefaultBondDenom defaultCommissionRate = "0.1" defaultCommissionMaxRate = "0.2" defaultCommissionMaxChangeRate = "0.01" diff --git a/x/staking/client/cli/tx_test.go b/x/staking/client/cli/tx_test.go index 78a0a45bcf..9be0ebd94b 100644 --- a/x/staking/client/cli/tx_test.go +++ b/x/staking/client/cli/tx_test.go @@ -33,7 +33,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), Moniker: moniker, - Amount: "100000000stake", + Amount: defaultAmount, // for power reduction change, do not hardcode value here CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", @@ -69,7 +69,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: "100000000stake", + Amount: defaultAmount, // for power reduction change, do not hardcode value here CommissionRate: "0.54", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", @@ -87,7 +87,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: "100000000stake", + Amount: defaultAmount, // for power reduction change, do not hardcode value here CommissionRate: "0.1", CommissionMaxRate: "0.89", CommissionMaxChangeRate: "0.01", @@ -105,7 +105,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: "100000000stake", + Amount: defaultAmount, // for power reduction change, do not hardcode value here CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.55", @@ -123,7 +123,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: "100000000stake", + Amount: defaultAmount, // for power reduction change, do not hardcode value here CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", diff --git a/x/staking/client/rest/grpc_query_test.go b/x/staking/client/rest/grpc_query_test.go index 8383537055..3aa4afdcfe 100644 --- a/x/staking/client/rest/grpc_query_test.go +++ b/x/staking/client/rest/grpc_query_test.go @@ -15,6 +15,7 @@ import ( grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" "github.com/cosmos/cosmos-sdk/types/query" "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/x/staking/client/cli" stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/client/testutil" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -194,7 +195,7 @@ func (s *IntegrationTestSuite) TestQueryValidatorDelegationsGRPC() { &types.QueryValidatorDelegationsResponse{}, &types.QueryValidatorDelegationsResponse{ DelegationResponses: types.DelegationResponses{ - types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDec(100000000), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000))), + types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), }, Pagination: &query.PageResponse{Total: 1}, }, @@ -438,7 +439,7 @@ func (s *IntegrationTestSuite) TestQueryDelegatorDelegationsGRPC() { &types.QueryDelegatorDelegationsResponse{}, &types.QueryDelegatorDelegationsResponse{ DelegationResponses: types.DelegationResponses{ - types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDec(100000000), sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000))), + types.NewDelegationResp(val.Address, val.ValAddress, sdk.NewDecFromInt(cli.DefaultTokens), sdk.NewCoin(sdk.DefaultBondDenom, cli.DefaultTokens)), }, Pagination: &query.PageResponse{Total: 1}, }, @@ -775,7 +776,7 @@ func (s *IntegrationTestSuite) TestQueryPoolGRPC() { &types.QueryPoolResponse{ Pool: types.Pool{ NotBondedTokens: sdk.NewInt(10), - BondedTokens: sdk.NewInt(199999990), + BondedTokens: cli.DefaultTokens.Mul(sdk.NewInt(2)).Sub(sdk.NewInt(10)), }, }, }, diff --git a/x/staking/keeper/grpc_query_test.go b/x/staking/keeper/grpc_query_test.go index e144668940..cf3c9e3fe4 100644 --- a/x/staking/keeper/grpc_query_test.go +++ b/x/staking/keeper/grpc_query_test.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" ) func (suite *KeeperTestSuite) TestGRPCQueryValidators() { @@ -727,7 +728,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidatorUnbondingDelegations() { } func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) { - addrs := simapp.AddTestAddrsIncremental(app, ctx, 5, sdk.NewInt(300000000)) + addrs := simapp.AddTestAddrsIncremental(app, ctx, 5, sdk.TokensFromConsensusPower(300)) valAddrs := simapp.ConvertAddrsToValAddrs(addrs) pks := simapp.CreateTestPubKeys(5) @@ -751,9 +752,12 @@ func createValidators(t *testing.T, ctx sdk.Context, app *simapp.SimApp, powers app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1) app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2) - _, _ = app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[0]), types.Unbonded, val1, true) - _, _ = app.StakingKeeper.Delegate(ctx, addrs[1], sdk.TokensFromConsensusPower(powers[1]), types.Unbonded, val2, true) - _, _ = app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[2]), types.Unbonded, val2, true) + _, err := app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[0]), types.Unbonded, val1, true) + require.NoError(t, err) + _, err = app.StakingKeeper.Delegate(ctx, addrs[1], sdk.TokensFromConsensusPower(powers[1]), types.Unbonded, val2, true) + require.NoError(t, err) + _, err = app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[2]), types.Unbonded, val2, true) + require.NoError(t, err) applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1) return addrs, valAddrs, vals From 705e26e98c790a26d54b296c8fe7a8ce8b89bc7d Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Wed, 11 Nov 2020 01:28:39 +1000 Subject: [PATCH 05/57] give enough balance to operations test validator based on TokensFromConsensusPower to consider PowerReduction --- x/staking/simulation/operations_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index 6e3f687393..37ebe3ea33 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -308,7 +308,7 @@ func getTestingValidator(t *testing.T, app *simapp.SimApp, ctx sdk.Context, acco require.NoError(t, err) validator.DelegatorShares = sdk.NewDec(100) - validator.Tokens = sdk.NewInt(1000000) + validator.Tokens = sdk.TokensFromConsensusPower(100) app.StakingKeeper.SetValidator(ctx, validator) From 4582dcd08f5a9bb736da91b0b276d771ceb6fa39 Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Wed, 11 Nov 2020 01:38:54 +1000 Subject: [PATCH 06/57] remove comment --- x/staking/client/cli/tx_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/staking/client/cli/tx_test.go b/x/staking/client/cli/tx_test.go index 9be0ebd94b..7a28aac964 100644 --- a/x/staking/client/cli/tx_test.go +++ b/x/staking/client/cli/tx_test.go @@ -33,7 +33,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), Moniker: moniker, - Amount: defaultAmount, // for power reduction change, do not hardcode value here + Amount: defaultAmount, CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", @@ -69,7 +69,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: defaultAmount, // for power reduction change, do not hardcode value here + Amount: defaultAmount, CommissionRate: "0.54", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", @@ -87,7 +87,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: defaultAmount, // for power reduction change, do not hardcode value here + Amount: defaultAmount, CommissionRate: "0.1", CommissionMaxRate: "0.89", CommissionMaxChangeRate: "0.01", @@ -105,7 +105,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: defaultAmount, // for power reduction change, do not hardcode value here + Amount: defaultAmount, CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.55", @@ -123,7 +123,7 @@ func TestPrepareConfigForTxCreateValidator(t *testing.T) { ChainID: chainID, NodeID: nodeID, PubKey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, valPubKey), - Amount: defaultAmount, // for power reduction change, do not hardcode value here + Amount: defaultAmount, CommissionRate: "0.1", CommissionMaxRate: "0.2", CommissionMaxChangeRate: "0.01", From 67b3f9071c600d137f2bf914e2934b09e82114d9 Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Wed, 11 Nov 2020 02:07:40 +1000 Subject: [PATCH 07/57] fix build issues && telemetry.SetGaugeWithLabels int64 range validation --- x/bank/keeper/msg_server.go | 12 +++++++----- x/distribution/keeper/allocation_test.go | 12 ++++++------ x/distribution/keeper/delegation_test.go | 10 +++++----- x/distribution/keeper/grpc_query_test.go | 2 +- x/distribution/keeper/msg_server.go | 24 ++++++++++++++---------- x/distribution/keeper/querier_test.go | 2 +- x/slashing/abci_test.go | 5 +++-- x/slashing/handler_test.go | 6 +++--- x/slashing/keeper/keeper_test.go | 2 +- x/staking/keeper/msg_server.go | 18 ++++++++++-------- 10 files changed, 51 insertions(+), 42 deletions(-) diff --git a/x/bank/keeper/msg_server.go b/x/bank/keeper/msg_server.go index 024d857dab..b318db2cc4 100644 --- a/x/bank/keeper/msg_server.go +++ b/x/bank/keeper/msg_server.go @@ -50,11 +50,13 @@ func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSe defer func() { for _, a := range msg.Amount { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "send"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) + if a.Amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "send"}, + float32(a.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, + ) + } } }() diff --git a/x/distribution/keeper/allocation_test.go b/x/distribution/keeper/allocation_test.go index bcb9e62aa2..9d8b0012a5 100644 --- a/x/distribution/keeper/allocation_test.go +++ b/x/distribution/keeper/allocation_test.go @@ -24,7 +24,7 @@ func TestAllocateTokensToValidatorWithCommission(t *testing.T) { // create validator with 50% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(sdk.ValAddress(addrs[0]), valConsPk1, 100, true) + tstaking.CreateValidator(sdk.ValAddress(addrs[0]), valConsPk1, sdk.NewInt(100), true) val := app.StakingKeeper.Validator(ctx, valAddrs[0]) // allocate tokens @@ -53,11 +53,11 @@ func TestAllocateTokensToManyValidators(t *testing.T) { // create validator with 50% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 100, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) // create second validator with 0% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[1], valConsPk2, 100, true) + tstaking.CreateValidator(valAddrs[1], valConsPk2, sdk.NewInt(100), true) abciValA := abci.Validator{ Address: valConsPk1.Address(), @@ -123,15 +123,15 @@ func TestAllocateTokensTruncation(t *testing.T) { // create validator with 10% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 110, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(110), true) // create second validator with 10% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[1], valConsPk2, 100, true) + tstaking.CreateValidator(valAddrs[1], valConsPk2, sdk.NewInt(100), true) // create third validator with 10% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(1, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[2], valConsPk3, 100, true) + tstaking.CreateValidator(valAddrs[2], valConsPk3, sdk.NewInt(100), true) abciValA := abci.Validator{ Address: valConsPk1.Address(), diff --git a/x/distribution/keeper/delegation_test.go b/x/distribution/keeper/delegation_test.go index e55acbe091..ac8ac4a334 100644 --- a/x/distribution/keeper/delegation_test.go +++ b/x/distribution/keeper/delegation_test.go @@ -23,7 +23,7 @@ func TestCalculateRewardsBasic(t *testing.T) { // create validator with 50% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 100, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) // end block to bond validator and start new block staking.EndBlocker(ctx, app.StakingKeeper) @@ -215,7 +215,7 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { // create validator with 50% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 100, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) // end block to bond validator staking.EndBlocker(ctx, app.StakingKeeper) @@ -234,7 +234,7 @@ func TestCalculateRewardsMultiDelegator(t *testing.T) { // second delegation tstaking.Ctx = ctx - tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], 100) + tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], sdk.NewInt(100)) del2 := app.StakingKeeper.Delegation(ctx, sdk.AccAddress(valAddrs[1]), valAddrs[0]) // fetch updated validator @@ -500,7 +500,7 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { // create validator with 50% commission tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 100, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) // end block to bond validator staking.EndBlocker(ctx, app.StakingKeeper) @@ -519,7 +519,7 @@ func TestCalculateRewardsMultiDelegatorMultWithdraw(t *testing.T) { require.Equal(t, uint64(2), app.DistrKeeper.GetValidatorHistoricalReferenceCount(ctx)) // second delegation - tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], 100) + tstaking.Delegate(sdk.AccAddress(valAddrs[1]), valAddrs[0], sdk.NewInt(100)) // historical count should be 3 (second delegation init) require.Equal(t, uint64(3), app.DistrKeeper.GetValidatorHistoricalReferenceCount(ctx)) diff --git a/x/distribution/keeper/grpc_query_test.go b/x/distribution/keeper/grpc_query_test.go index a101896fea..4121440946 100644 --- a/x/distribution/keeper/grpc_query_test.go +++ b/x/distribution/keeper/grpc_query_test.go @@ -343,7 +343,7 @@ func (suite *KeeperTestSuite) TestGRPCDelegationRewards() { tstaking := teststaking.NewHelper(suite.T(), ctx, app.StakingKeeper) tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valAddrs[0], valConsPk1, 100, true) + tstaking.CreateValidator(valAddrs[0], valConsPk1, sdk.NewInt(100), true) staking.EndBlocker(ctx, app.StakingKeeper) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index 017aeeb216..a6bbe9ea01 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -66,11 +66,13 @@ func (k msgServer) WithdrawDelegatorReward(goCtx context.Context, msg *types.Msg defer func() { for _, a := range amount { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "withdraw_reward"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) + if a.Amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "withdraw_reward"}, + float32(a.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, + ) + } } }() @@ -98,11 +100,13 @@ func (k msgServer) WithdrawValidatorCommission(goCtx context.Context, msg *types defer func() { for _, a := range amount { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "withdraw_commission"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) + if a.Amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "withdraw_commission"}, + float32(a.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, + ) + } } }() diff --git a/x/distribution/keeper/querier_test.go b/x/distribution/keeper/querier_test.go index c749bf7742..9a3da854ab 100644 --- a/x/distribution/keeper/querier_test.go +++ b/x/distribution/keeper/querier_test.go @@ -172,7 +172,7 @@ func TestQueries(t *testing.T) { // test delegation rewards query tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) tstaking.Commission = stakingtypes.NewCommissionRates(sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDec(0)) - tstaking.CreateValidator(valOpAddr1, valConsPk1, 100, true) + tstaking.CreateValidator(valOpAddr1, valConsPk1, sdk.NewInt(100), true) staking.EndBlocker(ctx, app.StakingKeeper) diff --git a/x/slashing/abci_test.go b/x/slashing/abci_test.go index 2d5430700c..50140eb58e 100644 --- a/x/slashing/abci_test.go +++ b/x/slashing/abci_test.go @@ -26,7 +26,8 @@ func TestBeginBlocker(t *testing.T) { tstaking := teststaking.NewHelper(t, ctx, app.StakingKeeper) // bond the validator - amt := tstaking.CreateValidatorWithValPower(addr, pk, 100, true) + power := int64(100) + amt := tstaking.CreateValidatorWithValPower(addr, pk, power, true) staking.EndBlocker(ctx, app.StakingKeeper) require.Equal( t, app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(addr)), @@ -36,7 +37,7 @@ func TestBeginBlocker(t *testing.T) { val := abci.Validator{ Address: pk.Address(), - Power: amt.Int64(), + Power: power, } // mark the validator as having signed diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index 17cd16b896..7a83014b96 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -58,7 +58,7 @@ func TestCannotUnjailUnlessMeetMinSelfDelegation(t *testing.T) { slh := slashing.NewHandler(app.SlashingKeeper) addr, val := sdk.ValAddress(pks[0].Address()), pks[0] amt := sdk.TokensFromConsensusPower(100) - msg := tstaking.CreateValidatorMsg(addr, val, amt.Int64()) + msg := tstaking.CreateValidatorMsg(addr, val, amt) msg.MinSelfDelegation = amt tstaking.Handle(msg, true) @@ -101,7 +101,7 @@ func TestJailedValidatorDelegations(t *testing.T) { // delegate tokens to the validator delAddr := sdk.AccAddress(pks[2].Address()) - tstaking.Delegate(delAddr, valAddr, amt.Int64()) + tstaking.Delegate(delAddr, valAddr, amt) // unbond validator total self-delegations (which should jail the validator) valAcc := sdk.AccAddress(valAddr) @@ -120,7 +120,7 @@ func TestJailedValidatorDelegations(t *testing.T) { require.Nil(t, res) // self-delegate to validator - tstaking.Delegate(valAcc, valAddr, amt.Int64()) + tstaking.Delegate(valAcc, valAddr, amt) // verify the validator can now unjail itself res, err = slashing.NewHandler(app.SlashingKeeper)(ctx, types.NewMsgUnjail(valAddr)) diff --git a/x/slashing/keeper/keeper_test.go b/x/slashing/keeper/keeper_test.go index 076dd16735..e083df637a 100644 --- a/x/slashing/keeper/keeper_test.go +++ b/x/slashing/keeper/keeper_test.go @@ -40,7 +40,7 @@ func TestUnJailNotBonded(t *testing.T) { // create a 6th validator with less power than the cliff validator (won't be bonded) addr, val := valAddrs[5], pks[5] amt := sdk.TokensFromConsensusPower(50) - msg := tstaking.CreateValidatorMsg(addr, val, amt.Int64()) + msg := tstaking.CreateValidatorMsg(addr, val, amt) msg.MinSelfDelegation = amt tstaking.Handle(msg, true) diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 0d00e7fbc5..03de9b92a5 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -270,14 +270,16 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed return nil, err } - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "redelegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", msg.Type()}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() + if msg.Amount.Amount.IsInt64() { + defer func() { + telemetry.IncrCounter(1, types.ModuleName, "redelegate") + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", msg.Type()}, + float32(msg.Amount.Amount.Int64()), + []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, + ) + }() + } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( From 0eb0cbec65521c88cec62c0f81027897943128f2 Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Thu, 12 Nov 2020 01:48:42 +1000 Subject: [PATCH 08/57] set PowerReduction=10^18 for staking tests --- x/staking/common_test.go | 6 ++++++ x/staking/keeper/common_test.go | 5 +++++ x/staking/simulation/common_test.go | 11 +++++++++++ x/staking/simulation/operations_test.go | 21 +++++++++++---------- 4 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 x/staking/simulation/common_test.go diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 640fd2e2e1..0c26e6830d 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -1,6 +1,8 @@ package staking_test import ( + "math/big" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/codec" @@ -12,6 +14,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) +func init() { + sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) +} + // nolint:deadcode,unused,varcheck var ( priv1 = secp256k1.GenPrivKey() diff --git a/x/staking/keeper/common_test.go b/x/staking/keeper/common_test.go index 1b96b4ce7d..7ec4e9677c 100644 --- a/x/staking/keeper/common_test.go +++ b/x/staking/keeper/common_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "math/big" "testing" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -16,6 +17,10 @@ var ( PKs = simapp.CreateTestPubKeys(500) ) +func init() { + sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) +} + // createTestInput Returns a simapp with custom StakingKeeper // to avoid messing with the hooks. func createTestInput() (*codec.LegacyAmino, *simapp.SimApp, sdk.Context) { diff --git a/x/staking/simulation/common_test.go b/x/staking/simulation/common_test.go new file mode 100644 index 0000000000..880cb442de --- /dev/null +++ b/x/staking/simulation/common_test.go @@ -0,0 +1,11 @@ +package simulation_test + +import ( + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func init() { + sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) +} diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index 37ebe3ea33..2b16857c04 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -82,9 +82,9 @@ func TestSimulateMsgCreateValidator(t *testing.T) { types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) require.True(t, operationMsg.OK) - require.Equal(t, "0.170063593193511020", msg.Commission.MaxChangeRate.String()) - require.Equal(t, "0.660000000000000000", msg.Commission.MaxRate.String()) - require.Equal(t, "0.047464127245687382", msg.Commission.Rate.String()) + // require.Equal(t, "0.170063593193511020", msg.Commission.MaxChangeRate.String()) + // require.Equal(t, "0.660000000000000000", msg.Commission.MaxRate.String()) + // require.Equal(t, "0.047464127245687382", msg.Commission.Rate.String()) require.Equal(t, types.TypeMsgCreateValidator, msg.Type()) require.Equal(t, []byte{0xa, 0x20, 0x51, 0xde, 0xbd, 0xe8, 0xfa, 0xdf, 0x4e, 0xfc, 0x33, 0xa5, 0x16, 0x94, 0xf6, 0xee, 0xd3, 0x69, 0x7a, 0x7a, 0x1c, 0x2d, 0x50, 0xb6, 0x2, 0xf7, 0x16, 0x4e, 0x66, 0x9f, 0xff, 0x38, 0x91, 0x9b}, msg.Pubkey.Value) require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) @@ -120,10 +120,10 @@ func TestSimulateMsgEditValidator(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "0.280623462081924936", msg.CommissionRate.String()) - require.Equal(t, "jLxzIivHSl", msg.Description.Moniker) - require.Equal(t, "rBqDOTtGTO", msg.Description.Identity) - require.Equal(t, "BSpYuLyYgg", msg.Description.Website) - require.Equal(t, "wNbeHVIkPZ", msg.Description.SecurityContact) + // require.Equal(t, "jLxzIivHSl", msg.Description.Moniker) + // require.Equal(t, "rBqDOTtGTO", msg.Description.Identity) + // require.Equal(t, "BSpYuLyYgg", msg.Description.Website) + // require.Equal(t, "wNbeHVIkPZ", msg.Description.SecurityContact) require.Equal(t, types.TypeMsgEditValidator, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) require.Len(t, futureOperations, 0) @@ -158,7 +158,7 @@ func TestSimulateMsgDelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) - require.Equal(t, "4896096", msg.Amount.Amount.String()) + // require.Equal(t, "4896096", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgDelegate, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) @@ -203,7 +203,7 @@ func TestSimulateMsgUndelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.DelegatorAddress) - require.Equal(t, "560969", msg.Amount.Amount.String()) + // require.Equal(t, "560969", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgUndelegate, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) @@ -252,7 +252,7 @@ func TestSimulateMsgBeginRedelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos12gwd9jchc69wck8dhstxgwz3z8qs8yv67ps8mu", msg.DelegatorAddress) - require.Equal(t, "692322", msg.Amount.Amount.String()) + // require.Equal(t, "692322", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgBeginRedelegate, msg.Type()) require.Equal(t, "cosmosvaloper1h6a7shta7jyc72hyznkys683z98z36e0zdk8g9", msg.ValidatorDstAddress) @@ -263,6 +263,7 @@ func TestSimulateMsgBeginRedelegate(t *testing.T) { // returns context and an app with updated mint keeper func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { + // sdk.PowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) app := simapp.Setup(isCheckTx) ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{}) From 0b20e23f21a9020b900729928b2dea9a56255ca3 Mon Sep 17 00:00:00 2001 From: antstalepresh Date: Thu, 12 Nov 2020 02:05:03 +1000 Subject: [PATCH 09/57] fix random values testing --- x/staking/simulation/operations_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/x/staking/simulation/operations_test.go b/x/staking/simulation/operations_test.go index 2b16857c04..fca3b78125 100644 --- a/x/staking/simulation/operations_test.go +++ b/x/staking/simulation/operations_test.go @@ -82,9 +82,9 @@ func TestSimulateMsgCreateValidator(t *testing.T) { types.ModuleCdc.UnmarshalJSON(operationMsg.Msg, &msg) require.True(t, operationMsg.OK) - // require.Equal(t, "0.170063593193511020", msg.Commission.MaxChangeRate.String()) - // require.Equal(t, "0.660000000000000000", msg.Commission.MaxRate.String()) - // require.Equal(t, "0.047464127245687382", msg.Commission.Rate.String()) + require.Equal(t, "0.080000000000000000", msg.Commission.MaxChangeRate.String()) + require.Equal(t, "0.080000000000000000", msg.Commission.MaxRate.String()) + require.Equal(t, "0.019527679037870745", msg.Commission.Rate.String()) require.Equal(t, types.TypeMsgCreateValidator, msg.Type()) require.Equal(t, []byte{0xa, 0x20, 0x51, 0xde, 0xbd, 0xe8, 0xfa, 0xdf, 0x4e, 0xfc, 0x33, 0xa5, 0x16, 0x94, 0xf6, 0xee, 0xd3, 0x69, 0x7a, 0x7a, 0x1c, 0x2d, 0x50, 0xb6, 0x2, 0xf7, 0x16, 0x4e, 0x66, 0x9f, 0xff, 0x38, 0x91, 0x9b}, msg.Pubkey.Value) require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) @@ -120,10 +120,10 @@ func TestSimulateMsgEditValidator(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "0.280623462081924936", msg.CommissionRate.String()) - // require.Equal(t, "jLxzIivHSl", msg.Description.Moniker) - // require.Equal(t, "rBqDOTtGTO", msg.Description.Identity) - // require.Equal(t, "BSpYuLyYgg", msg.Description.Website) - // require.Equal(t, "wNbeHVIkPZ", msg.Description.SecurityContact) + require.Equal(t, "rBqDOTtGTO", msg.Description.Moniker) + require.Equal(t, "BSpYuLyYgg", msg.Description.Identity) + require.Equal(t, "wNbeHVIkPZ", msg.Description.Website) + require.Equal(t, "MOXcnQfyze", msg.Description.SecurityContact) require.Equal(t, types.TypeMsgEditValidator, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) require.Len(t, futureOperations, 0) @@ -158,7 +158,7 @@ func TestSimulateMsgDelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r", msg.DelegatorAddress) - // require.Equal(t, "4896096", msg.Amount.Amount.String()) + require.Equal(t, "98100858108421259236", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgDelegate, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) @@ -203,7 +203,7 @@ func TestSimulateMsgUndelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos1p8wcgrjr4pjju90xg6u9cgq55dxwq8j7u4x9a0", msg.DelegatorAddress) - // require.Equal(t, "560969", msg.Amount.Amount.String()) + require.Equal(t, "280623462081924937", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgUndelegate, msg.Type()) require.Equal(t, "cosmosvaloper1tnh2q55v8wyygtt9srz5safamzdengsn9dsd7z", msg.ValidatorAddress) @@ -252,7 +252,7 @@ func TestSimulateMsgBeginRedelegate(t *testing.T) { require.True(t, operationMsg.OK) require.Equal(t, "cosmos12gwd9jchc69wck8dhstxgwz3z8qs8yv67ps8mu", msg.DelegatorAddress) - // require.Equal(t, "692322", msg.Amount.Amount.String()) + require.Equal(t, "489348507626016866", msg.Amount.Amount.String()) require.Equal(t, "stake", msg.Amount.Denom) require.Equal(t, types.TypeMsgBeginRedelegate, msg.Type()) require.Equal(t, "cosmosvaloper1h6a7shta7jyc72hyznkys683z98z36e0zdk8g9", msg.ValidatorDstAddress) From 8bc429d288fc5c0b701ac159275a1579b3b5aae6 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Fri, 13 Nov 2020 11:48:06 -0400 Subject: [PATCH 10/57] fix int64 --- x/staking/handler_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index d67fffbe32..0f5a641057 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -185,7 +185,7 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { } func TestBothPubKeyTypesMsgCreateValidator(t *testing.T) { - app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, sdk.NewInt(1000)) ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ Validator: &tmproto.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519, tmtypes.ABCIPubKeyTypeSecp256k1}}, }) @@ -210,7 +210,7 @@ func TestBothPubKeyTypesMsgCreateValidator(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(*testing.T) { - tstaking.CreateValidator(tc.addr, tc.pk, 10, true) + tstaking.CreateValidator(tc.addr, tc.pk, sdk.NewInt(10), true) }) } } From 6b62d266bb01a1561fd13721c868fe1d130ad179 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Mon, 16 Nov 2020 10:14:21 +0100 Subject: [PATCH 11/57] use verifycommitlight (#7936) --- .../07-tendermint/types/misbehaviour.go | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go index 85fb615e5e..d4de93504e 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go @@ -111,27 +111,19 @@ func (misbehaviour Misbehaviour) ValidateBasic() error { if bytes.Equal(blockID1.Hash, blockID2.Hash) { return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "headers block hashes are equal") } - if err := ValidCommit(misbehaviour.Header1.Header.ChainID, misbehaviour.Header1.Commit, misbehaviour.Header1.ValidatorSet); err != nil { + if err := validCommit(misbehaviour.Header1.Header.ChainID, *blockID1, + misbehaviour.Header1.Commit, misbehaviour.Header1.ValidatorSet); err != nil { return err } - if err := ValidCommit(misbehaviour.Header2.Header.ChainID, misbehaviour.Header2.Commit, misbehaviour.Header2.ValidatorSet); err != nil { + if err := validCommit(misbehaviour.Header2.Header.ChainID, *blockID2, + misbehaviour.Header2.Commit, misbehaviour.Header2.ValidatorSet); err != nil { return err } return nil } -// ValidCommit checks if the given commit is a valid commit from the passed-in validatorset -// -// CommitToVoteSet will panic if the commit cannot be converted to a valid voteset given the validatorset -// This implies that someone tried to submit misbehaviour that wasn't actually committed by the validatorset -// thus we should return an error here and reject the misbehaviour rather than panicing. -func ValidCommit(chainID string, commit *tmproto.Commit, valSet *tmproto.ValidatorSet) (err error) { - defer func() { - if r := recover(); r != nil { - err = sdkerrors.Wrapf(clienttypes.ErrInvalidMisbehaviour, "invalid commit: %v", r) - } - }() - +// validCommit checks if the given commit is a valid commit from the passed-in validatorset +func validCommit(chainID string, blockID tmtypes.BlockID, commit *tmproto.Commit, valSet *tmproto.ValidatorSet) (err error) { tmCommit, err := tmtypes.CommitFromProto(commit) if err != nil { return sdkerrors.Wrap(err, "commit is not tendermint commit type") @@ -141,13 +133,7 @@ func ValidCommit(chainID string, commit *tmproto.Commit, valSet *tmproto.Validat return sdkerrors.Wrap(err, "validator set is not tendermint validator set type") } - // Convert commits to vote-sets given the validator set so we can check if they both have 2/3 power - voteSet := tmtypes.CommitToVoteSet(chainID, tmCommit, tmValset) - - blockID, ok := voteSet.TwoThirdsMajority() - - // Check that ValidatorSet did indeed commit to blockID hash in Commit - if !ok || !bytes.Equal(blockID.Hash, tmCommit.BlockID.Hash) { + if err := tmValset.VerifyCommitLight(chainID, blockID, tmCommit.Height, tmCommit); err != nil { return sdkerrors.Wrap(clienttypes.ErrInvalidMisbehaviour, "validator set did not commit to header") } From cd29fd642a3c948c68355e5f14e55405242aed3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 16 Nov 2020 10:30:57 +0100 Subject: [PATCH 12/57] Fix connection path validation and remove unused PathValidator function (#7930) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/ibc/core/03-connection/types/connection_test.go | 13 +++++++------ x/ibc/core/03-connection/types/genesis.go | 6 +++--- x/ibc/core/03-connection/types/genesis_test.go | 9 ++++----- x/ibc/core/24-host/validate.go | 11 ----------- x/ibc/core/24-host/validate_test.go | 7 ++++++- x/ibc/core/genesis_test.go | 13 ++++++------- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/x/ibc/core/03-connection/types/connection_test.go b/x/ibc/core/03-connection/types/connection_test.go index ff2aa08d4a..93891cbea1 100644 --- a/x/ibc/core/03-connection/types/connection_test.go +++ b/x/ibc/core/03-connection/types/connection_test.go @@ -12,12 +12,13 @@ import ( ) var ( - chainID = "gaiamainnet" - connectionID = "connectionidone" - clientID = "clientidone" - connectionID2 = "connectionidtwo" - clientID2 = "clientidtwo" - clientHeight = clienttypes.NewHeight(0, 6) + chainID = "gaiamainnet" + connectionID = "connectionidone" + clientID = "clientidone" + connectionID2 = "connectionidtwo" + clientID2 = "clientidtwo" + invalidConnectionID = "(invalidConnectionID)" + clientHeight = clienttypes.NewHeight(0, 6) ) func TestConnectionValidateBasic(t *testing.T) { diff --git a/x/ibc/core/03-connection/types/genesis.go b/x/ibc/core/03-connection/types/genesis.go index 9b155a368b..58b21678c2 100644 --- a/x/ibc/core/03-connection/types/genesis.go +++ b/x/ibc/core/03-connection/types/genesis.go @@ -45,9 +45,9 @@ func (gs GenesisState) Validate() error { if err := host.ClientIdentifierValidator(conPaths.ClientId); err != nil { return fmt.Errorf("invalid client connection path %d: %w", i, err) } - for _, path := range conPaths.Paths { - if err := host.PathValidator(path); err != nil { - return fmt.Errorf("invalid client connection path %d: %w", i, err) + for _, connectionID := range conPaths.Paths { + if err := host.ConnectionIdentifierValidator(connectionID); err != nil { + return fmt.Errorf("invalid client connection ID (%s) in connection paths %d: %w", connectionID, i, err) } } } diff --git a/x/ibc/core/03-connection/types/genesis_test.go b/x/ibc/core/03-connection/types/genesis_test.go index 8080f49d5c..6290a98a9f 100644 --- a/x/ibc/core/03-connection/types/genesis_test.go +++ b/x/ibc/core/03-connection/types/genesis_test.go @@ -7,7 +7,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" - host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ) @@ -30,7 +29,7 @@ func TestValidateGenesis(t *testing.T) { types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), }, []types.ConnectionPaths{ - {clientID, []string{host.ConnectionPath(connectionID)}}, + {clientID, []string{connectionID}}, }, ), expPass: true, @@ -42,7 +41,7 @@ func TestValidateGenesis(t *testing.T) { types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, "(CLIENTIDONE)", types.Counterparty{clientID, connectionID, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), }, []types.ConnectionPaths{ - {clientID, []string{host.ConnectionPath(connectionID)}}, + {clientID, []string{connectionID}}, }, ), expPass: false, @@ -54,7 +53,7 @@ func TestValidateGenesis(t *testing.T) { types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), }, []types.ConnectionPaths{ - {"(CLIENTIDONE)", []string{host.ConnectionPath(connectionID)}}, + {"(CLIENTIDONE)", []string{connectionID}}, }, ), expPass: false, @@ -66,7 +65,7 @@ func TestValidateGenesis(t *testing.T) { types.NewIdentifiedConnection(connectionID, types.NewConnectionEnd(types.INIT, clientID, types.Counterparty{clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))}, []*types.Version{ibctesting.ConnectionVersion})), }, []types.ConnectionPaths{ - {clientID, []string{connectionID}}, + {clientID, []string{invalidConnectionID}}, }, ), expPass: false, diff --git a/x/ibc/core/24-host/validate.go b/x/ibc/core/24-host/validate.go index bbfafbee75..d589223f58 100644 --- a/x/ibc/core/24-host/validate.go +++ b/x/ibc/core/24-host/validate.go @@ -112,14 +112,3 @@ func NewPathValidator(idValidator ValidateFn) ValidateFn { return nil } } - -// PathValidator takes in path string and validates with default identifier rules: -// path consists of `/`-separated valid identifiers, -// each identifier is between 1-64 characters and contains only alphanumeric and some allowed -// special characters (see IsValidID). -func PathValidator(path string) error { - f := NewPathValidator(func(path string) error { - return nil - }) - return f(path) -} diff --git a/x/ibc/core/24-host/validate_test.go b/x/ibc/core/24-host/validate_test.go index 41dd5167d9..40987bd157 100644 --- a/x/ibc/core/24-host/validate_test.go +++ b/x/ibc/core/24-host/validate_test.go @@ -73,7 +73,12 @@ func TestPathValidator(t *testing.T) { } for _, tc := range testCases { - err := PathValidator(tc.id) + f := NewPathValidator(func(path string) error { + return nil + }) + + err := f(tc.id) + if tc.expPass { seps := strings.Count(tc.id, "/") require.Equal(t, 1, seps) diff --git a/x/ibc/core/genesis_test.go b/x/ibc/core/genesis_test.go index a14669faaa..d435cf8566 100644 --- a/x/ibc/core/genesis_test.go +++ b/x/ibc/core/genesis_test.go @@ -14,7 +14,6 @@ import ( connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" - host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" "github.com/cosmos/cosmos-sdk/x/ibc/core/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" @@ -77,7 +76,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), ), clienttypes.NewIdentifiedClientState( exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), @@ -104,7 +103,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion})), }, []connectiontypes.ConnectionPaths{ - connectiontypes.NewConnectionPaths(clientID, []string{host.ConnectionPath(connectionID)}), + connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, ), ChannelGenesis: channeltypes.NewGenesisState( @@ -144,7 +143,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), ), clienttypes.NewIdentifiedClientState( exported.Localhost, localhosttypes.NewClientState("(chaindID)", clienttypes.ZeroHeight()), @@ -167,7 +166,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, "(CLIENTIDONE)", connectiontypes.NewCounterparty(clientID, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{connectiontypes.NewVersion("1.1", nil)})), }, []connectiontypes.ConnectionPaths{ - connectiontypes.NewConnectionPaths(clientID, []string{host.ConnectionPath(connectionID)}), + connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, ), }, @@ -216,7 +215,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { ClientGenesis: clienttypes.NewGenesisState( []clienttypes.IdentifiedClientState{ clienttypes.NewIdentifiedClientState( - clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + clientID, ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), ), clienttypes.NewIdentifiedClientState( exported.Localhost, localhosttypes.NewClientState("chaindID", clientHeight), @@ -243,7 +242,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { connectiontypes.NewIdentifiedConnection(connectionID, connectiontypes.NewConnectionEnd(connectiontypes.INIT, clientID, connectiontypes.NewCounterparty(clientID2, connectionID2, commitmenttypes.NewMerklePrefix([]byte("prefix"))), []*connectiontypes.Version{ibctesting.ConnectionVersion})), }, []connectiontypes.ConnectionPaths{ - connectiontypes.NewConnectionPaths(clientID, []string{host.ConnectionPath(connectionID)}), + connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, ), ChannelGenesis: channeltypes.NewGenesisState( From b5e873cd9197ee3e1a13f921d8db9d8f138c1875 Mon Sep 17 00:00:00 2001 From: Paul Kim Date: Mon, 16 Nov 2020 19:00:34 +0900 Subject: [PATCH 13/57] version --long displays replaced build dependencies (#7941) * version --long displays replaced modules * Update CHANGELOG * Update CHANGELOG * Update version/version.go * Update CHANGELOG.md * Update CHANGELOG.md Co-authored-by: Alessio Treglia Co-authored-by: Alessio Treglia --- CHANGELOG.md | 2 +- version/version.go | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e63adfaca..46d8a76ef3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ - (SDK) [\#7925](https://github.com/cosmos/cosmos-sdk/pull/7925) Updated dependencies to use gRPC v1.33.2 * Updated gRPC dependency to v1.33.2 * Updated iavl dependency to v0.15-rc2 - +* (version) [\#7848](https://github.com/cosmos/cosmos-sdk/pull/7848) [\#7941](https://github.com/cosmos/cosmos-sdk/pull/7941) `version --long` output now shows the list of build dependencies and replaced build dependencies. ## [v0.40.0-rc3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc3) - 2020-11-06 diff --git a/version/version.go b/version/version.go index 25995932fc..a179b37fe3 100644 --- a/version/version.go +++ b/version/version.go @@ -85,6 +85,13 @@ type buildDep struct { *debug.Module } -func (d buildDep) String() string { return fmt.Sprintf("%s@%s", d.Path, d.Version) } +func (d buildDep) String() string { + if d.Replace != nil { + return fmt.Sprintf("%s@%s => %s@%s", d.Path, d.Version, d.Replace.Path, d.Replace.Version) + } + + return fmt.Sprintf("%s@%s", d.Path, d.Version) +} + func (d buildDep) MarshalJSON() ([]byte, error) { return json.Marshal(d.String()) } func (d buildDep) MarshalYAML() (interface{}, error) { return d.String(), nil } From 0d0c9696e8faa1d34052c9ed583494ad7f36ad1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Nov 2020 10:36:09 +0000 Subject: [PATCH 14/57] build(deps): bump github.com/prometheus/common from 0.14.0 to 0.15.0 (#7942) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.14.0 to 0.15.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.14.0...v0.15.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 7049f591ab..ad65e29a68 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( github.com/pelletier/go-toml v1.8.0 // indirect github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.8.0 - github.com/prometheus/common v0.14.0 + github.com/prometheus/common v0.15.0 github.com/rakyll/statik v0.1.7 github.com/regen-network/cosmos-proto v0.3.0 github.com/spf13/afero v1.2.2 // indirect diff --git a/go.sum b/go.sum index db70ba9caf..3fb9fc93bf 100644 --- a/go.sum +++ b/go.sum @@ -501,6 +501,8 @@ github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lN github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= From 54201d11e6d2c14f47542e3eac600c10c9db4723 Mon Sep 17 00:00:00 2001 From: yihuang Date: Mon, 16 Nov 2020 19:34:54 +0800 Subject: [PATCH 15/57] cli: convert coins to smallest unit registered (#7777) * cli: convert coins to smallest unit registered fixes: #7623 - test order of decimal operations - support both int and decimal coins, truncate when normalizing to base unit * Update types/coin_test.go * Update types/coin_test.go Co-authored-by: Alessio Treglia Co-authored-by: Amaury Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- client/tx/factory.go | 2 +- simapp/simd/cmd/genaccounts.go | 4 +- types/coin.go | 39 +++------- types/coin_test.go | 12 +-- types/dec_coin_test.go | 7 +- types/denom.go | 85 +++++++++++++++++++++- types/denom_internal_test.go | 101 ++++++++++++++++++++++++++ types/rest/rest_test.go | 2 +- types/simulation/rand_util_test.go | 2 +- x/auth/vesting/client/cli/tx.go | 2 +- x/bank/client/cli/tx.go | 2 +- x/bank/client/testutil/cli_helpers.go | 2 +- x/distribution/client/cli/tx.go | 6 +- x/genutil/client/cli/gentx.go | 2 +- x/gov/client/cli/tx.go | 4 +- x/params/client/cli/tx.go | 2 +- x/upgrade/client/cli/tx.go | 4 +- 17 files changed, 225 insertions(+), 53 deletions(-) diff --git a/client/tx/factory.go b/client/tx/factory.go index 5077d36e74..19c7c61dea 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -120,7 +120,7 @@ func (f Factory) WithGas(gas uint64) Factory { // WithFees returns a copy of the Factory with an updated fee. func (f Factory) WithFees(fees string) Factory { - parsedFees, err := sdk.ParseCoins(fees) + parsedFees, err := sdk.ParseCoinsNormalized(fees) if err != nil { panic(err) } diff --git a/simapp/simd/cmd/genaccounts.go b/simapp/simd/cmd/genaccounts.go index 167da30578..dc6925120e 100644 --- a/simapp/simd/cmd/genaccounts.go +++ b/simapp/simd/cmd/genaccounts.go @@ -67,7 +67,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa addr = info.GetAddress() } - coins, err := sdk.ParseCoins(args[1]) + coins, err := sdk.ParseCoinsNormalized(args[1]) if err != nil { return fmt.Errorf("failed to parse coins: %w", err) } @@ -76,7 +76,7 @@ contain valid denominations. Accounts may optionally be supplied with vesting pa vestingEnd, _ := cmd.Flags().GetInt64(flagVestingEnd) vestingAmtStr, _ := cmd.Flags().GetString(flagVestingAmt) - vestingAmt, err := sdk.ParseCoins(vestingAmtStr) + vestingAmt, err := sdk.ParseCoinsNormalized(vestingAmtStr) if err != nil { return fmt.Errorf("failed to parse vesting amount: %w", err) } diff --git a/types/coin.go b/types/coin.go index 8ac9a8843d..5e2c22bdf8 100644 --- a/types/coin.go +++ b/types/coin.go @@ -600,7 +600,7 @@ var ( // a letter, a number or a separator ('/'). reDnmString = `[a-zA-Z][a-zA-Z0-9/]{2,127}` reAmt = `[[:digit:]]+` - reDecAmt = `[[:digit:]]*\.[[:digit:]]+` + reDecAmt = `[[:digit:]]+(?:\.[[:digit:]]+)?|\.[[:digit:]]+` reSpc = `[[:space:]]*` reDnm = returnReDnm reCoin = returnReCoin @@ -664,33 +664,18 @@ func ParseCoin(coinStr string) (coin Coin, err error) { return NewCoin(denomStr, amount), nil } -// ParseCoins will parse out a list of coins separated by commas. If the parsing is successuful, -// the provided coins will be sanitized by removing zero coins and sorting the coin set. Lastly -// a validation of the coin set is executed. If the check passes, ParseCoins will return the sanitized coins. +// ParseCoinsNormalized will parse out a list of coins separated by commas, and normalize them by converting to smallest +// unit. If the parsing is successuful, the provided coins will be sanitized by removing zero coins and sorting the coin +// set. Lastly a validation of the coin set is executed. If the check passes, ParseCoinsNormalized will return the +// sanitized coins. // Otherwise it will return an error. -// If an empty string is provided to ParseCoins, it returns nil Coins. +// If an empty string is provided to ParseCoinsNormalized, it returns nil Coins. +// ParseCoinsNormalized supports decimal coins as inputs, and truncate them to int after converted to smallest unit. // Expected format: "{amount0}{denomination},...,{amountN}{denominationN}" -func ParseCoins(coinsStr string) (Coins, error) { - coinsStr = strings.TrimSpace(coinsStr) - if len(coinsStr) == 0 { - return nil, nil +func ParseCoinsNormalized(coinStr string) (Coins, error) { + coins, err := ParseDecCoins(coinStr) + if err != nil { + return Coins{}, err } - - coinStrs := strings.Split(coinsStr, ",") - coins := make(Coins, len(coinStrs)) - for i, coinStr := range coinStrs { - coin, err := ParseCoin(coinStr) - if err != nil { - return nil, err - } - - coins[i] = coin - } - - newCoins := sanitizeCoins(coins) - if err := newCoins.Validate(); err != nil { - return nil, err - } - - return newCoins, nil + return NormalizeCoins(coins), nil } diff --git a/types/coin_test.go b/types/coin_test.go index 9d4130576b..0e4bbf739f 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -660,18 +660,18 @@ func (s *coinTestSuite) TestParseCoins() { {"98 bar , 1 foo ", true, sdk.Coins{{"bar", sdk.NewInt(98)}, {"foo", one}}}, {" 55\t \t bling\n", true, sdk.Coins{{"bling", sdk.NewInt(55)}}}, {"2foo, 97 bar", true, sdk.Coins{{"bar", sdk.NewInt(97)}, {"foo", sdk.NewInt(2)}}}, - {"5 mycoin,", false, nil}, // no empty coins in a list - {"2 3foo, 97 bar", false, nil}, // 3foo is invalid coin name - {"11me coin, 12you coin", false, nil}, // no spaces in coin names - {"1.2btc", false, nil}, // amount must be integer - {"5foo:bar", false, nil}, // invalid separator + {"5 mycoin,", false, nil}, // no empty coins in a list + {"2 3foo, 97 bar", false, nil}, // 3foo is invalid coin name + {"11me coin, 12you coin", false, nil}, // no spaces in coin names + {"1.2btc", true, sdk.Coins{{"btc", sdk.NewInt(1)}}}, // amount can be decimal, will get truncated + {"5foo:bar", false, nil}, // invalid separator {"10atom10", true, sdk.Coins{{"atom10", sdk.NewInt(10)}}}, {"200transfer/channelToA/uatom", true, sdk.Coins{{"transfer/channelToA/uatom", sdk.NewInt(200)}}}, {"50ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", true, sdk.Coins{{"ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2", sdk.NewInt(50)}}}, } for tcIndex, tc := range cases { - res, err := sdk.ParseCoins(tc.input) + res, err := sdk.ParseCoinsNormalized(tc.input) if !tc.valid { s.Require().Error(err, "%s: %#v. tc #%d", tc.input, res, tcIndex) } else if s.Assert().Nil(err, "%s: %+v", tc.input, err) { diff --git a/types/dec_coin_test.go b/types/dec_coin_test.go index e0f4a66b23..938f7dddff 100644 --- a/types/dec_coin_test.go +++ b/types/dec_coin_test.go @@ -352,8 +352,11 @@ func (s *decCoinTestSuite) TestParseDecCoins() { expectedErr bool }{ {"", nil, false}, - {"4stake", nil, true}, - {"5.5atom,4stake", nil, true}, + {"4stake", sdk.DecCoins{sdk.NewDecCoinFromDec("stake", sdk.NewDecFromInt(sdk.NewInt(4)))}, false}, + {"5.5atom,4stake", sdk.DecCoins{ + sdk.NewDecCoinFromDec("atom", sdk.NewDecWithPrec(5500000000000000000, sdk.Precision)), + sdk.NewDecCoinFromDec("stake", sdk.NewDec(4)), + }, false}, {"0.0stake", sdk.DecCoins{}, false}, // remove zero coins {"10.0btc,1.0atom,20.0btc", nil, true}, { diff --git a/types/denom.go b/types/denom.go index f79bef8b94..160e2806e1 100644 --- a/types/denom.go +++ b/types/denom.go @@ -8,6 +8,9 @@ import ( // multipliers (e.g. 1atom = 10^-6uatom). var denomUnits = map[string]Dec{} +// baseDenom is the denom of smallest unit registered +var baseDenom string = "" + // RegisterDenom registers a denomination with a corresponding unit. If the // denomination is already registered, an error will be returned. func RegisterDenom(denom string, unit Dec) error { @@ -20,6 +23,10 @@ func RegisterDenom(denom string, unit Dec) error { } denomUnits[denom] = unit + + if baseDenom == "" || unit.LT(denomUnits[baseDenom]) { + baseDenom = denom + } return nil } @@ -38,6 +45,14 @@ func GetDenomUnit(denom string) (Dec, bool) { return unit, true } +// GetBaseDenom returns the denom of smallest unit registered +func GetBaseDenom() (string, error) { + if baseDenom == "" { + return "", fmt.Errorf("no denom is registered") + } + return baseDenom, nil +} + // ConvertCoin attempts to convert a coin to a given denomination. If the given // denomination is invalid or if neither denomination is registered, an error // is returned. @@ -60,5 +75,73 @@ func ConvertCoin(coin Coin, denom string) (Coin, error) { return NewCoin(denom, coin.Amount), nil } - return NewCoin(denom, coin.Amount.ToDec().Mul(srcUnit.Quo(dstUnit)).TruncateInt()), nil + return NewCoin(denom, coin.Amount.ToDec().Mul(srcUnit).Quo(dstUnit).TruncateInt()), nil +} + +// ConvertDecCoin attempts to convert a decimal coin to a given denomination. If the given +// denomination is invalid or if neither denomination is registered, an error +// is returned. +func ConvertDecCoin(coin DecCoin, denom string) (DecCoin, error) { + if err := ValidateDenom(denom); err != nil { + return DecCoin{}, err + } + + srcUnit, ok := GetDenomUnit(coin.Denom) + if !ok { + return DecCoin{}, fmt.Errorf("source denom not registered: %s", coin.Denom) + } + + dstUnit, ok := GetDenomUnit(denom) + if !ok { + return DecCoin{}, fmt.Errorf("destination denom not registered: %s", denom) + } + + if srcUnit.Equal(dstUnit) { + return NewDecCoinFromDec(denom, coin.Amount), nil + } + + return NewDecCoinFromDec(denom, coin.Amount.Mul(srcUnit).Quo(dstUnit)), nil +} + +// NormalizeCoin try to convert a coin to the smallest unit registered, +// returns original one if failed. +func NormalizeCoin(coin Coin) Coin { + base, err := GetBaseDenom() + if err != nil { + return coin + } + newCoin, err := ConvertCoin(coin, base) + if err != nil { + return coin + } + return newCoin +} + +// NormalizeDecCoin try to convert a decimal coin to the smallest unit registered, +// returns original one if failed. +func NormalizeDecCoin(coin DecCoin) DecCoin { + base, err := GetBaseDenom() + if err != nil { + return coin + } + newCoin, err := ConvertDecCoin(coin, base) + if err != nil { + return coin + } + return newCoin +} + +// NormalizeCoins normalize and truncate a list of decimal coins +func NormalizeCoins(coins []DecCoin) Coins { + if coins == nil { + return nil + } + result := make([]Coin, 0, len(coins)) + + for _, coin := range coins { + newCoin, _ := NormalizeDecCoin(coin).TruncateDecimal() + result = append(result, newCoin) + } + + return result } diff --git a/types/denom_internal_test.go b/types/denom_internal_test.go index e540b28d57..8c957353eb 100644 --- a/types/denom_internal_test.go +++ b/types/denom_internal_test.go @@ -36,6 +36,7 @@ func (s *internalDenomTestSuite) TestRegisterDenom() { s.Require().Equal(ZeroDec(), res) // reset registration + baseDenom = "" denomUnits = map[string]Dec{} } @@ -52,6 +53,21 @@ func (s *internalDenomTestSuite) TestConvertCoins() { natomUnit := NewDecWithPrec(1, 9) // 10^-9 (nano) s.Require().NoError(RegisterDenom(natom, natomUnit)) + res, err := GetBaseDenom() + s.Require().NoError(err) + s.Require().Equal(res, natom) + s.Require().Equal(NormalizeCoin(NewCoin(uatom, NewInt(1))), NewCoin(natom, NewInt(1000))) + s.Require().Equal(NormalizeCoin(NewCoin(matom, NewInt(1))), NewCoin(natom, NewInt(1000000))) + s.Require().Equal(NormalizeCoin(NewCoin(atom, NewInt(1))), NewCoin(natom, NewInt(1000000000))) + + coins, err := ParseCoinsNormalized("1atom,1matom,1uatom") + s.Require().NoError(err) + s.Require().Equal(coins, Coins{ + Coin{natom, NewInt(1000000000)}, + Coin{natom, NewInt(1000000)}, + Coin{natom, NewInt(1000)}, + }) + testCases := []struct { input Coin denom string @@ -87,5 +103,90 @@ func (s *internalDenomTestSuite) TestConvertCoins() { } // reset registration + baseDenom = "" + denomUnits = map[string]Dec{} +} + +func (s *internalDenomTestSuite) TestConvertDecCoins() { + atomUnit := OneDec() // 1 (base denom unit) + s.Require().NoError(RegisterDenom(atom, atomUnit)) + + matomUnit := NewDecWithPrec(1, 3) // 10^-3 (milli) + s.Require().NoError(RegisterDenom(matom, matomUnit)) + + uatomUnit := NewDecWithPrec(1, 6) // 10^-6 (micro) + s.Require().NoError(RegisterDenom(uatom, uatomUnit)) + + natomUnit := NewDecWithPrec(1, 9) // 10^-9 (nano) + s.Require().NoError(RegisterDenom(natom, natomUnit)) + + res, err := GetBaseDenom() + s.Require().NoError(err) + s.Require().Equal(res, natom) + s.Require().Equal(NormalizeDecCoin(NewDecCoin(uatom, NewInt(1))), NewDecCoin(natom, NewInt(1000))) + s.Require().Equal(NormalizeDecCoin(NewDecCoin(matom, NewInt(1))), NewDecCoin(natom, NewInt(1000000))) + s.Require().Equal(NormalizeDecCoin(NewDecCoin(atom, NewInt(1))), NewDecCoin(natom, NewInt(1000000000))) + + coins, err := ParseCoinsNormalized("0.1atom,0.1matom,0.1uatom") + s.Require().NoError(err) + s.Require().Equal(coins, Coins{ + Coin{natom, NewInt(100000000)}, + Coin{natom, NewInt(100000)}, + Coin{natom, NewInt(100)}, + }) + + testCases := []struct { + input DecCoin + denom string + result DecCoin + expErr bool + }{ + {NewDecCoin("foo", ZeroInt()), atom, DecCoin{}, true}, + {NewDecCoin(atom, ZeroInt()), "foo", DecCoin{}, true}, + {NewDecCoin(atom, ZeroInt()), "FOO", DecCoin{}, true}, + + // 0.5atom + {NewDecCoinFromDec(atom, NewDecWithPrec(5, 1)), matom, NewDecCoin(matom, NewInt(500)), false}, // atom => matom + {NewDecCoinFromDec(atom, NewDecWithPrec(5, 1)), uatom, NewDecCoin(uatom, NewInt(500000)), false}, // atom => uatom + {NewDecCoinFromDec(atom, NewDecWithPrec(5, 1)), natom, NewDecCoin(natom, NewInt(500000000)), false}, // atom => natom + + {NewDecCoin(uatom, NewInt(5000000)), matom, NewDecCoin(matom, NewInt(5000)), false}, // uatom => matom + {NewDecCoin(uatom, NewInt(5000000)), natom, NewDecCoin(natom, NewInt(5000000000)), false}, // uatom => natom + {NewDecCoin(uatom, NewInt(5000000)), atom, NewDecCoin(atom, NewInt(5)), false}, // uatom => atom + + {NewDecCoin(matom, NewInt(5000)), natom, NewDecCoin(natom, NewInt(5000000000)), false}, // matom => natom + {NewDecCoin(matom, NewInt(5000)), uatom, NewDecCoin(uatom, NewInt(5000000)), false}, // matom => uatom + } + + for i, tc := range testCases { + res, err := ConvertDecCoin(tc.input, tc.denom) + s.Require().Equal( + tc.expErr, err != nil, + "unexpected error; tc: #%d, input: %s, denom: %s", i+1, tc.input, tc.denom, + ) + s.Require().Equal( + tc.result, res, + "invalid result; tc: #%d, input: %s, denom: %s", i+1, tc.input, tc.denom, + ) + } + + // reset registration + baseDenom = "" + denomUnits = map[string]Dec{} +} + +func (s *internalDenomTestSuite) TestDecOperationOrder() { + dec, err := NewDecFromStr("11") + s.Require().NoError(err) + s.Require().NoError(RegisterDenom("unit1", dec)) + dec, err = NewDecFromStr("100000011") + s.Require().NoError(RegisterDenom("unit2", dec)) + + coin, err := ConvertCoin(NewCoin("unit1", NewInt(100000011)), "unit2") + s.Require().NoError(err) + s.Require().Equal(coin, NewCoin("unit2", NewInt(11))) + + // reset registration + baseDenom = "" denomUnits = map[string]Dec{} } diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 0a3e16b29d..8f873645d6 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -42,7 +42,7 @@ func TestBaseReq_Sanitize(t *testing.T) { func TestBaseReq_ValidateBasic(t *testing.T) { fromAddr := "cosmos1cq0sxam6x4l0sv9yz3a2vlqhdhvt2k6jtgcse0" - tenstakes, err := types.ParseCoins("10stake") + tenstakes, err := types.ParseCoinsNormalized("10stake") require.NoError(t, err) onestake, err := types.ParseDecCoins("1.0stake") require.NoError(t, err) diff --git a/types/simulation/rand_util_test.go b/types/simulation/rand_util_test.go index d68db7c6ab..c487625ed0 100644 --- a/types/simulation/rand_util_test.go +++ b/types/simulation/rand_util_test.go @@ -56,7 +56,7 @@ func TestRandStringOfLength(t *testing.T) { } func mustParseCoins(s string) sdk.Coins { - coins, err := sdk.ParseCoins(s) + coins, err := sdk.ParseCoinsNormalized(s) if err != nil { panic(err) } diff --git a/x/auth/vesting/client/cli/tx.go b/x/auth/vesting/client/cli/tx.go index 33668fadde..0974552c8a 100644 --- a/x/auth/vesting/client/cli/tx.go +++ b/x/auth/vesting/client/cli/tx.go @@ -58,7 +58,7 @@ timestamp.`, return err } - amount, err := sdk.ParseCoins(args[1]) + amount, err := sdk.ParseCoinsNormalized(args[1]) if err != nil { return err } diff --git a/x/bank/client/cli/tx.go b/x/bank/client/cli/tx.go index 64ea2ea217..21a2e6c330 100644 --- a/x/bank/client/cli/tx.go +++ b/x/bank/client/cli/tx.go @@ -46,7 +46,7 @@ ignored as it is implied from [from_key_or_address].`, return err } - coins, err := sdk.ParseCoins(args[2]) + coins, err := sdk.ParseCoinsNormalized(args[2]) if err != nil { return err } diff --git a/x/bank/client/testutil/cli_helpers.go b/x/bank/client/testutil/cli_helpers.go index 4dff74e2b5..92062a182b 100644 --- a/x/bank/client/testutil/cli_helpers.go +++ b/x/bank/client/testutil/cli_helpers.go @@ -87,7 +87,7 @@ ignored as it is implied from [from_key_or_address].`, return err } - coins, err := sdk.ParseCoins(args[2]) + coins, err := sdk.ParseCoinsNormalized(args[2]) if err != nil { return err } diff --git a/x/distribution/client/cli/tx.go b/x/distribution/client/cli/tx.go index 67635e5782..386174b083 100644 --- a/x/distribution/client/cli/tx.go +++ b/x/distribution/client/cli/tx.go @@ -256,7 +256,7 @@ $ %s tx distribution fund-community-pool 100uatom --from mykey } depositorAddr := clientCtx.GetFromAddress() - amount, err := sdk.ParseCoins(args[0]) + amount, err := sdk.ParseCoinsNormalized(args[0]) if err != nil { return err } @@ -315,12 +315,12 @@ Where proposal.json contains: return err } - amount, err := sdk.ParseCoins(proposal.Amount) + amount, err := sdk.ParseCoinsNormalized(proposal.Amount) if err != nil { return err } - deposit, err := sdk.ParseCoins(proposal.Deposit) + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) if err != nil { return err } diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index b151290e5d..33a37760ed 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -116,7 +116,7 @@ $ %s gentx my-key-name --home=/path/to/home/dir --keyring-backend=os --chain-id= } amount, _ := cmd.Flags().GetString(cli.FlagAmount) - coins, err := sdk.ParseCoins(amount) + coins, err := sdk.ParseCoinsNormalized(amount) if err != nil { return errors.Wrap(err, "failed to parse coins") } diff --git a/x/gov/client/cli/tx.go b/x/gov/client/cli/tx.go index 5f04d9184c..b13786ede8 100644 --- a/x/gov/client/cli/tx.go +++ b/x/gov/client/cli/tx.go @@ -114,7 +114,7 @@ $ %s tx gov submit-proposal --title="Test Proposal" --description="My awesome pr return fmt.Errorf("failed to parse proposal: %w", err) } - amount, err := sdk.ParseCoins(proposal.Deposit) + amount, err := sdk.ParseCoinsNormalized(proposal.Deposit) if err != nil { return err } @@ -177,7 +177,7 @@ $ %s tx gov deposit 1 10stake --from mykey from := clientCtx.GetFromAddress() // Get amount of coins - amount, err := sdk.ParseCoins(args[1]) + amount, err := sdk.ParseCoinsNormalized(args[1]) if err != nil { return err } diff --git a/x/params/client/cli/tx.go b/x/params/client/cli/tx.go index fcc8080438..154722a144 100644 --- a/x/params/client/cli/tx.go +++ b/x/params/client/cli/tx.go @@ -73,7 +73,7 @@ Where proposal.json contains: proposal.Title, proposal.Description, proposal.Changes.ToParamChanges(), ) - deposit, err := sdk.ParseCoins(proposal.Deposit) + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) if err != nil { return err } diff --git a/x/upgrade/client/cli/tx.go b/x/upgrade/client/cli/tx.go index 2a44cd5591..fd7a6ed760 100644 --- a/x/upgrade/client/cli/tx.go +++ b/x/upgrade/client/cli/tx.go @@ -61,7 +61,7 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { if err != nil { return err } - deposit, err := sdk.ParseCoins(depositStr) + deposit, err := sdk.ParseCoinsNormalized(depositStr) if err != nil { return err } @@ -110,7 +110,7 @@ func NewCmdSubmitCancelUpgradeProposal() *cobra.Command { return err } - deposit, err := sdk.ParseCoins(depositStr) + deposit, err := sdk.ParseCoinsNormalized(depositStr) if err != nil { return err } From be10bcb1633b20ae0510fcb08fa3fc1537ecde22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 16 Nov 2020 16:06:55 +0100 Subject: [PATCH 16/57] counterParty -> counterparty (#7946) * nit * fix spec and docs --- docs/ibc/custom.md | 2 +- x/ibc/core/05-port/types/module.go | 2 +- x/ibc/core/spec/05_callbacks.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ibc/custom.md b/docs/ibc/custom.md index dd840ebf13..09cd27a951 100644 --- a/docs/ibc/custom.md +++ b/docs/ibc/custom.md @@ -45,7 +45,7 @@ func (k Keeper) OnChanOpenInit(ctx sdk.Context, portID string, channelID string, channelCap *capabilitytypes.Capability, - counterParty channeltypes.Counterparty, + counterparty channeltypes.Counterparty, version string, ) error { // OpenInit must claim the channelCapability that IBC passes into the callback diff --git a/x/ibc/core/05-port/types/module.go b/x/ibc/core/05-port/types/module.go index a9a7b50922..4c68673201 100644 --- a/x/ibc/core/05-port/types/module.go +++ b/x/ibc/core/05-port/types/module.go @@ -17,7 +17,7 @@ type IBCModule interface { portID string, channelID string, channelCap *capabilitytypes.Capability, - counterParty channeltypes.Counterparty, + counterparty channeltypes.Counterparty, version string, ) error diff --git a/x/ibc/core/spec/05_callbacks.md b/x/ibc/core/spec/05_callbacks.md index c276ae370e..dd74738025 100644 --- a/x/ibc/core/spec/05_callbacks.md +++ b/x/ibc/core/spec/05_callbacks.md @@ -18,7 +18,7 @@ type IBCModule interface { portId string, channelId string, channelCap *capability.Capability, - counterParty channeltypes.Counterparty, + counterparty channeltypes.Counterparty, version string, ) error From 2f6ebb7792e3eb38a835b04fe2ede992c372229b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Nov 2020 08:05:24 +0100 Subject: [PATCH 17/57] build(deps): bump codecov/codecov-action from v1.0.14 to v1.0.15 (#7953) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from v1.0.14 to v1.0.15. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Commits](https://github.com/codecov/codecov-action/compare/v1.0.14...239febf655bba88b16ff5dea1d3135ea8663a1f9) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index afa753e232..06e85c907f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -151,7 +151,7 @@ jobs: sed -i.bak "/$(echo $filename | sed 's/\//\\\//g')/d" coverage.txt done if: env.GIT_DIFF - - uses: codecov/codecov-action@v1.0.14 + - uses: codecov/codecov-action@v1.0.15 with: file: ./coverage.txt if: env.GIT_DIFF From f962f3a28c3b91cf79ee31891d9235e65e3b8513 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Tue, 17 Nov 2020 19:42:06 +0900 Subject: [PATCH 18/57] Fix int64 overflow error for height comparison (#7944) * fix int64 overflow for height comparison * apply suggestions from review Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/ibc/core/02-client/types/height.go | 16 +++++++--------- x/ibc/core/02-client/types/height_test.go | 3 +++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/x/ibc/core/02-client/types/height.go b/x/ibc/core/02-client/types/height.go index 72af4d56b2..ab156e80de 100644 --- a/x/ibc/core/02-client/types/height.go +++ b/x/ibc/core/02-client/types/height.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "math/big" "regexp" "strconv" "strings" @@ -54,18 +55,15 @@ func (h Height) Compare(other exported.Height) int64 { if !ok { panic(fmt.Sprintf("cannot compare against invalid height type: %T. expected height type: %T", other, h)) } - var cmp int64 + var a, b big.Int if h.VersionNumber != height.VersionNumber { - cmp = int64(h.VersionNumber) - int64(height.VersionNumber) + a.SetUint64(h.VersionNumber) + b.SetUint64(height.VersionNumber) } else { - cmp = int64(h.VersionHeight) - int64(height.VersionHeight) + a.SetUint64(h.VersionHeight) + b.SetUint64(height.VersionHeight) } - if cmp < 0 { - return -1 - } else if cmp > 0 { - return 1 - } - return 0 + return int64(a.Cmp(&b)) } // LT Helper comparison function returns true if h < other diff --git a/x/ibc/core/02-client/types/height_test.go b/x/ibc/core/02-client/types/height_test.go index 33d33fd714..0bd8f0848f 100644 --- a/x/ibc/core/02-client/types/height_test.go +++ b/x/ibc/core/02-client/types/height_test.go @@ -1,6 +1,7 @@ package types_test import ( + "math" "testing" "github.com/stretchr/testify/require" @@ -23,6 +24,8 @@ func TestCompareHeights(t *testing.T) { {"version number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, {"version height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, {"version height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, + {"version number is MaxUint64", types.NewHeight(math.MaxUint64, 1), types.NewHeight(0, 1), 1}, + {"version height is MaxUint64", types.NewHeight(1, math.MaxUint64), types.NewHeight(1, 0), 1}, {"height is equal", types.NewHeight(4, 4), types.NewHeight(4, 4), 0}, } From e93b18e60ec81ef10841460f00e166d201a76fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 12:40:12 +0100 Subject: [PATCH 19/57] self height uses GTE in self client check (#7945) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/ibc/core/02-client/keeper/keeper.go | 6 +++--- x/ibc/core/02-client/keeper/keeper_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x/ibc/core/02-client/keeper/keeper.go b/x/ibc/core/02-client/keeper/keeper.go index d3465e7669..7ebfa33555 100644 --- a/x/ibc/core/02-client/keeper/keeper.go +++ b/x/ibc/core/02-client/keeper/keeper.go @@ -220,9 +220,9 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS } selfHeight := types.NewHeight(version, uint64(ctx.BlockHeight())) - if tmClient.LatestHeight.GT(selfHeight) { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than chain height %d", - tmClient.LatestHeight, ctx.BlockHeight()) + if tmClient.LatestHeight.GTE(selfHeight) { + return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than or equal to chain height %d", + tmClient.LatestHeight, selfHeight) } expectedProofSpecs := commitmenttypes.GetSDKSpecs() diff --git a/x/ibc/core/02-client/keeper/keeper_test.go b/x/ibc/core/02-client/keeper/keeper_test.go index 2ed2b2f032..c031ac37c9 100644 --- a/x/ibc/core/02-client/keeper/keeper_test.go +++ b/x/ibc/core/02-client/keeper/keeper_test.go @@ -152,7 +152,7 @@ func (suite *KeeperTestSuite) TestSetClientConsensusState() { } func (suite *KeeperTestSuite) TestValidateSelfClient() { - testClientHeight := types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight())) + testClientHeight := types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight()-1)) testCases := []struct { name string @@ -186,7 +186,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "invalid client height", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, testClientHeight.VersionHeight+10), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight())), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), false, }, { From 0647d897f58603846418e032d0931a5dbf6e5b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 13:55:33 +0100 Subject: [PATCH 20/57] add is frozen client state check to send packet (#7957) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/ibc/core/04-channel/keeper/packet.go | 5 +++++ x/ibc/core/04-channel/keeper/packet_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/x/ibc/core/04-channel/keeper/packet.go b/x/ibc/core/04-channel/keeper/packet.go index 87ba9ce337..e86887eee9 100644 --- a/x/ibc/core/04-channel/keeper/packet.go +++ b/x/ibc/core/04-channel/keeper/packet.go @@ -67,6 +67,11 @@ func (k Keeper) SendPacket( return clienttypes.ErrConsensusStateNotFound } + // prevent accidental sends with clients that cannot be updated + if clientState.IsFrozen() { + return sdkerrors.Wrapf(clienttypes.ErrClientFrozen, "cannot send packet on a frozen client with ID %s", connectionEnd.GetClientID()) + } + // check if packet timeouted on the receiving chain latestHeight := clientState.GetLatestHeight() timeoutHeight := packet.GetTimeoutHeight() diff --git a/x/ibc/core/04-channel/keeper/packet_test.go b/x/ibc/core/04-channel/keeper/packet_test.go index f04b6ac100..f53ed79475 100644 --- a/x/ibc/core/04-channel/keeper/packet_test.go +++ b/x/ibc/core/04-channel/keeper/packet_test.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ibcmock "github.com/cosmos/cosmos-sdk/x/ibc/testing/mock" ) @@ -111,6 +112,22 @@ func (suite *KeeperTestSuite) TestSendPacket() { packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(channelA.PortID, channelA.ID) }, false}, + {"client state is frozen", func() { + _, _, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) + + connection := suite.chainA.GetConnection(connA) + clientState := suite.chainA.GetClientState(connection.ClientId) + cs, ok := clientState.(*ibctmtypes.ClientState) + suite.Require().True(ok) + + // freeze client + cs.FrozenHeight = clienttypes.NewHeight(0, 1) + suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), connection.ClientId, cs) + + packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) + channelCap = suite.chainA.GetChannelCapability(channelA.PortID, channelA.ID) + }, false}, + {"timeout height passed", func() { clientA, _, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) // use client state latest height for timeout From 9369a005576c55aa2f96db4f9d8ced1882a0f3eb Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Tue, 17 Nov 2020 06:27:12 -0800 Subject: [PATCH 21/57] x/simulation: make signals channel buffered to avoid missing signals (#7952) Invoking: c := make(chan os.Signal) signal.Notify(c, signals...) is explicitly called out as a bug in the os/signal docs and should instead make that channel buffered lest a signal could be lost. Fixes #7950 Co-authored-by: Aleksandr Bezobchuk --- x/simulation/simulate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/simulation/simulate.go b/x/simulation/simulate.go index 7767cbbe50..fdcf224611 100644 --- a/x/simulation/simulate.go +++ b/x/simulation/simulate.go @@ -102,7 +102,7 @@ func SimulateFromSeed( opCount := 0 // Setup code to catch SIGTERM's - c := make(chan os.Signal) + c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) go func() { From ab7104865db622c1aecf2861b31f06b33a410ed1 Mon Sep 17 00:00:00 2001 From: atheeshp <59333759+atheeshp@users.noreply.github.com> Date: Tue, 17 Nov 2020 20:16:24 +0530 Subject: [PATCH 22/57] improve error messages for legacy rest endpoints (#7856) * improve error messages for legacy rest endpoints * add test * review changes * review changes * refactor * Update x/auth/client/rest/query.go Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Aleksandr Bezobchuk --- x/auth/client/rest/decode.go | 6 +++ x/auth/client/rest/query.go | 30 +++++++++++++ x/auth/client/rest/rest_test.go | 74 +++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/x/auth/client/rest/decode.go b/x/auth/client/rest/decode.go index a3aa5ec750..d048f91b4c 100644 --- a/x/auth/client/rest/decode.go +++ b/x/auth/client/rest/decode.go @@ -55,6 +55,12 @@ func DecodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { response := DecodeResp(stdTx) + err = checkSignModeError(w, clientCtx, response, "/cosmos/tx/v1beta1/txs/decode") + if err != nil { + // Error is already returned by checkSignModeError. + return + } + rest.PostProcessResponse(w, clientCtx, response) } } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 23afef323c..d60028abc5 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -17,6 +17,8 @@ import ( genutilrest "github.com/cosmos/cosmos-sdk/x/genutil/client/rest" ) +const unRegisteredConcreteTypeErr = "unregistered concrete type" + // query accountREST Handler func QueryAccountRequestHandlerFn(storeName string, clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -107,6 +109,12 @@ func QueryTxsRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { packStdTxResponse(w, clientCtx, txRes) } + err = checkSignModeError(w, clientCtx, searchResult, "/cosmos/tx/v1beta1/txs") + if err != nil { + // Error is already returned by checkSignModeError. + return + } + rest.PostProcessResponseBare(w, clientCtx, searchResult) } } @@ -143,6 +151,12 @@ func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr)) } + err = checkSignModeError(w, clientCtx, output, "/cosmos/tx/v1beta1/tx/{txhash}") + if err != nil { + // Error is already returned by checkSignModeError. + return + } + rest.PostProcessResponseBare(w, clientCtx, output) } } @@ -182,3 +196,19 @@ func packStdTxResponse(w http.ResponseWriter, clientCtx client.Context, txRes *s return nil } + +func checkSignModeError(w http.ResponseWriter, ctx client.Context, resp interface{}, grpcEndPoint string) error { + // LegacyAmino used intentionally here to handle the SignMode errors + marshaler := ctx.LegacyAmino + + _, err := marshaler.MarshalJSON(resp) + if err != nil && strings.Contains(err.Error(), unRegisteredConcreteTypeErr) { + rest.WriteErrorResponse(w, http.StatusInternalServerError, + "This transaction was created with the new SIGN_MODE_DIRECT signing method, and therefore cannot be displayed"+ + " via legacy REST handlers, please use CLI or directly query the Tendermint RPC endpoint to query"+ + " this transaction. gRPC gateway endpoint is "+grpcEndPoint) + return err + } + + return nil +} diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index 86216dd53b..b03b615b6a 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -10,14 +10,19 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/testutil" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/types/tx/signing" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" + ibccli "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/client/cli" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" rest2 "github.com/cosmos/cosmos-sdk/x/auth/client/rest" "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" "github.com/cosmos/cosmos-sdk/x/bank/types" @@ -298,6 +303,75 @@ func (s *IntegrationTestSuite) broadcastReq(stdTx legacytx.StdTx, mode string) ( return rest.PostRequest(fmt.Sprintf("%s/txs", val.APIAddress), "application/json", bz) } +func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { + val := s.network.Validators[0] + + args := []string{ + "121", // dummy port-id + "21212121212", // dummy channel-id + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=foobar", flags.FlagMemo), + } + + // created a dummy txn for IBC, eventually it fails. Our intension is to test the error message of querying a + // message which is signed with proto, since IBC won't support legacy amino at all we are considering a message from IBC module. + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, ibccli.NewChannelCloseInitCmd(), args) + s.Require().NoError(err) + + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + + s.Require().NoError(s.network.WaitForNextBlock()) + + // try to fetch the txn using legacy rest, this won't work since the ibc module doesn't support amino. + txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs/%s", val.APIAddress, txRes.TxHash)) + s.Require().NoError(err) + + var errResp rest.ErrorResponse + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &errResp)) + + errMsg := "This transaction was created with the new SIGN_MODE_DIRECT signing method, " + + "and therefore cannot be displayed via legacy REST handlers, please use CLI or directly query the Tendermint " + + "RPC endpoint to query this transaction." + + s.Require().Contains(errResp.Error, errMsg) + + // try fetching the txn using gRPC req, it will fetch info since it has proto codec. + grpcJSON, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/tx/%s", val.APIAddress, txRes.TxHash)) + s.Require().NoError(err) + + var getTxRes txtypes.GetTxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(grpcJSON, &getTxRes)) + s.Require().Equal(getTxRes.Tx.Body.Memo, "foobar") + + // generate broadcast only txn. + args = append(args, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, ibccli.NewChannelCloseInitCmd(), args) + s.Require().NoError(err) + + txFile, cleanup := testutil.WriteToNewTempFile(s.T(), string(out.Bytes())) + txFileName := txFile.Name() + s.T().Cleanup(cleanup) + + // encode the generated txn. + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, authcli.GetEncodeCommand(), []string{txFileName}) + s.Require().NoError(err) + + bz, err := val.ClientCtx.LegacyAmino.MarshalJSON(rest2.DecodeReq{Tx: string(out.Bytes())}) + s.Require().NoError(err) + + // try to decode the txn using legacy rest, it fails. + res, err := rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz) + s.Require().NoError(err) + + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &errResp)) + s.Require().Contains(errResp.Error, errMsg) +} + func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } From 715933b5f37d37928e8d4a97696b1ef8e8e6cdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 16:01:34 +0100 Subject: [PATCH 23/57] reduce redundancy (#7959) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/ibc/core/24-host/keys.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/ibc/core/24-host/keys.go b/x/ibc/core/24-host/keys.go index 51d2939577..21f4bc4309 100644 --- a/x/ibc/core/24-host/keys.go +++ b/x/ibc/core/24-host/keys.go @@ -79,7 +79,7 @@ func ClientStateKey() []byte { // FullConsensusStatePath takes a client identifier and returns a Path under which to // store the consensus state of a client. func FullConsensusStatePath(clientID string, height exported.Height) string { - return FullClientPath(clientID, fmt.Sprintf("%s/%s", KeyConsensusStatePrefix, height)) + return FullClientPath(clientID, ConsensusStatePath(height)) } // FullConsensusStateKey returns the store key for the consensus state of a particular @@ -177,7 +177,7 @@ func NextSequenceAckKey(portID, channelID string) []byte { // PacketCommitmentPath defines the commitments to packet data fields store path func PacketCommitmentPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/%s/%s", KeyPacketCommitmentPrefix, channelPath(portID, channelID), sequencePath(sequence)) + return fmt.Sprintf("%s/%d", PacketCommitmentPrefixPath(portID, channelID), sequence) } // PacketCommitmentKey returns the store key of under which a packet commitment @@ -193,7 +193,7 @@ func PacketCommitmentPrefixPath(portID, channelID string) string { // PacketAcknowledgementPath defines the packet acknowledgement store path func PacketAcknowledgementPath(portID, channelID string, sequence uint64) string { - return fmt.Sprintf("%s/%s/%s", KeyPacketAckPrefix, channelPath(portID, channelID), sequencePath(sequence)) + return fmt.Sprintf("%s/%d", PacketAcknowledgementPrefixPath(portID, channelID), sequence) } // PacketAcknowledgementKey returns the store key of under which a packet From a7435d03ebe4e588014d95a7bb40d61527c3e680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 16:18:16 +0100 Subject: [PATCH 24/57] fix validate basic check (#7962) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/ibc/core/04-channel/types/channel.go | 2 +- x/ibc/core/04-channel/types/channel_test.go | 27 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/x/ibc/core/04-channel/types/channel.go b/x/ibc/core/04-channel/types/channel.go index 9bddb84fa4..8513a8123d 100644 --- a/x/ibc/core/04-channel/types/channel.go +++ b/x/ibc/core/04-channel/types/channel.go @@ -55,7 +55,7 @@ func (ch Channel) GetVersion() string { // ValidateBasic performs a basic validation of the channel fields func (ch Channel) ValidateBasic() error { - if ch.State.String() == "" { + if ch.State == UNINITIALIZED { return ErrInvalidChannelState } if !(ch.Ordering == ORDERED || ch.Ordering == UNORDERED) { diff --git a/x/ibc/core/04-channel/types/channel_test.go b/x/ibc/core/04-channel/types/channel_test.go index 14592d4b4c..30fee4443b 100644 --- a/x/ibc/core/04-channel/types/channel_test.go +++ b/x/ibc/core/04-channel/types/channel_test.go @@ -8,6 +8,33 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" ) +func TestChannelValidateBasic(t *testing.T) { + counterparty := types.Counterparty{"portidone", "channelidone"} + testCases := []struct { + name string + channel types.Channel + expPass bool + }{ + {"valid channel", types.NewChannel(types.TRYOPEN, types.ORDERED, counterparty, connHops, version), true}, + {"invalid state", types.NewChannel(types.UNINITIALIZED, types.ORDERED, counterparty, connHops, version), false}, + {"invalid order", types.NewChannel(types.TRYOPEN, types.NONE, counterparty, connHops, version), false}, + {"more than 1 connection hop", types.NewChannel(types.TRYOPEN, types.ORDERED, counterparty, []string{"connection1", "connection2"}, version), false}, + {"invalid connection hop identifier", types.NewChannel(types.TRYOPEN, types.ORDERED, counterparty, []string{"(invalid)"}, version), false}, + {"invalid counterparty", types.NewChannel(types.TRYOPEN, types.ORDERED, types.NewCounterparty("(invalidport)", "channelidone"), connHops, version), false}, + } + + for i, tc := range testCases { + tc := tc + + err := tc.channel.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid test case %d failed: %s", i, tc.name) + } else { + require.Error(t, err, "invalid test case %d passed: %s", i, tc.name) + } + } +} + func TestCounterpartyValidateBasic(t *testing.T) { testCases := []struct { name string From 03c8fb313da7871d1424a991124fdee663b089f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 16:37:20 +0100 Subject: [PATCH 25/57] add domain separation between port and channel (#7960) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/ibc/applications/transfer/types/keys.go | 4 +++- .../applications/transfer/types/keys_test.go | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 x/ibc/applications/transfer/types/keys_test.go diff --git a/x/ibc/applications/transfer/types/keys.go b/x/ibc/applications/transfer/types/keys.go index f1fbffd951..1b0e45b9c7 100644 --- a/x/ibc/applications/transfer/types/keys.go +++ b/x/ibc/applications/transfer/types/keys.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + "github.com/tendermint/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" @@ -43,5 +45,5 @@ var ( // port associated with the channel ID so that the address created is actually // unique. func GetEscrowAddress(portID, channelID string) sdk.AccAddress { - return sdk.AccAddress(crypto.AddressHash([]byte(portID + channelID))) + return sdk.AccAddress(crypto.AddressHash([]byte(fmt.Sprintf("%s/%s", portID, channelID)))) } diff --git a/x/ibc/applications/transfer/types/keys_test.go b/x/ibc/applications/transfer/types/keys_test.go new file mode 100644 index 0000000000..9ab3314c2e --- /dev/null +++ b/x/ibc/applications/transfer/types/keys_test.go @@ -0,0 +1,24 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" +) + +// Test that there is domain separation between the port id and the channel id otherwise an +// escrow address may overlap with another channel end +func TestGetEscrowAddress(t *testing.T) { + var ( + port1 = "transfer" + channel1 = "channel" + port2 = "transfercha" + channel2 = "nnel" + ) + + escrow1 := types.GetEscrowAddress(port1, channel1) + escrow2 := types.GetEscrowAddress(port2, channel2) + require.NotEqual(t, escrow1, escrow2) +} From b90bacb7750e2a8dea6cf725468e451abc71c3a0 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 18 Nov 2020 00:25:32 +0500 Subject: [PATCH 26/57] docs: add newline to versions file (#7938) Co-authored-by: Alessio Treglia --- docs/versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/versions b/docs/versions index 8df09cc782..d5dc85eb28 100644 --- a/docs/versions +++ b/docs/versions @@ -1,2 +1,2 @@ master master -launchpad/backports v0.39 \ No newline at end of file +launchpad/backports v0.39 From 1cc8af8d9be1cd85f628c8dd641d6d191098637a Mon Sep 17 00:00:00 2001 From: Marie Gauthier Date: Tue, 17 Nov 2020 21:41:43 +0100 Subject: [PATCH 27/57] [docs]: update building modules section to reflect ADR31 (#7702) * Revert "Revert "Update old ref of RegisterQueryService"" This reverts commit 03e4c56de53938ccbf025a441e54b9842f7c4544. * Update intro, module-manager and messages-and-queries * Update messages-and-queries * Update handler * Update structure * Add doc related to RegisterMsgServiceDesc * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba * Update docs/building-modules/handler.md Co-authored-by: Robert Zaremba * Update docs/building-modules/messages-and-queries.md * Update handler.md * Rename handler.md to msg-services.md * Update legacy msgs wording * Update messages-and-queries.md * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny * Update docs/building-modules/intro.md Co-authored-by: Amaury Martiny * Remove handler mention from intro.md * Update docs/building-modules/messages-and-queries.md Co-authored-by: Amaury Martiny * Update docs/building-modules/messages-and-queries.md Co-authored-by: Amaury Martiny * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny * Update docs/building-modules/keeper.md Co-authored-by: Amaury Martiny * Update docs/building-modules/msg-services.md Co-authored-by: Amaury Martiny * Address review comments * Use tag * Update docs/building-modules/intro.md Co-authored-by: Cory * Update docs/building-modules/intro.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/core/transactions.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Remove framework related explanation from docs * Update docs/building-modules/messages-and-queries.md Co-authored-by: Aaron Craelius * Update docs/building-modules/module-manager.md Co-authored-by: Aaron Craelius * Update docs/building-modules/module-manager.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/building-modules/msg-services.md Co-authored-by: Aaron Craelius * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius * Update beginblock-endblock.md * Update docs/core/baseapp.md Co-authored-by: Aaron Craelius * Update docs/core/transactions.md Co-authored-by: Aaron Craelius * Add deprecated notice * Update tx-lifecycle.md Co-authored-by: Robert Zaremba Co-authored-by: Amaury Martiny Co-authored-by: Aaron Craelius Co-authored-by: Cory Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- docs/basics/app-anatomy.md | 2 +- docs/basics/gas-fees.md | 2 +- docs/basics/tx-lifecycle.md | 14 +-- docs/building-modules/README.md | 2 +- docs/building-modules/beginblock-endblock.md | 2 +- docs/building-modules/handler.md | 96 ------------------ docs/building-modules/intro.md | 11 +-- docs/building-modules/keeper.md | 2 +- docs/building-modules/messages-and-queries.md | 47 ++++++--- docs/building-modules/module-manager.md | 18 ++-- docs/building-modules/msg-services.md | 97 +++++++++++++++++++ docs/building-modules/query-services.md | 4 +- docs/building-modules/structure.md | 1 + docs/core/baseapp.md | 6 +- docs/core/events.md | 4 +- docs/core/transactions.md | 6 +- docs/intro/sdk-app-architecture.md | 2 +- types/module/module.go | 6 +- x/auth/module.go | 2 +- x/capability/module.go | 2 +- x/ibc/testing/mock/mock.go | 2 +- x/mint/module.go | 2 +- x/params/module.go | 2 +- x/upgrade/module.go | 2 +- 24 files changed, 178 insertions(+), 156 deletions(-) delete mode 100644 docs/building-modules/handler.md create mode 100644 docs/building-modules/msg-services.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index e7bfc8cf0c..b45e22d6ba 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -158,7 +158,7 @@ Each module should also implement the `RegisterServices` method as part of the [ #### Handlers -The [handler](../building-modules/handler.md) refers to the part of the module responsible for processing the `Msg` after it is routed by `baseapp`. Handler functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [handler](../building-modules/msg-services.md#handler-type) refers to the part of the module responsible for processing the `Msg` after it is routed by `baseapp`. Handler functions of modules are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The `handler` of a module is generally defined in a file called `handler.go` and consists of: diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 76dc2aa83b..94cd59a562 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -44,7 +44,7 @@ By default, the Cosmos SDK makes use of two different gas meters, the [main gas `ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction. -Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`handler`](../building-modules/handler.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). +Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`Msg` service](../building-modules/msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). ### Block Gas Meter diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index 7e375fc4db..e025765546 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -179,7 +179,7 @@ explicitly ordered in the block proposal. ### DeliverTx -The `DeliverTx` ABCI function defined in [`baseapp`](../core/baseapp.md) does the bulk of the +The `DeliverTx` ABCI function defined in [`BaseApp`](../core/baseapp.md) does the bulk of the state transitions: it is run for each transaction in the block in sequential order as committed to during consensus. Under the hood, `DeliverTx` is almost identical to `CheckTx` but calls the [`runTx`](../core/baseapp.md#runtx) function in deliver mode instead of check mode. @@ -194,15 +194,15 @@ Instead of using their `checkState`, full-nodes use `deliverState`: `AnteHandler` will not compare `gas-prices` to the node's `min-gas-prices` since that value is local to each node - differing values across nodes would yield nondeterministic results. -- **Route and Handler:** While `CheckTx` would have exited, `DeliverTx` continues to run +- **`MsgServiceRouter`:** While `CheckTx` would have exited, `DeliverTx` continues to run [`runMsgs`](../core/baseapp.md#runtx-and-runmsgs) to fully execute each `Msg` within the transaction. - Since the transaction may have messages from different modules, `baseapp` needs to know which module - to find the appropriate Handler. Thus, the `route` function is called via the [module manager](../building-modules/module-manager.md) to - retrieve the route name and find the [`Handler`](../building-modules/handler.md) within the module. + Since the transaction may have messages from different modules, `BaseApp` needs to know which module + to find the appropriate handler. This is achieved using `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](../building-modules/msg-services.md). + For legacy `Msg` routing, the `Route` function is called via the [module manager](../building-modules/module-manager.md) to retrieve the route name and find the legacy [`Handler`](../building-modules/msg-services.md#handler-type) within the module. -- **Handler:** The `handler`, a step up from `AnteHandler`, is responsible for executing each +- **`Msg` service:** The `Msg` service, a step up from `AnteHandler`, is responsible for executing each message in the `Tx` and causes state transitions to persist in `deliverTxState`. It is defined - within a `Msg`'s module and writes to the appropriate stores within the module. + within a module `Msg` protobuf service and writes to the appropriate stores within the module. - **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much gas is being used; if execution completes, `GasUsed` is set and returned in the diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md index 43b8638ca9..22f3ffb75e 100644 --- a/docs/building-modules/README.md +++ b/docs/building-modules/README.md @@ -11,7 +11,7 @@ This repository contains documentation on concepts developers need to know in or 1. [Introduction to Cosmos SDK Modules](./intro.md) 2. [`AppModule` Interface and Module Manager](./module-manager.md) 3. [Messages and Queries](./messages-and-queries.md) -4. [`Handler`s - Processing Messages](./handler.md) +4. [`Msg` services - Processing Messages](./msg-services.md) 5. [Query Services - Processing Queries](./query-services.md) 6. [BeginBlocker and EndBlocker](./beginblock-endblock.md) 7. [`Keeper`s](./keeper.md) diff --git a/docs/building-modules/beginblock-endblock.md b/docs/building-modules/beginblock-endblock.md index b4f3abaff9..09a48df880 100644 --- a/docs/building-modules/beginblock-endblock.md +++ b/docs/building-modules/beginblock-endblock.md @@ -16,7 +16,7 @@ order: 6 When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`AppModule` interface](./module-manager.md#appmodule). The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in a **`abci.go`** file. -The actual implementation of `BeginBlocker` and `EndBlocker` in `./abci.go` are very similar to that of a [`handler`](./handler.md): +The actual implementation of `BeginBlocker` and `EndBlocker` in `./abci.go` are very similar to that of a [`Msg` service](./msg-services.md): - They generally use the [`keeper`](./keeper.md) and [`ctx`](../core/context.md) to retrieve information about the latest state. - If needed, they use the `keeper` and `ctx` to trigger state-transitions. diff --git a/docs/building-modules/handler.md b/docs/building-modules/handler.md deleted file mode 100644 index 45e9a4c119..0000000000 --- a/docs/building-modules/handler.md +++ /dev/null @@ -1,96 +0,0 @@ - - -# Handlers - -A `Handler` designates a function that processes [`message`s](./messages-and-queries.md#messages). `Handler`s are specific to the module in which they are defined, and only process `message`s defined within the said module. They are called from `baseapp` during [`DeliverTx`](../core/baseapp.md#delivertx). {synopsis} - -## Pre-requisite Readings - -- [Module Manager](./module-manager.md) {prereq} -- [Messages and Queries](./messages-and-queries.md) {prereq} - -## `handler` type - -The `handler` type defined in the Cosmos SDK specifies the typical structure of a `handler` function. - -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L4 - -Let us break it down: - -- The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. -- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. -- The [`*Result`] returned to `baseapp`, which contains (among other things) information on the execution of the `handler` and [`events`](../core/events.md). - +++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95 - -## Implementation of a module `handler`s - -Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The -[module manager](./module-manager.md) is used to add the module's `handler`s to the -[application's `router`](../core/baseapp.md#message-routing) via the `Route()` method. Typically, -the manager's `Route()` method simply constructs a Route that calls a `NewHandler()` method defined in `handler.go`, -which looks like the following: - -```go -func NewHandler(keeper Keeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { - ctx = ctx.WithEventManager(sdk.NewEventManager()) - switch msg := msg.(type) { - case *MsgType1: - return handleMsgType1(ctx, keeper, msg) - - case *MsgType2: - return handleMsgType2(ctx, keeper, msg) - - default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg) - } - } -} -``` - -First, the `handler` function sets a new `EventManager` to the context to isolate events per `msg`. -Then, this simple switch returns a `handler` function specific to the type of the received `message`. These `handler` functions are the ones that actually process `message`s, and usually follow the following 2 steps: - -- First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` method has already been called, meaning *stateless* checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in the `handler` can be more expensive and require access to the state. For example, a `handler` for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `handler` needs to call the [`keeper`'s](./keeper.md) getter functions. -- Then, if the checks are successfull, the `handler` calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition. - -Before returning, `handler` functions generally emit one or multiple [`events`](../core/events.md) via the `EventManager` held in the `ctx`: - -```go -ctx.EventManager().EmitEvent( - sdk.NewEvent( - eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module - sdk.NewAttribute(attributeKey, attributeValue), - ), - ) -``` - -These `events` are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../core/events.md) to learn more about `events`. - -Finally, the `handler` function returns a `*sdk.Result` which contains the aforementioned `events` and an optional `Data` field. - -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95 - -Next is an example of how to return a `*Result` from the `gov` module: - -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go#L67-L70 - -For a deeper look at `handler`s, see this [example implementation of a `handler` function](https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/gov/handler.go) from the `gov` module. - -The `handler` can then be registered from [`AppModule.Route()`](./module-manager.md#appmodule) as shown in the example below: - -+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/x/gov/module.go#L143-L146 - -## Telemetry - -New [telemetry metrics](../core/telemetry.md) can be created from the `handler` when handling messages for instance. - -This is an example from the `auth` module: - -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/auth/vesting/handler.go#L68-L80 - -## Next {hide} - -Learn about [query services](./query-services.md) {hide} diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 7b3a4c3faa..95d45fa7b6 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -17,7 +17,7 @@ The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It On top of this core, the Cosmos SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./messages-and-queries.md#messages). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one or more `KVStore`s in the [main multistore](../core/store.md), as well as a subset of [message types](./messages-and-queries.md#messages). These messages are routed by one of the main component of SDK core, [`BaseApp`](../core/baseapp.md), to the [`Msg` service](./msg-services.md) of the module that define them. ``` + @@ -76,12 +76,11 @@ While there is no definitive guidelines for writing modules, here are some impor ## Main Components of SDK Modules -Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: +Modules are by convention defined in the `./x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./messages-and-queries.md#messages) to trigger state-transitions. -- A [`handler`](./handler.md) used to process messages when they are routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. -- A [query service](./query-services.md), used to process user queries when they are routed to the module by [`baseapp`](../core/baseapp.md#query-routing). +- A [`keeper`](./keeper.md), used to access the module's store(s) and update the state. +- A [`Msg` service](./messages-and-queries.md#messages) used to process messages when they are routed to the module by [`BaseApp`](../core/baseapp.md#message-routing) and trigger state-transitions. +- A [query service](./query-services.md), used to process user queries when they are routed to the module by [`BaseApp`](../core/baseapp.md#query-routing). - Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module. In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). diff --git a/docs/building-modules/keeper.md b/docs/building-modules/keeper.md index 5c57faef1f..e84abfb01f 100644 --- a/docs/building-modules/keeper.md +++ b/docs/building-modules/keeper.md @@ -46,7 +46,7 @@ Of course, it is possible to define different types of internal `keeper`s for th ## Implementing Methods -`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`handler`](./handler.md) when `keeper`s' methods are called. +`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed via the `ValidateBasic()` method of the [`message`](./messages-and-queries.md#messages) and the [`Msg` server](./msg-services.md) when `keeper`s' methods are called. Typically, a *getter* method will present with the following signature diff --git a/docs/building-modules/messages-and-queries.md b/docs/building-modules/messages-and-queries.md index 7139044981..33afa51dbb 100644 --- a/docs/building-modules/messages-and-queries.md +++ b/docs/building-modules/messages-and-queries.md @@ -4,7 +4,7 @@ order: 3 # Messages and Queries -`Message`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `handler`s, `keeper`s and `querier`s, exist to process `message`s and `queries`. {synopsis} +`Msg`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `Msg` services, `keeper`s and `Query` services, exist to process `message`s and `queries`. {synopsis} ## Pre-requisite Readings @@ -12,15 +12,36 @@ order: 3 ## Messages -`Message`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../core/transactions.md), which may contain one or multiple of them. +`Msg`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../core/transactions.md), which may contain one or more of them. -When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`baseapp`](../core/baseapp.md). Then, each `message` contained in the transaction is extracted and routed to the appropriate module via `baseapp`'s `router` so that it can be processed by the module's [`handler`](./handler.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When a transaction is relayed from the underlying consensus engine to the SDK application, it is first decoded by [`BaseApp`](../core/baseapp.md). Then, each message contained in the transaction is extracted and routed to the appropriate module via `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](./msg-services.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). -Defining `message`s is the responsibility of module developers. Typically, they are defined as protobuf messages in a `proto/` directory (see more info about [conventions and naming](../core/encoding.md#faq)). The `message`'s definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said `message`. +### `Msg` Services -Here's an example of a protobuf message definition: +Starting from v0.40, defining Protobuf `Msg` services is the recommended way to handle messages. A `Msg` protobuf service should be created per module, typically in `tx.proto` (see more info about [conventions and naming](../core/encoding.md#faq)). It must have an RPC service method defined for each message in the module. -+++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/gov/v1beta1/tx.proto#L15-L27 +See an example of a `Msg` service definition from `x/bank` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L10-L17 + +For backwards compatibility with [legacy Amino `Msg`s](#legacy-amino-msgs), existing `Msg` types should be used as the request parameter for `service` definitions. Newer `Msg` types which only support `service` definitions should use the more canonical `Msg...Request` names. + +`Msg` request types need to implement the `MsgRequest` interface which is a simplified version of the `Msg` interface described [below](#legacy-amino-msgs) with only `ValidateBasic()` and `GetSigners()` methods. + +Defining such `Msg` services allow to specify return types as part of `Msg` response using the canonical `Msg...Response` names. + +In addition, this generates client and server code. +The generated `MsgServer` interface defines the server API for the `Msg` service and its implementation is described as part of the [`Msg` services](./msg-services.md) documentation. + +A `RegisterMsgServer` method is also generated and should be used to register the module's `MsgServer` implementation in `RegisterServices` method from the [`AppModule` interface](./module-manager.md#appmodule). + +In order for clients (CLI and grpc-gateway) to have these URLs registered, the SDK provides the function `RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.ServiceDesc)` that should be called inside module's [`RegisterInterfaces`](module-manager.md#appmodulebasic) method, using the proto-generated `&_Msg_serviceDesc` as `*grpc.ServiceDesc` argument. + +### Legacy Amino `Msg`s + +This way of defining messages is deprecated and using [`Msg` services](#msg-services) is preferred. + +Legacy `Msg`s can be defined as protobuf messages. The messages definition usually includes a list of parameters needed to process the message that will be provided by end-users when they want to create a new transaction containing said message. The `Msg` is typically accompanied by a standard constructor function, that is called from one of the [module's interface](./module-interfaces.md). `message`s also need to implement the [`Msg`] interface: @@ -30,17 +51,17 @@ It extends `proto.Message` and contains the following methods: - `Route() string`: Name of the route for this message. Typically all `message`s in a module have the same route, which is most often the module's name. - `Type() string`: Type of the message, used primarly in [events](../core/events.md). This should return a message-specific `string`, typically the denomination of the message itself. -- `ValidateBasic() error`: This method is called by `baseapp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). +- `ValidateBasic() error`: This method is called by `BaseApp` very early in the processing of the `message` (in both [`CheckTx`](../core/baseapp.md#checktx) and [`DeliverTx`](../core/baseapp.md#delivertx)), in order to discard obviously invalid messages. `ValidateBasic` should only include *stateless* checks, i.e. checks that do not require access to the state. This usually consists in checking that the message's parameters are correctly formatted and valid (i.e. that the `amount` is strictly positive for a transfer). - `GetSignBytes() []byte`: Return the canonical byte representation of the message. Used to generate a signature. - `GetSigners() []AccAddress`: Return the list of signers. The SDK will make sure that each `message` contained in a transaction is signed by all the signers listed in the list returned by this method. See an example implementation of a `message` from the `gov` module: -+++ https://github.com/cosmos/cosmos-sdk/blob/master/x/gov/types/msgs.go#L94-L136 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/gov/types/msgs.go#L77-L125 ## Queries -A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `baseapp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md). +A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `BaseApp`'s `queryrouter` so that it can be processed by the module's query service (./query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../interfaces/query-lifecycle.md). ### gRPC Queries @@ -52,7 +73,7 @@ Here's an example of such a `Query` service definition: As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://golang.org/pkg/fmt/#Stringer). -A `RegisterQueryServer` method is also generated and should be used to register the module's query server in `RegisterQueryService` method from the [`AppModule` interface](./module-manager.md#appmodule). +A `RegisterQueryServer` method is also generated and should be used to register the module's query server in the `RegisterServices` method from the [`AppModule` interface](./module-manager.md#appmodule). ### Legacy Queries @@ -64,8 +85,8 @@ queryCategory/queryRoute/queryType/arg1/arg2/... where: -- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `baseapp`'s [`Query` method](../core/baseapp.md#query). -- `queryRoute` is used by `baseapp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module. +- `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `BaseApp`'s [`Query` method](../core/baseapp.md#query). +- `queryRoute` is used by `BaseApp`'s [`queryRouter`](../core/baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module. - `queryType` is used by the module's [`querier`](./query-services.md#legacy-queriers) to map the `query` to the appropriate `querier function` within the module. - `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the `Data` field of the request `req` instead of the `path`. @@ -87,4 +108,4 @@ See following examples: ## Next {hide} -Learn about [`handler`s](./handler.md) {hide} \ No newline at end of file +Learn about [`Msg` services](./msg-services.md) {hide} diff --git a/docs/building-modules/module-manager.md b/docs/building-modules/module-manager.md index 7c6ead627b..cd8cc4b9ec 100644 --- a/docs/building-modules/module-manager.md +++ b/docs/building-modules/module-manager.md @@ -62,17 +62,17 @@ It does not have its own manager, and exists separately from [`AppModule`](#appm The `AppModule` interface defines the inter-dependent methods modules need to implement. -+++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/types/module/module.go#L160-L182 ++++ https://github.com/cosmos/cosmos-sdk/blob/b4cce159bcc6a32ac78245c6866dd87c73f3720d/types/module/module.go#L160-L182 `AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. Let us go through the methods of `AppModule`: - `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). -- `Route()`: Returns the route for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- `QuerierRoute()` (deprecated): Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`baseapp`](../core/baseapp.md#query-routing). +- `Route()`: Returns the route for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`BaseApp`](../core/baseapp.md#message-routing). +- `QuerierRoute()` (deprecated): Returns the name of the module's query route, for [`queries`](./messages-and-queries.md#queries) to be routes to the module by [`BaseApp`](../core/baseapp.md#query-routing). - `LegacyQuerierHandler(*codec.LegacyAmino)` (deprecated): Returns a [`querier`](./query-services.md#legacy-queriers) given the query `path`, in order to process the `query`. -- `RegisterQueryService(grpc.Server)`: Allows a module to register a gRPC query service. +- `RegisterServices(Configurator)`: Allows a module to register services. - `BeginBlock(sdk.Context, abci.RequestBeginBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. Implement empty if no logic needs to be triggered at the beginning of each block for this module. - `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the beginning of each block for this module. @@ -80,7 +80,7 @@ Let us go through the methods of `AppModule`: Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). -Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `Route()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. +Almost every module needs to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `Route()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./msg-services.md#handler-type) and therefore needs to pass the module's [`keeper`](./keeper.md) as a parameter. ```go // example @@ -134,12 +134,12 @@ The module manager is used throughout the application whenever an action on a co - `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). - `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/app-anatomy.md#constructor-function). - `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./invariants.md) of each module. -- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers module routes to the application's `router`, in order to route [`message`s](./messages-and-queries.md#messages) to the appropriate [`handler`](./handler.md), and module query routes to the application's `queryRouter`, in order to route [`queries`](./messages-and-queries.md#queries) to the appropriate [`querier`](./query-services.md#legacy-queriers). -- `RegisterQueryServices(grpcRouter grpc.Server)`: Registers all module gRPC query services. +- `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers legacy [`Msg`](./messages-and-queries.md#messages) and [`querier`](./query-services.md#legacy-queriers) routes. +- `RegisterServices(cfg Configurator)`: Registers all module services. - `InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates. - `ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler)`: Calls the [`ExportGenesis`](./genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required. -- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`baseapp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. -- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`baseapp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). +- `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`BaseApp`](../core/baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. +- `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`BaseApp`](../core/baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./beginblock-endblock.md) function of each module, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/context.md) with an event manager to aggregate [events](../core/events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). Here's an example of a concrete integration within an application: diff --git a/docs/building-modules/msg-services.md b/docs/building-modules/msg-services.md new file mode 100644 index 0000000000..0cde42b195 --- /dev/null +++ b/docs/building-modules/msg-services.md @@ -0,0 +1,97 @@ + +# `Msg` Services + +A `Msg` Service processes [messages](./messages-and-queries.md#messages). `Msg` Services are specific to the module in which they are defined, and only process messages defined within the said module. They are called from `BaseApp` during [`DeliverTx`](../core/baseapp.md#delivertx). {synopsis} + +## Pre-requisite Readings + +- [Module Manager](./module-manager.md) {prereq} +- [Messages and Queries](./messages-and-queries.md) {prereq} + +## Implementation of a module `Msg` service + +All `Msg` processing is done by a [`Msg`](messages-and-queries.md#msg-services) protobuf service. Each module should define a `Msg` service, which will be responsible for request and response serialization. + +As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code. + +When possible, the existing module's [`Keeper`](keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L14-L16 + +`msgServer` methods can retrieve the `sdk.Context` from the `context.Context` parameter method using the `sdk.UnwrapSDKContext`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L27 + +`Msg` processing usually follows these 2 steps: + +- First, they perform *stateful* checks to make sure the `message` is valid. At this stage, the `message`'s `ValidateBasic()` method has already been called, meaning *stateless* checks on the message (like making sure parameters are correctly formatted) have already been performed. Checks performed in the `msgServer` method can be more expensive and require access to the state. For example, a `msgServer` method for a `transfer` message might check that the sending account has enough funds to actually perform the transfer. To access the state, the `msgServer` method needs to call the [`keeper`'s](./keeper.md) getter functions. +- Then, if the checks are successful, the `msgServer` method calls the [`keeper`'s](./keeper.md) setter functions to actually perform the state transition. + +Before returning, `msgServer` methods generally emit one or more [events](../core/events.md) via the `EventManager` held in the `ctx`: + +```go +ctx.EventManager().EmitEvent( + sdk.NewEvent( + eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module + sdk.NewAttribute(attributeKey, attributeValue), + ), + ) +``` + +These events are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../core/events.md) to learn more about events. + +The invoked `msgServer` method returns a `proto.Message` response and an `error`. These return values are then wrapped into an `*sdk.Result` or an `error` using `sdk.WrapServiceResult(ctx sdk.Context, res proto.Message, err error)`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/baseapp/msg_service_router.go#L104 + +This method takes care of marshaling the `res` parameter to protobuf and attaching any events on the `ctx.EventManager()` to the `sdk.Result`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/proto/cosmos/base/abci/v1beta1/abci.proto#L81-L95 + +## Legacy Amino `Msg`s + +### `handler` type + +The `handler` type defined in the Cosmos SDK will be deprecated in favor of [`Msg` Services](#implementation-of-a-module-msg-service). + +Here is the typical structure of a `handler` function: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/types/handler.go#L4 + +Let us break it down: + +- The [`Msg`](./messages-and-queries.md#messages) is the actual object being processed. +- The [`Context`](../core/context.md) contains all the necessary information needed to process the `msg`, as well as a cache-wrapped copy of the latest state. If the `msg` is succesfully processed, the modified version of the temporary state contained in the `ctx` will be written to the main state. +- The [`*Result`] returned to `BaseApp` contains (among other things) information on the execution of the `handler` and [events](../core/events.md). + +Module `handler`s are typically implemented in a `./handler.go` file inside the module's folder. The [module manager](./module-manager.md) is used to add the module's `handler`s to the +[application's `router`](../core/baseapp.md#message-routing) via the `Route()` method. Typically, +the manager's `Route()` method simply constructs a Route that calls a `NewHandler()` method defined in `handler.go`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/228728cce2af8d494c8b4e996d011492139b04ab/x/gov/module.go#L143-L146 + +### Implementation + +`NewHandler` function dispatches a `Msg` to appropriate handler function, usually by using a switch statement: + ++++ https://github.com/cosmos/cosmos-sdk/blob/d55c1a26657a0af937fa2273b38dcfa1bb3cff9f/x/bank/handler.go#L13-L29 + +First, `NewHandler` function sets a new `EventManager` to the context to isolate events per `msg`. +Then, a simple switch calls the appropriate `handler` based on the `Msg` type. + +In this regard, `handler`s functions need to be implemented for each module `Msg`. This will also involve manual handler registration of `Msg` types. +`handler`s functions should return a `*Result` and an `error`. + +## Telemetry + +New [telemetry metrics](../core/telemetry.md) can be created from `msgServer` methods when handling messages. + +This is an example from the `x/auth/vesting` module: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/auth/vesting/msg_server.go#L73-L85 + +## Next {hide} + +Learn about [query services](./query-services.md) {hide} diff --git a/docs/building-modules/query-services.md b/docs/building-modules/query-services.md index fa7a6e0bae..fb64a2e1aa 100644 --- a/docs/building-modules/query-services.md +++ b/docs/building-modules/query-services.md @@ -4,7 +4,7 @@ order: 5 # Query Services -A query service processes [`queries`](./messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `baseapp`'s [`Query` method](../core/baseapp.md#query). {synopsis} +A query service processes [`queries`](./messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `BaseApp`'s [`Query` method](../core/baseapp.md#query). {synopsis} ## Pre-requisite Readings @@ -22,7 +22,7 @@ Let us break it down: - The `path` is an array of `string`s that contains the type of the query, and that can also contain `query` arguments. See [`queries`](./messages-and-queries.md#queries) for more information. - The `req` itself is primarily used to retrieve arguments if they are too large to fit in the `path`. This is done using the `Data` field of `req`. - The [`Context`](../core/context.md) contains all the necessary information needed to process the `query`, as well as a cache-wrapped copy of the latest state. It is primarily used by the [`keeper`](./keeper.md) to access the state. -- The result `res` returned to `baseapp`, marshalled using the application's [`codec`](../core/encoding.md). +- The result `res` returned to `BaseApp`, marshalled using the application's [`codec`](../core/encoding.md). ## Implementation of a module query service diff --git a/docs/building-modules/structure.md b/docs/building-modules/structure.md index cdc2c6983c..79c353a2ce 100644 --- a/docs/building-modules/structure.md +++ b/docs/building-modules/structure.md @@ -25,6 +25,7 @@ x/{module} │   ├── invariants.go │   ├── genesis.go │   ├── keeper.go +│   ├── msg_server.go │   ├── ... │   └── querier.go │   └── grpc_query.go diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index c4ea2c9faf..0b9417cfe6 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -192,7 +192,7 @@ When messages and queries are received by the application, they must be routed t ### Message Routing -[`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a `router` which maps `paths` (`string`) to the appropriate module [`handler`](../building-modules/handler.md) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module. +[Messages](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a router which maps string paths to the appropriate module [handler](../building-modules/msg-services.md#handler-type) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module. The [default router included in baseapp](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into the `Route` function of the [Router interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/router.go#L12). For a stateless router that doesn't want to make use of this, can just ignore the ctx. @@ -285,7 +285,7 @@ Before the first transaction of a given block is processed, a [volatile state](# `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: 1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -2. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +2. For each message in the transaction, route to the appropriate module's [`handler`](../building-modules/msg-services.md#handler-type). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation: @@ -342,7 +342,7 @@ Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the message's `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/msg-services.md#handler-type) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages diff --git a/docs/core/events.md b/docs/core/events.md index f2407bcf2e..d7fe2b8e13 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -32,7 +32,7 @@ Events are returned to the underlying consensus engine in the response of the fo - [`DeliverTx`](./baseapp.md#delivertx) Events, the `type` and `attributes`, are defined on a **per-module basis** in the module's -`/types/events.go` file, and triggered from the module's [`handler`](../building-modules/handler.md) +`/types/events.go` file, and triggered from the module's [`Msg` service](../building-modules/msg-services.md) via the [`EventManager`](#eventmanager). In addition, each module documents its events under `spec/xx_events.md`. @@ -68,7 +68,7 @@ func NewHandler(keeper Keeper) sdk.Handler { switch msg := msg.(type) { ``` -See the [`Handler`](../building-modules/handler.md) concept doc for a more detailed +See the [`Msg` services](../building-modules/msg-services.md) concept doc for a more detailed view on how to typically implement `Events` and use the `EventManager` in modules. ## Subscribing to Events diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 507f47e6b1..8bd5ae17f4 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -12,7 +12,7 @@ order: 2 ## Transactions -Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md). +Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md). When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `message`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). @@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin ### Messages -**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the `message`s for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/handler.md) to process them. +**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/msg-services.md#handler-type) to process them. +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L8-L29 @@ -85,7 +85,7 @@ Every message in a transaction must be signed by the addresses specified by `Get ### Handlers -Since `message`s are module-specific types, each module needs a [`handler`](../building-modules/handler.md) to process all of its `message` types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/handler.md). +Since messages are module-specific types, each module needs a [`handler`](../building-modules/msg-services.md#handler-type) to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/msg-services.md#handler-type). ## Next {hide} diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 3cb8e71210..55ffad8a12 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -87,7 +87,7 @@ Note that **Tendermint only handles transaction bytes**. It has no knowledge of Here are the most important messages of the ABCI: - `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. A special handler called the [`AnteHandler`](../basics/gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. -- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`handler`s](../building-modules/handler.md) for each message in the transaction. +- `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again along with the actual [`Msg` service methods](../building-modules/msg-services.md) for each message in the transaction. - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. Find a more detailed view of the ABCI methods from the [Tendermint docs](https://tendermint.com/docs/spec/abci/abci.html#overview). diff --git a/types/module/module.go b/types/module/module.go index c58555a980..2379c93d5e 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -162,13 +162,13 @@ type AppModule interface { // registers RegisterInvariants(sdk.InvariantRegistry) - // routes + // Deprecated: use RegisterServices Route() sdk.Route - // Deprecated: use RegisterQueryService + // Deprecated: use RegisterServices QuerierRoute() string - // Deprecated: use RegisterQueryService + // Deprecated: use RegisterServices LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier // RegisterServices allows a module to register services diff --git a/x/auth/module.go b/x/auth/module.go index 0c6b1fa832..73aa9a1066 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -125,7 +125,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.accountKeeper, legacyQuerierCdc) } -// RegisterQueryService registers a GRPC query service to respond to the +// RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.accountKeeper) diff --git a/x/capability/module.go b/x/capability/module.go index f27e5cdb5d..7957f57747 100644 --- a/x/capability/module.go +++ b/x/capability/module.go @@ -111,7 +111,7 @@ func (AppModule) QuerierRoute() string { return "" } // LegacyQuerierHandler returns the capability module's Querier. func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -// RegisterQueryService registers a GRPC query service to respond to the +// RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(module.Configurator) {} diff --git a/x/ibc/testing/mock/mock.go b/x/ibc/testing/mock/mock.go index e338e24d3b..663497aa05 100644 --- a/x/ibc/testing/mock/mock.go +++ b/x/ibc/testing/mock/mock.go @@ -102,7 +102,7 @@ func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { return nil } -// RegisterQueryService implements the AppModule interface. +// RegisterServices implements the AppModule interface. func (am AppModule) RegisterServices(module.Configurator) {} // InitGenesis implements the AppModule interface. diff --git a/x/mint/module.go b/x/mint/module.go index a100139825..44e96ce74b 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -123,7 +123,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterQueryService registers a gRPC query service to respond to the +// RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) diff --git a/x/params/module.go b/x/params/module.go index 1460460317..b0a4584129 100644 --- a/x/params/module.go +++ b/x/params/module.go @@ -109,7 +109,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterQueryService registers a gRPC query service to respond to the +// RegisterServices registers a gRPC query service to respond to the // module-specific gRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { proposal.RegisterQueryServer(cfg.QueryServer(), am.keeper) diff --git a/x/upgrade/module.go b/x/upgrade/module.go index c136d9cf0a..4e4982a324 100644 --- a/x/upgrade/module.go +++ b/x/upgrade/module.go @@ -94,7 +94,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd return keeper.NewQuerier(am.keeper, legacyQuerierCdc) } -// RegisterQueryService registers a GRPC query service to respond to the +// RegisterServices registers a GRPC query service to respond to the // module-specific GRPC queries. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterQueryServer(cfg.QueryServer(), am.keeper) From f02a46263fe43ae6f7f496039c5fd9664dafc00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 18 Nov 2020 14:56:26 +0100 Subject: [PATCH 28/57] update transfer error messages (#7968) * update transfer err messages * apply @AdityaSripal review suggestion --- x/ibc/applications/transfer/keeper/relay.go | 27 +++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/x/ibc/applications/transfer/keeper/relay.go b/x/ibc/applications/transfer/keeper/relay.go index d26e71e984..1d0f5c2166 100644 --- a/x/ibc/applications/transfer/keeper/relay.go +++ b/x/ibc/applications/transfer/keeper/relay.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "strings" "github.com/armon/go-metrics" @@ -137,7 +138,7 @@ func (k Keeper) SendTransfer( // NOTE: should not happen as the module account was // retrieved on the step above and it has enough balace // to burn. - return err + panic(fmt.Sprintf("cannot burn coins after a successful send to a module account: %v", err)) } } @@ -222,7 +223,11 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t // unescrow tokens escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) if err := k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)); err != nil { - return err + // NOTE: this error is only expected to occur given an unexpected bug or a malicious + // counterparty module. The bug may occur in bank or any part of the code that allows + // the escrow address to be drained. A malicious counterparty module could drain the + // escrow address by allowing more tokens to be sent back then were escrowed. + return sdkerrors.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") } defer func() { @@ -281,7 +286,7 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t if err := k.bankKeeper.SendCoinsFromModuleToAccount( ctx, types.ModuleName, receiver, sdk.NewCoins(voucher), ); err != nil { - return err + panic(fmt.Sprintf("unable to send coins from module to account despite previously minting coins to module account: %v", err)) } defer func() { @@ -345,7 +350,15 @@ func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, d if types.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) { // unescrow tokens back to sender escrowAddress := types.GetEscrowAddress(packet.GetSourcePort(), packet.GetSourceChannel()) - return k.bankKeeper.SendCoins(ctx, escrowAddress, sender, sdk.NewCoins(token)) + if err := k.bankKeeper.SendCoins(ctx, escrowAddress, sender, sdk.NewCoins(token)); err != nil { + // NOTE: this error is only expected to occur given an unexpected bug or a malicious + // counterparty module. The bug may occur in bank or any part of the code that allows + // the escrow address to be drained. A malicious counterparty module could drain the + // escrow address by allowing more tokens to be sent back then were escrowed. + return sdkerrors.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") + } + + return nil } // mint vouchers back to sender @@ -355,7 +368,11 @@ func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, d return err } - return k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sender, sdk.NewCoins(token)) + if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sender, sdk.NewCoins(token)); err != nil { + panic(fmt.Sprintf("unable to send coins from module to account despite previously minting coins to module account: %v", err)) + } + + return nil } // DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash From 97d96612c9cf1c05475313a4b6fe5cffdfe34a23 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 18 Nov 2020 19:42:45 +0100 Subject: [PATCH 29/57] crypto/hd: add 'm/' prefix to hd path (#7970) * crypto/hd: add 'm/' prefix to hd path * update fundraiser path * fix some tests * tests * fix test case * changelog * fix ledger tests --- CHANGELOG.md | 4 + crypto/hd/fundraiser_test.go | 5 +- crypto/hd/hdpath.go | 50 +++++-- crypto/hd/hdpath_test.go | 187 ++++++++++++++------------ crypto/keyring/keyring_ledger_test.go | 4 +- crypto/keyring/types_test.go | 26 ++-- crypto/ledger/ledger_test.go | 24 ++-- types/address.go | 10 +- 8 files changed, 172 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46d8a76ef3..efca4d9bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Updated iavl dependency to v0.15-rc2 * (version) [\#7848](https://github.com/cosmos/cosmos-sdk/pull/7848) [\#7941](https://github.com/cosmos/cosmos-sdk/pull/7941) `version --long` output now shows the list of build dependencies and replaced build dependencies. +### Bug Fixes + +* (crypto) [\#7966](https://github.com/cosmos/cosmos-sdk/issues/7966) `Bip44Params` `String()` function now correctly returns the absolute HD path by adding the `m/` prefix. + ## [v0.40.0-rc3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.40.0-rc3) - 2020-11-06 ### Client Breaking diff --git a/crypto/hd/fundraiser_test.go b/crypto/hd/fundraiser_test.go index e8649a0086..4afbfc5a9c 100644 --- a/crypto/hd/fundraiser_test.go +++ b/crypto/hd/fundraiser_test.go @@ -27,7 +27,7 @@ type addrData struct { } func TestFullFundraiserPath(t *testing.T) { - require.Equal(t, "44'/118'/0'/0/0", hd.NewFundraiserParams(0, 118, 0).String()) + require.Equal(t, "m/44'/118'/0'/0/0", hd.NewFundraiserParams(0, 118, 0).String()) } func initFundraiserTestVectors(t *testing.T) []addrData { @@ -63,8 +63,9 @@ func TestFundraiserCompatibility(t *testing.T) { t.Logf("ROUND: %d MNEMONIC: %s", i, d.Mnemonic) master, ch := hd.ComputeMastersFromSeed(seed) - priv, err := hd.DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") + priv, err := hd.DerivePrivateKeyForPath(master, ch, "m/44'/118'/0'/0/0") require.NoError(t, err) + privKey := &secp256k1.PrivKey{Key: priv} pub := privKey.PubKey() diff --git a/crypto/hd/hdpath.go b/crypto/hd/hdpath.go index 67a02f0290..04469d7305 100644 --- a/crypto/hd/hdpath.go +++ b/crypto/hd/hdpath.go @@ -36,52 +36,66 @@ func NewParams(purpose, coinType, account uint32, change bool, addressIdx uint32 } } -// Parse the BIP44 path and unmarshal into the struct. +// NewParamsFromPath parses the BIP44 path and unmarshals it into a Bip44Params. It supports both +// absolute and relative paths. func NewParamsFromPath(path string) (*BIP44Params, error) { spl := strings.Split(path, "/") + + // Handle absolute or relative paths + switch { + case spl[0] == path: + return nil, fmt.Errorf("path %s doesn't contain '/' separators", path) + + case strings.TrimSpace(spl[0]) == "": + return nil, fmt.Errorf("ambiguous path %s: use 'm/' prefix for absolute paths, or no leading '/' for relative ones", path) + + case strings.TrimSpace(spl[0]) == "m": + spl = spl[1:] + } + if len(spl) != 5 { - return nil, fmt.Errorf("path length is wrong. Expected 5, got %d", len(spl)) + return nil, fmt.Errorf("invalid path length %s", path) } // Check items can be parsed purpose, err := hardenedInt(spl[0]) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid HD path purpose %s: %w", spl[0], err) } coinType, err := hardenedInt(spl[1]) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid HD path coin type %s: %w", spl[1], err) } account, err := hardenedInt(spl[2]) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid HD path account %s: %w", spl[2], err) } change, err := hardenedInt(spl[3]) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid HD path change %s: %w", spl[3], err) } addressIdx, err := hardenedInt(spl[4]) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid HD path address index %s: %w", spl[4], err) } // Confirm valid values if spl[0] != "44'" { - return nil, fmt.Errorf("first field in path must be 44', got %v", spl[0]) + return nil, fmt.Errorf("first field in path must be 44', got %s", spl[0]) } if !isHardened(spl[1]) || !isHardened(spl[2]) { return nil, - fmt.Errorf("second and third field in path must be hardened (ie. contain the suffix ', got %v and %v", spl[1], spl[2]) + fmt.Errorf("second and third field in path must be hardened (ie. contain the suffix ', got %s and %s", spl[1], spl[2]) } if isHardened(spl[3]) || isHardened(spl[4]) { return nil, - fmt.Errorf("fourth and fifth field in path must not be hardened (ie. not contain the suffix ', got %v and %v", spl[3], spl[4]) + fmt.Errorf("fourth and fifth field in path must not be hardened (ie. not contain the suffix ', got %s and %s", spl[3], spl[4]) } if !(change == 0 || change == 1) { @@ -135,6 +149,8 @@ func (p BIP44Params) DerivationPath() []uint32 { } } +// String returns the full absolute HD path of the BIP44 (https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) params: +// m / purpose' / coin_type' / account' / change / address_index func (p BIP44Params) String() string { var changeStr string if p.Change { @@ -142,8 +158,7 @@ func (p BIP44Params) String() string { } else { changeStr = "0" } - // m / Purpose' / coin_type' / Account' / Change / address_index - return fmt.Sprintf("%d'/%d'/%d'/%s/%d", + return fmt.Sprintf("m/%d'/%d'/%d'/%s/%d", p.Purpose, p.CoinType, p.Account, @@ -165,6 +180,13 @@ func DerivePrivateKeyForPath(privKeyBytes, chainCode [32]byte, path string) ([]b data := privKeyBytes parts := strings.Split(path, "/") + switch { + case parts[0] == path: + return nil, fmt.Errorf("path '%s' doesn't contain '/' separators", path) + case strings.TrimSpace(parts[0]) == "m": + parts = parts[1:] + } + for _, part := range parts { // do we have an apostrophe? harden := part[len(part)-1:] == "'" @@ -178,7 +200,7 @@ func DerivePrivateKeyForPath(privKeyBytes, chainCode [32]byte, path string) ([]b // index values are in the range [0, 1<<31-1] aka [0, max(int32)] idx, err := strconv.ParseUint(part, 10, 31) if err != nil { - return []byte{}, fmt.Errorf("invalid BIP 32 path: %s", err) + return []byte{}, fmt.Errorf("invalid BIP 32 path %s: %w", path, err) } data, chainCode = derivePrivateKey(data, chainCode, uint32(idx), harden) @@ -188,7 +210,7 @@ func DerivePrivateKeyForPath(privKeyBytes, chainCode [32]byte, path string) ([]b n := copy(derivedKey, data[:]) if n != 32 || len(data) != 32 { - return []byte{}, fmt.Errorf("expected a (secp256k1) key of length 32, got length: %v", len(data)) + return []byte{}, fmt.Errorf("expected a key of length 32, got length: %d", len(data)) } return derivedKey, nil diff --git a/crypto/hd/hdpath_test.go b/crypto/hd/hdpath_test.go index 42622b9a9c..2620e0605c 100644 --- a/crypto/hd/hdpath_test.go +++ b/crypto/hd/hdpath_test.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/types" bip39 "github.com/cosmos/go-bip39" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -20,26 +19,22 @@ func mnemonicToSeed(mnemonic string) []byte { return bip39.NewSeed(mnemonic, defaultBIP39Passphrase) } -// nolint:govet -func ExampleStringifyPathParams() { +func TestPathParamsString(t *testing.T) { path := hd.NewParams(44, 0, 0, false, 0) - fmt.Println(path.String()) + require.Equal(t, "m/44'/0'/0'/0/0", path.String()) path = hd.NewParams(44, 33, 7, true, 9) - fmt.Println(path.String()) - // Output: - // 44'/0'/0'/0/0 - // 44'/33'/7'/1/9 + require.Equal(t, "m/44'/33'/7'/1/9", path.String()) } func TestStringifyFundraiserPathParams(t *testing.T) { path := hd.NewFundraiserParams(4, types.CoinType, 22) - require.Equal(t, "44'/118'/4'/0/22", path.String()) + require.Equal(t, "m/44'/118'/4'/0/22", path.String()) path = hd.NewFundraiserParams(4, types.CoinType, 57) - require.Equal(t, "44'/118'/4'/0/57", path.String()) + require.Equal(t, "m/44'/118'/4'/0/57", path.String()) path = hd.NewFundraiserParams(4, 12345, 57) - require.Equal(t, "44'/12345'/4'/0/57", path.String()) + require.Equal(t, "m/44'/12345'/4'/0/57", path.String()) } func TestPathToArray(t *testing.T) { @@ -55,95 +50,101 @@ func TestParamsFromPath(t *testing.T) { params *hd.BIP44Params path string }{ - {&hd.BIP44Params{44, 0, 0, false, 0}, "44'/0'/0'/0/0"}, - {&hd.BIP44Params{44, 1, 0, false, 0}, "44'/1'/0'/0/0"}, - {&hd.BIP44Params{44, 0, 1, false, 0}, "44'/0'/1'/0/0"}, - {&hd.BIP44Params{44, 0, 0, true, 0}, "44'/0'/0'/1/0"}, - {&hd.BIP44Params{44, 0, 0, false, 1}, "44'/0'/0'/0/1"}, - {&hd.BIP44Params{44, 1, 1, true, 1}, "44'/1'/1'/1/1"}, - {&hd.BIP44Params{44, 118, 52, true, 41}, "44'/118'/52'/1/41"}, + {&hd.BIP44Params{44, 0, 0, false, 0}, "m/44'/0'/0'/0/0"}, + {&hd.BIP44Params{44, 1, 0, false, 0}, "m/44'/1'/0'/0/0"}, + {&hd.BIP44Params{44, 0, 1, false, 0}, "m/44'/0'/1'/0/0"}, + {&hd.BIP44Params{44, 0, 0, true, 0}, "m/44'/0'/0'/1/0"}, + {&hd.BIP44Params{44, 0, 0, false, 1}, "m/44'/0'/0'/0/1"}, + {&hd.BIP44Params{44, 1, 1, true, 1}, "m/44'/1'/1'/1/1"}, + {&hd.BIP44Params{44, 118, 52, true, 41}, "m/44'/118'/52'/1/41"}, } for i, c := range goodCases { params, err := hd.NewParamsFromPath(c.path) errStr := fmt.Sprintf("%d %v", i, c) - assert.NoError(t, err, errStr) - assert.EqualValues(t, c.params, params, errStr) - assert.Equal(t, c.path, c.params.String()) + require.NoError(t, err, errStr) + require.EqualValues(t, c.params, params, errStr) + require.Equal(t, c.path, c.params.String()) } badCases := []struct { path string }{ - {"43'/0'/0'/0/0"}, // doesnt start with 44 - {"44'/1'/0'/0/0/5"}, // too many fields - {"44'/0'/1'/0"}, // too few fields - {"44'/0'/0'/2/0"}, // change field can only be 0/1 - {"44/0'/0'/0/0"}, // first field needs ' - {"44'/0/0'/0/0"}, // second field needs ' - {"44'/0'/0/0/0"}, // third field needs ' - {"44'/0'/0'/0'/0"}, // fourth field must not have ' - {"44'/0'/0'/0/0'"}, // fifth field must not have ' - {"44'/-1'/0'/0/0"}, // no negatives - {"44'/0'/0'/-1/0"}, // no negatives - {"a'/0'/0'/-1/0"}, // valid values - {"0/X/0'/-1/0"}, // valid values - {"44'/0'/X/-1/0"}, // valid values - {"44'/0'/0'/%/0"}, // valid values - {"44'/0'/0'/0/%"}, // valid values + {"m/43'/0'/0'/0/0"}, // doesn't start with 44 + {"m/44'/1'/0'/0/0/5"}, // too many fields + {"m/44'/0'/1'/0"}, // too few fields + {"m/44'/0'/0'/2/0"}, // change field can only be 0/1 + {"m/44/0'/0'/0/0"}, // first field needs ' + {"m/44'/0/0'/0/0"}, // second field needs ' + {"m/44'/0'/0/0/0"}, // third field needs ' + {"m/44'/0'/0'/0'/0"}, // fourth field must not have ' + {"m/44'/0'/0'/0/0'"}, // fifth field must not have ' + {"m/44'/-1'/0'/0/0"}, // no negatives + {"m/44'/0'/0'/-1/0"}, // no negatives + {"m/a'/0'/0'/-1/0"}, // invalid values + {"m/0/X/0'/-1/0"}, // invalid values + {"m/44'/0'/X/-1/0"}, // invalid values + {"m/44'/0'/0'/%/0"}, // invalid values + {"m/44'/0'/0'/0/%"}, // invalid values + {"m44'0'0'00"}, // no separators + {" /44'/0'/0'/0/0"}, // blank first component } for i, c := range badCases { params, err := hd.NewParamsFromPath(c.path) errStr := fmt.Sprintf("%d %v", i, c) - assert.Nil(t, params, errStr) - assert.Error(t, err, errStr) + require.Nil(t, params, errStr) + require.Error(t, err, errStr) } } -// nolint:govet -func ExampleSomeBIP32TestVecs() { +func TestBIP32Vecs(t *testing.T) { seed := mnemonicToSeed("barrel original fuel morning among eternal " + "filter ball stove pluck matrix mechanic") master, ch := hd.ComputeMastersFromSeed(seed) fmt.Println("keys from fundraiser test-vector (cosmos, bitcoin, ether)") fmt.Println() - // cosmos + + // cosmos, absolute path priv, err := hd.DerivePrivateKeyForPath(master, ch, types.FullFundraiserPath) - if err != nil { - fmt.Println("INVALID") - } else { - fmt.Println(hex.EncodeToString(priv[:])) - } + require.NoError(t, err) + require.NotEmpty(t, priv) + fmt.Println(hex.EncodeToString(priv[:])) + + absPrivKey := hex.EncodeToString(priv[:]) + + // cosmos, relative path + priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") + require.NoError(t, err) + require.NotEmpty(t, priv) + + relPrivKey := hex.EncodeToString(priv[:]) + + // check compatibility between relative and absolute HD paths + require.Equal(t, relPrivKey, absPrivKey) + // bitcoin - priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/0") - if err != nil { - fmt.Println("INVALID") - } else { - fmt.Println(hex.EncodeToString(priv[:])) - } + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/0'/0'/0/0") + require.NoError(t, err) + require.NotEmpty(t, priv) + fmt.Println(hex.EncodeToString(priv[:])) + // ether - priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/60'/0'/0/0") - if err != nil { - fmt.Println("INVALID") - } else { - fmt.Println(hex.EncodeToString(priv[:])) - } + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/60'/0'/0/0") + require.NoError(t, err) + require.NotEmpty(t, priv) + fmt.Println(hex.EncodeToString(priv[:])) + // INVALID - priv, err = hd.DerivePrivateKeyForPath(master, ch, "X/0'/0'/0/0") - if err != nil { - fmt.Println("INVALID") - } else { - fmt.Println(hex.EncodeToString(priv[:])) - } - priv, err = hd.DerivePrivateKeyForPath(master, ch, "-44/0'/0'/0/0") - if err != nil { - fmt.Println("INVALID") - } else { - fmt.Println(hex.EncodeToString(priv[:])) - } + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/X/0'/0'/0/0") + require.Error(t, err) + require.Empty(t, priv) + + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/-44/0'/0'/0/0") + require.Error(t, err) + require.Empty(t, priv) fmt.Println() fmt.Println("keys generated via https://coinomi.com/recovery-phrase-tool.html") @@ -153,13 +154,14 @@ func ExampleSomeBIP32TestVecs() { "advice process birth april short trust crater change bacon monkey medal garment " + "gorilla ranch hour rival razor call lunar mention taste vacant woman sister") master, ch = hd.ComputeMastersFromSeed(seed) - priv, _ = hd.DerivePrivateKeyForPath(master, ch, "44'/1'/1'/0/4") + priv, _ = hd.DerivePrivateKeyForPath(master, ch, "m/44'/1'/1'/0/4") fmt.Println(hex.EncodeToString(priv[:])) seed = mnemonicToSeed("idea naive region square margin day captain habit " + "gun second farm pact pulse someone armed") master, ch = hd.ComputeMastersFromSeed(seed) - priv, _ = hd.DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/420") + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/0'/0'/0/420") + require.NoError(t, err) fmt.Println(hex.EncodeToString(priv[:])) fmt.Println() @@ -169,7 +171,8 @@ func ExampleSomeBIP32TestVecs() { // bip32 path: m/0/7 seed = mnemonicToSeed("monitor flock loyal sick object grunt duty ride develop assault harsh history") master, ch = hd.ComputeMastersFromSeed(seed) - priv, _ = hd.DerivePrivateKeyForPath(master, ch, "0/7") + priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/0/7") + require.NoError(t, err) // TODO: shouldn't this error? fmt.Println(hex.EncodeToString(priv[:])) // Output: keys from fundraiser test-vector (cosmos, bitcoin, ether) @@ -177,8 +180,6 @@ func ExampleSomeBIP32TestVecs() { // bfcb217c058d8bbafd5e186eae936106ca3e943889b0b4a093ae13822fd3170c // e77c3de76965ad89997451de97b95bb65ede23a6bf185a55d80363d92ee37c3d // 7fc4d8a8146dea344ba04c593517d3f377fa6cded36cd55aee0a0bb968e651bc - // INVALID - // INVALID // // keys generated via https://coinomi.com/recovery-phrase-tool.html // @@ -201,9 +202,9 @@ func TestCreateHDPath(t *testing.T) { args args want hd.BIP44Params }{ - {"44'/0'/0'/0/0", args{0, 0, 0}, hd.BIP44Params{Purpose: 44}}, - {"44'/114'/0'/0/0", args{114, 0, 0}, hd.BIP44Params{Purpose: 44, CoinType: 114, Account: 0, AddressIndex: 0}}, - {"44'/114'/1'/1/0", args{114, 1, 1}, hd.BIP44Params{Purpose: 44, CoinType: 114, Account: 1, AddressIndex: 1}}, + {"m/44'/0'/0'/0/0", args{0, 0, 0}, hd.BIP44Params{Purpose: 44}}, + {"m/44'/114'/0'/0/0", args{114, 0, 0}, hd.BIP44Params{Purpose: 44, CoinType: 114, Account: 0, AddressIndex: 0}}, + {"m/44'/114'/1'/1/0", args{114, 1, 1}, hd.BIP44Params{Purpose: 44, CoinType: 114, Account: 1, AddressIndex: 1}}, } for _, tt := range tests { tt := tt @@ -227,36 +228,44 @@ func TestDeriveHDPathRange(t *testing.T) { wantErr string }{ { - path: "1'/2147483648/0'/0/0", + path: "m/1'/2147483648/0'/0/0", wantErr: "out of range", }, { - path: "2147483648'/1/0/0", + path: "m/2147483648'/1/0/0", wantErr: "out of range", }, { - path: "2147483648'/2147483648/0'/0/0", + path: "m/2147483648'/2147483648/0'/0/0", wantErr: "out of range", }, { - path: "1'/-5/0'/0/0", + path: "m/1'/-5/0'/0/0", wantErr: "invalid syntax", }, { - path: "-2147483646'/1/0/0", + path: "m/-2147483646'/1/0/0", wantErr: "invalid syntax", }, { - path: "-2147483648'/-2147483648/0'/0/0", + path: "m/-2147483648'/-2147483648/0'/0/0", wantErr: "invalid syntax", }, + { + path: "m44'118'0'00", + wantErr: "path 'm44'118'0'00' doesn't contain '/' separators", + }, + { + path: "", + wantErr: "path '' doesn't contain '/' separators", + }, { // Should pass. - path: "1'/2147483647/0'/0/0", + path: "m/1'/2147483647'/1/0'/0/0", }, { // Should pass. - path: "2147483647'/1/0'/0/0", + path: "1'/2147483647'/1/0'/0/0", }, } @@ -267,9 +276,9 @@ func TestDeriveHDPathRange(t *testing.T) { _, err := hd.DerivePrivateKeyForPath(master, ch, tt.path) if tt.wantErr == "" { - require.Nil(t, err, "unexpected error") + require.NoError(t, err, "unexpected error") } else { - require.NotNil(t, err, "expected a report of an int overflow") + require.Error(t, err, "expected a report of an int overflow") require.Contains(t, err.Error(), tt.wantErr) } }) diff --git a/crypto/keyring/keyring_ledger_test.go b/crypto/keyring/keyring_ledger_test.go index 275e3edd57..eb7e85f9e8 100644 --- a/crypto/keyring/keyring_ledger_test.go +++ b/crypto/keyring/keyring_ledger_test.go @@ -45,7 +45,7 @@ func TestInMemoryCreateLedger(t *testing.T) { path, err := restoredKey.GetPath() require.NoError(t, err) - require.Equal(t, "44'/118'/3'/0/1", path.String()) + require.Equal(t, "m/44'/118'/3'/0/1", path.String()) } // TestSignVerify does some detailed checks on how we sign and validate @@ -123,5 +123,5 @@ func TestAltKeyring_SaveLedgerKey(t *testing.T) { path, err := restoredKey.GetPath() require.NoError(t, err) - require.Equal(t, "44'/118'/3'/0/1", path.String()) + require.Equal(t, "m/44'/118'/3'/0/1", path.String()) } diff --git a/crypto/keyring/types_test.go b/crypto/keyring/types_test.go index ca99d9b7c5..8c68bce670 100644 --- a/crypto/keyring/types_test.go +++ b/crypto/keyring/types_test.go @@ -4,11 +4,10 @@ import ( "encoding/hex" "testing" - "github.com/stretchr/testify/assert" - "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" ) func Test_writeReadLedgerInfo(t *testing.T) { @@ -17,28 +16,27 @@ func Test_writeReadLedgerInfo(t *testing.T) { copy(tmpKey[:], bz) lInfo := newLedgerInfo("some_name", &secp256k1.PubKey{Key: tmpKey}, *hd.NewFundraiserParams(5, sdk.CoinType, 1), hd.Secp256k1Type) - assert.Equal(t, TypeLedger, lInfo.GetType()) + require.Equal(t, TypeLedger, lInfo.GetType()) path, err := lInfo.GetPath() - assert.NoError(t, err) - assert.Equal(t, "44'/118'/5'/0/1", path.String()) - assert.Equal(t, + require.NoError(t, err) + require.Equal(t, "m/44'/118'/5'/0/1", path.String()) + require.Equal(t, "cosmospub1addwnpepqddddqg2glc8x4fl7vxjlnr7p5a3czm5kcdp4239sg6yqdc4rc2r5wmxv8p", sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, lInfo.GetPubKey())) // Serialize and restore serialized := marshalInfo(lInfo) restoredInfo, err := unmarshalInfo(serialized) - assert.NoError(t, err) - assert.NotNil(t, restoredInfo) + require.NoError(t, err) + require.NotNil(t, restoredInfo) // Check both keys match - assert.Equal(t, lInfo.GetName(), restoredInfo.GetName()) - assert.Equal(t, lInfo.GetType(), restoredInfo.GetType()) - assert.Equal(t, lInfo.GetPubKey(), restoredInfo.GetPubKey()) + require.Equal(t, lInfo.GetName(), restoredInfo.GetName()) + require.Equal(t, lInfo.GetType(), restoredInfo.GetType()) + require.Equal(t, lInfo.GetPubKey(), restoredInfo.GetPubKey()) restoredPath, err := restoredInfo.GetPath() - assert.NoError(t, err) - - assert.Equal(t, path, restoredPath) + require.NoError(t, err) + require.Equal(t, path, restoredPath) } diff --git a/crypto/ledger/ledger_test.go b/crypto/ledger/ledger_test.go index bc85b2feba..5fe9da8f55 100644 --- a/crypto/ledger/ledger_test.go +++ b/crypto/ledger/ledger_test.go @@ -24,7 +24,7 @@ func TestErrorHandling(t *testing.T) { func TestPublicKeyUnsafe(t *testing.T) { path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, err := NewPrivKeySecp256k1Unsafe(path) - require.Nil(t, err, "%s", err) + require.NoError(t, err) require.NotNil(t, priv) require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", @@ -62,10 +62,10 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { // Check with device for i := uint32(0); i < 10; i++ { path := *hd.NewFundraiserParams(0, sdk.CoinType, i) - fmt.Printf("Checking keys at %v\n", path) + t.Logf("Checking keys at %v\n", path) priv, err := NewPrivKeySecp256k1Unsafe(path) - require.Nil(t, err, "%s", err) + require.NoError(t, err) require.NotNil(t, priv) // Check other methods @@ -100,7 +100,7 @@ func TestPublicKeySafe(t *testing.T) { path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") - require.Nil(t, err, "%s", err) + require.NoError(t, err) require.NotNil(t, priv) require.Nil(t, ShowAddress(path, priv.PubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix())) @@ -155,10 +155,10 @@ func TestPublicKeyHDPath(t *testing.T) { // Check with device for i := uint32(0); i < 10; i++ { path := *hd.NewFundraiserParams(0, sdk.CoinType, i) - fmt.Printf("Checking keys at %v\n", path) + t.Logf("Checking keys at %s\n", path) priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") - require.Nil(t, err, "%s", err) + require.NoError(t, err) require.NotNil(t, addr) require.NotNil(t, priv) @@ -209,14 +209,14 @@ func TestSignaturesHD(t *testing.T) { msg := getFakeTx(account) path := *hd.NewFundraiserParams(account, sdk.CoinType, account/5) - fmt.Printf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path) + t.Logf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path) priv, err := NewPrivKeySecp256k1Unsafe(path) - require.Nil(t, err, "%s", err) + require.NoError(t, err) pub := priv.PubKey() sig, err := priv.Sign(msg) - require.Nil(t, err) + require.NoError(t, err) valid := pub.VerifySignature(msg, sig) require.True(t, valid, "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) @@ -227,11 +227,11 @@ func TestRealDeviceSecp256k1(t *testing.T) { msg := getFakeTx(50) path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, err := NewPrivKeySecp256k1Unsafe(path) - require.Nil(t, err, "%s", err) + require.NoError(t, err) pub := priv.PubKey() sig, err := priv.Sign(msg) - require.Nil(t, err) + require.NoError(t, err) valid := pub.VerifySignature(msg, sig) require.True(t, valid) @@ -246,7 +246,7 @@ func TestRealDeviceSecp256k1(t *testing.T) { // signing with the loaded key should match the original pubkey sig, err = priv.Sign(msg) - require.Nil(t, err) + require.NoError(t, err) valid = pub.VerifySignature(msg, sig) require.True(t, valid) diff --git a/types/address.go b/types/address.go index a6d65e7a70..7e0408a849 100644 --- a/types/address.go +++ b/types/address.go @@ -31,15 +31,15 @@ const ( // AddrLen defines a valid address length AddrLen = 20 - // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address + // Bech32MainPrefix defines the main SDK Bech32 prefix of an account's address Bech32MainPrefix = "cosmos" - // Atom in https://github.com/satoshilabs/slips/blob/master/slip-0044.md + // CoinType is the ATOM coin type as defined in SLIP44 (https://github.com/satoshilabs/slips/blob/master/slip-0044.md) CoinType = 118 - // BIP44Prefix is the parts of the BIP44 HD path that are fixed by - // what we used during the fundraiser. - FullFundraiserPath = "44'/118'/0'/0/0" + // FullFundraiserPath is the parts of the BIP44 HD path that are fixed by + // what we used during the ATOM fundraiser. + FullFundraiserPath = "m/44'/118'/0'/0/0" // PrefixAccount is the prefix for account keys PrefixAccount = "acc" From 87315a6aabc0485268dde9d7f93ce64a78bf3a41 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Wed, 18 Nov 2020 20:01:22 +0100 Subject: [PATCH 30/57] ibc: commit packet and hash (#7808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ibc: commit packet and hash * minor changes * fix build * update err msgs * don't use Any * update commitment hash to used fixed length preimage The commitment hash will now use 8 bytes timeout timestamp + 8 bytes timeout height version number + 8 bytes timeout height version height + sha 256 hash of data * remove error from CommitPacket return values * update godoc * rm proto-tools-stamp Co-authored-by: Colin Axner Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- x/ibc/applications/transfer/types/trace.go | 5 +-- x/ibc/core/02-client/types/codec.go | 3 -- .../core/03-connection/keeper/verify_test.go | 3 +- x/ibc/core/04-channel/keeper/packet.go | 14 +++++--- x/ibc/core/04-channel/keeper/timeout.go | 12 ++++--- x/ibc/core/04-channel/types/packet.go | 32 +++++++++++++------ x/ibc/core/04-channel/types/packet_test.go | 16 ++++++++++ .../07-tendermint/types/client_state_test.go | 31 +++++++++--------- 8 files changed, 78 insertions(+), 38 deletions(-) diff --git a/x/ibc/applications/transfer/types/trace.go b/x/ibc/applications/transfer/types/trace.go index b4527d668f..f45113efa3 100644 --- a/x/ibc/applications/transfer/types/trace.go +++ b/x/ibc/applications/transfer/types/trace.go @@ -1,12 +1,12 @@ package types import ( + "crypto/sha256" "encoding/hex" "fmt" "sort" "strings" - "github.com/tendermint/tendermint/crypto/tmhash" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtypes "github.com/tendermint/tendermint/types" @@ -42,7 +42,8 @@ func ParseDenomTrace(rawDenom string) DenomTrace { // // hash = sha256(tracePath + "/" + baseDenom) func (dt DenomTrace) Hash() tmbytes.HexBytes { - return tmhash.Sum([]byte(dt.GetFullDenomPath())) + hash := sha256.Sum256([]byte(dt.GetFullDenomPath())) + return hash[:] } // GetPrefix returns the receiving denomination prefix composed by the trace info and a separator. diff --git a/x/ibc/core/02-client/types/codec.go b/x/ibc/core/02-client/types/codec.go index d3cb8f7a5f..64b2a3a4f1 100644 --- a/x/ibc/core/02-client/types/codec.go +++ b/x/ibc/core/02-client/types/codec.go @@ -27,9 +27,6 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterInterface( "ibc.core.client.v1.Height", (*exported.Height)(nil), - ) - registry.RegisterImplementations( - (*exported.Height)(nil), &Height{}, ) registry.RegisterInterface( diff --git a/x/ibc/core/03-connection/keeper/verify_test.go b/x/ibc/core/03-connection/keeper/verify_test.go index ace373e12a..3b047e741a 100644 --- a/x/ibc/core/03-connection/keeper/verify_test.go +++ b/x/ibc/core/03-connection/keeper/verify_test.go @@ -289,9 +289,10 @@ func (suite *KeeperTestSuite) TestVerifyPacketCommitment() { packet.Data = []byte(ibctesting.InvalidID) } + commitment := channeltypes.CommitPacket(suite.chainB.App.IBCKeeper.Codec(), packet) err = suite.chainB.App.IBCKeeper.ConnectionKeeper.VerifyPacketCommitment( suite.chainB.GetContext(), connection, malleateHeight(proofHeight, tc.heightDiff), proof, - packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), channeltypes.CommitPacket(packet), + packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment, ) if tc.expPass { diff --git a/x/ibc/core/04-channel/keeper/packet.go b/x/ibc/core/04-channel/keeper/packet.go index e86887eee9..9af59745d5 100644 --- a/x/ibc/core/04-channel/keeper/packet.go +++ b/x/ibc/core/04-channel/keeper/packet.go @@ -109,9 +109,11 @@ func (k Keeper) SendPacket( ) } + commitment := types.CommitPacket(k.cdc, packet) + nextSequenceSend++ k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend) - k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), types.CommitPacket(packet)) + k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment) // Emit Event with Packet data along with other packet information for relayer to pick up // and relay to other chain @@ -216,11 +218,13 @@ func (k Keeper) RecvPacket( ) } + commitment := types.CommitPacket(k.cdc, packet) + // verify that the counterparty did commit to sending this packet if err := k.connectionKeeper.VerifyPacketCommitment( ctx, connectionEnd, proofHeight, proof, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), - types.CommitPacket(packet), + commitment, ); err != nil { return sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment") } @@ -443,9 +447,11 @@ func (k Keeper) AcknowledgePacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + packetCommitment := types.CommitPacket(k.cdc, packet) + // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet)) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "commitment bytes are not equal: got (%v), expected (%v)", types.CommitPacket(packet), commitment) + if !bytes.Equal(commitment, packetCommitment) { + return sdkerrors.Wrapf(types.ErrInvalidPacket, "commitment bytes are not equal: got (%v), expected (%v)", packetCommitment, commitment) } if err := k.connectionKeeper.VerifyPacketAcknowledgement( diff --git a/x/ibc/core/04-channel/keeper/timeout.go b/x/ibc/core/04-channel/keeper/timeout.go index 490eb83c8f..1f3dac918f 100644 --- a/x/ibc/core/04-channel/keeper/timeout.go +++ b/x/ibc/core/04-channel/keeper/timeout.go @@ -80,9 +80,11 @@ func (k Keeper) TimeoutPacket( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + packetCommitment := types.CommitPacket(k.cdc, packet) + // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet)) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, types.CommitPacket(packet)) + if !bytes.Equal(commitment, packetCommitment) { + return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) } switch channel.Ordering { @@ -216,9 +218,11 @@ func (k Keeper) TimeoutOnClose( commitment := k.GetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + packetCommitment := types.CommitPacket(k.cdc, packet) + // verify we sent the packet and haven't cleared it out yet - if !bytes.Equal(commitment, types.CommitPacket(packet)) { - return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, types.CommitPacket(packet)) + if !bytes.Equal(commitment, packetCommitment) { + return sdkerrors.Wrapf(types.ErrInvalidPacket, "packet commitment bytes are not equal: got (%v), expected (%v)", commitment, packetCommitment) } counterpartyHops, found := k.CounterpartyHops(ctx, channel) diff --git a/x/ibc/core/04-channel/types/packet.go b/x/ibc/core/04-channel/types/packet.go index 46c1a1f06e..18a3690b1e 100644 --- a/x/ibc/core/04-channel/types/packet.go +++ b/x/ibc/core/04-channel/types/packet.go @@ -1,8 +1,9 @@ package types import ( - "github.com/tendermint/tendermint/crypto/tmhash" + "crypto/sha256" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" @@ -10,19 +11,32 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ) -// CommitPacket returns a packet commitment bytes. The commitment consists of: -// hash(timeout_timestamp + timeout_version_number + timeout_version_height + data) from a given packet. -func CommitPacket(packet exported.PacketI) []byte { +// CommitPacket returns the packet commitment bytes. The commitment consists of: +// sha256_hash(timeout_timestamp + timeout_height.VersionNumber + timeout_height.VersionHeight + sha256_hash(data)) +// from a given packet. This results in a fixed length preimage. +// NOTE: sdk.Uint64ToBigEndian sets the uint64 to a slice of length 8. +func CommitPacket(cdc codec.BinaryMarshaler, packet exported.PacketI) []byte { + timeoutHeight := packet.GetTimeoutHeight() + buf := sdk.Uint64ToBigEndian(packet.GetTimeoutTimestamp()) - buf = append(buf, sdk.Uint64ToBigEndian(packet.GetTimeoutHeight().GetVersionNumber())...) - buf = append(buf, sdk.Uint64ToBigEndian(packet.GetTimeoutHeight().GetVersionHeight())...) - buf = append(buf, packet.GetData()...) - return tmhash.Sum(buf) + + versionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionNumber()) + buf = append(buf, versionNumber...) + + versionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionHeight()) + buf = append(buf, versionHeight...) + + dataHash := sha256.Sum256(packet.GetData()) + buf = append(buf, dataHash[:]...) + + hash := sha256.Sum256(buf) + return hash[:] } // CommitAcknowledgement returns the hash of commitment bytes func CommitAcknowledgement(data []byte) []byte { - return tmhash.Sum(data) + hash := sha256.Sum256(data) + return hash[:] } var _ exported.PacketI = (*Packet)(nil) diff --git a/x/ibc/core/04-channel/types/packet_test.go b/x/ibc/core/04-channel/types/packet_test.go index 114352f5c9..12ed828e66 100644 --- a/x/ibc/core/04-channel/types/packet_test.go +++ b/x/ibc/core/04-channel/types/packet_test.go @@ -5,9 +5,25 @@ import ( "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" ) +func TestCommitPacket(t *testing.T) { + packet := types.NewPacket(validPacketData, 1, portid, chanid, cpportid, cpchanid, timeoutHeight, timeoutTimestamp) + + registry := codectypes.NewInterfaceRegistry() + clienttypes.RegisterInterfaces(registry) + types.RegisterInterfaces(registry) + + cdc := codec.NewProtoCodec(registry) + + commitment := types.CommitPacket(cdc, &packet) + require.NotNil(t, commitment) +} + func TestPacketValidateBasic(t *testing.T) { testCases := []struct { packet types.Packet diff --git a/x/ibc/light-clients/07-tendermint/types/client_state_test.go b/x/ibc/light-clients/07-tendermint/types/client_state_test.go index a160484609..71f9f3fc3b 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state_test.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state_test.go @@ -33,57 +33,57 @@ func (suite *TendermintTestSuite) TestValidate() { }{ { name: "valid client", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: true, }, { name: "valid client with nil upgrade path", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), "", false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), "", false, false), expPass: true, }, { name: "invalid chainID", - clientState: types.NewClientState(" ", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(" ", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "invalid trust level", - clientState: types.NewClientState(chainID, types.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.Fraction{Numerator: 0, Denominator: 1}, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "invalid trusting period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, 0, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "invalid unbonding period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, 0, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "invalid max clock drift", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, 0, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "invalid height", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "trusting period not less than unbonding period", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), expPass: false, }, { name: "proof specs is nil", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, nil, upgradePath, false, false), expPass: false, }, { name: "proof specs contains nil", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, ubdPeriod, ubdPeriod, maxClockDrift, height, []*ics23.ProofSpec{ics23.TendermintSpec, nil}, upgradePath, false, false), expPass: false, }, } @@ -119,7 +119,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { // }, { name: "ApplyPrefix failed", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), }, @@ -128,7 +128,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "latest client height < height", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), }, @@ -146,7 +146,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "proof verification failed", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), NextValidatorsHash: suite.valsHash, @@ -396,9 +396,10 @@ func (suite *TendermintTestSuite) TestVerifyPacketCommitment() { store := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) + commitment := channeltypes.CommitPacket(suite.chainA.App.IBCKeeper.Codec(), packet) err = clientState.VerifyPacketCommitment( store, suite.chainA.Codec, proofHeight, &prefix, proof, - packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), channeltypes.CommitPacket(packet), + packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment, ) if tc.expPass { From 35183a37e6eda8ee461035c41d90ef36772f99cd Mon Sep 17 00:00:00 2001 From: Amaury Date: Wed, 18 Nov 2020 22:44:13 +0100 Subject: [PATCH 31/57] Fix StatusCommand (#7974) Co-authored-by: SaReN --- client/rpc/rpc_test.go | 47 ++++++++++++++++++++++++++++++++++++++++++ client/rpc/status.go | 43 ++++++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 client/rpc/rpc_test.go diff --git a/client/rpc/rpc_test.go b/client/rpc/rpc_test.go new file mode 100644 index 0000000000..c1c233e73b --- /dev/null +++ b/client/rpc/rpc_test.go @@ -0,0 +1,47 @@ +package rpc_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/client/rpc" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" +) + +type IntegrationTestSuite struct { + suite.Suite + + network *network.Network +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + s.network = network.New(s.T(), network.DefaultConfig()) + s.Require().NotNil(s.network) + + s.Require().NoError(s.network.WaitForNextBlock()) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s *IntegrationTestSuite) TestStatusCommand() { + val0 := s.network.Validators[0] + cmd := rpc.StatusCommand() + + out, err := clitestutil.ExecTestCLICmd(val0.ClientCtx, cmd, []string{}) + s.Require().NoError(err) + + // Make sure the output has the validator moniker. + s.Require().Contains(out.String(), fmt.Sprintf("\"moniker\":\"%s\"", val0.Moniker)) +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/client/rpc/status.go b/client/rpc/status.go index b234427480..f390a1ab99 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -2,22 +2,38 @@ package rpc import ( "context" - "fmt" "net/http" "github.com/spf13/cobra" + "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/p2p" ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/legacy" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/version" - - "github.com/tendermint/tendermint/p2p" ) +// ValidatorInfo is info about the node's validator, same as Tendermint, +// except that we use our own PubKey. +type validatorInfo struct { + Address bytes.HexBytes + PubKey cryptotypes.PubKey + VotingPower int64 +} + +// ResultStatus is node's info, same as Tendermint, except that we use our own +// PubKey. +type resultStatus struct { + NodeInfo p2p.DefaultNodeInfo + SyncInfo ctypes.SyncInfo + ValidatorInfo validatorInfo +} + // StatusCommand returns the command to return the status of the network. func StatusCommand() *cobra.Command { cmd := &cobra.Command{ @@ -31,12 +47,27 @@ func StatusCommand() *cobra.Command { return err } - output, err := legacy.Cdc.MarshalJSON(status) + // `status` has TM pubkeys, we need to convert them to our pubkeys. + pk, err := cryptocodec.FromTmPubKeyInterface(status.ValidatorInfo.PubKey) + if err != nil { + return err + } + statusWithPk := resultStatus{ + NodeInfo: status.NodeInfo, + SyncInfo: status.SyncInfo, + ValidatorInfo: validatorInfo{ + Address: status.ValidatorInfo.Address, + PubKey: pk, + VotingPower: status.ValidatorInfo.VotingPower, + }, + } + + output, err := clientCtx.LegacyAmino.MarshalJSON(statusWithPk) if err != nil { return err } - fmt.Println(string(output)) + cmd.Println(string(output)) return nil }, } From fe58ee99518adb62fe4a13c7ca3049af079d6fc7 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 19 Nov 2020 00:11:04 +0100 Subject: [PATCH 32/57] =?UTF-8?q?ADR-031:=20elaborate=20consequences=20and?= =?UTF-8?q?=20encapsulation=20of=20module=20client-se=E2=80=A6=20(#7839)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ADR-031: elaborate consequences and encapsulation of module client-server implementation * Update docs/architecture/adr-031-msg-service.md Co-authored-by: Aaron Craelius Co-authored-by: Aaron Craelius --- docs/architecture/adr-031-msg-service.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/architecture/adr-031-msg-service.md b/docs/architecture/adr-031-msg-service.md index bd67d090d8..edd906fdb9 100644 --- a/docs/architecture/adr-031-msg-service.md +++ b/docs/architecture/adr-031-msg-service.md @@ -53,7 +53,7 @@ This isn't necessarily bad, but it does add overhead to creating modules. We decide to use protobuf `service` definitions for defining `Msg`s as well as the code generated by them as a replacement for `Msg` handlers. -Below we define how this will look for the `SubmitProposal` message from `x/gov` module. +Below we define how this will look for the `SubmitProposal` message from `x/gov` module. We start with a `Msg` `service` definition: ```proto @@ -105,7 +105,7 @@ should use the more canonical `Msg...Request` names. Currently, we are encoding `Msg`s as `Any` in `Tx`s which involves packing the binary-encoded `Msg` with its type URL. -The type URL for `MsgSubmitProposal` based on the proto3 spec is `/cosmos.gov.MsgSubmitProposal`. +The type URL for `MsgSubmitProposal` based on the proto3 spec is `/cosmos.gov.MsgSubmitProposal`. The fully-qualified name for the `SubmitProposal` service method above (also based on the proto3 and gRPC specs) is `/cosmos.gov.Msg/SubmitProposal` which varies @@ -117,7 +117,7 @@ In order to encode service methods in transactions, we encode them as `Any`s in the same `TxBody.messages` field as other `Msg`s. We simply set `Any.type_url` to the full-qualified method name (ex. `/cosmos.gov.Msg/SubmitProposal`) and set `Any.value` to the protobuf encoding of the request message -(`MsgSubmitProposal` in this case). +(`MsgSubmitProposal` in this case). ### Decoding @@ -125,7 +125,7 @@ When decoding, `TxBody.UnpackInterfaces` will need a special case to detect if `Any` type URLs match the service method format (ex. `/cosmos.gov.Msg/SubmitProposal`) by checking for two `/` characters. Messages that are method names plus request parameters instead of a normal `Any` messages will get unpacked into the `ServiceMsg` struct: - + ```go type ServiceMsg struct { // MethodName is the fully-qualified service name @@ -139,7 +139,7 @@ type ServiceMsg struct { In the future, `service` definitions may become the primary method for defining `Msg`s. As a starting point, we need to integrate with the SDK's existing routing -and `Msg` interface. +and `Msg` interface. To do this, `ServiceMsg` implements the `sdk.Msg` interface and its handler does the actual method routing, allowing this feature to be added incrementally on top of @@ -218,17 +218,25 @@ Separate handler definition is no longer needed with this approach. ## Consequences +This design changes how a module functionality is exposed and accessed. It deprecates the existing `Handler` interface and `AppModule.Route` in favor of [Protocol Buffer Services](https://developers.google.com/protocol-buffers/docs/proto3#services) and Service Routing described above. This dramatically simplifies the code. We don't need to create handlers and keepers any more. Use of Protocol Buffer auto-generated clients clearly separates the communication interfaces between the module and a modules user. The control logic (aka handlers and keepers) is not exposed any more. A module interface can be seen as a black box accessible through a client API. It's worth to note that the client interfaces are also generated by Protocol Buffers. + +This also allows us to change how we perform functional tests. Instead of mocking AppModules and Router, we will mock a client (server will stay hidden). More specifically: we will never mock `moduleA.MsgServer` in `moduleB`, but rather `moduleA.MsgClient`. One can think about it as working with external services (eg DBs, or online servers...). We assume that the transmission between clients and servers is correctly handled by generated Protocol Buffers. + +Finally, closing a module to client API opens desirable OCAP patterns discussed in ADR-033. Since server implementation and interface is hidden, nobody can hold "keepers"/servers and will be forced to relay on the client interface, which will drive developers for correct encapsulation and software engineering patterns. + ### Pros - communicates return type clearly - manual handler registration and return type marshaling is no longer needed, just implement the interface and register it -- some keeper code could be automatically generate, this would improve the UX of [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093) approach (1) if we chose to adopt that -- generated client code could be useful for clients +- communication interface is automatically generated, the developer can now focus only on the state transition methods - this would improve the UX of [\#7093](https://github.com/cosmos/cosmos-sdk/issues/7093) approach (1) if we chose to adopt that +- generated client code could be useful for clients and tests +- dramatically reduces and simplifies the code ### Cons - supporting both this and the current concrete `Msg` type approach simultaneously could be confusing (we could choose to deprecate the current approach) - using `service` definitions outside the context of gRPC could be confusing (but doesn’t violate the proto3 spec) + ## References - [Initial Github Issue \#7122](https://github.com/cosmos/cosmos-sdk/issues/7122) From 0034e4845826bf97032d08a13c37d68d414cc573 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 19 Nov 2020 01:10:11 +0100 Subject: [PATCH 33/57] Bech32 PubKey: use protobuf in slashing keeper --- x/slashing/keeper/keeper.go | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/x/slashing/keeper/keeper.go b/x/slashing/keeper/keeper.go index 999e82404b..5264e45948 100644 --- a/x/slashing/keeper/keeper.go +++ b/x/slashing/keeper/keeper.go @@ -42,33 +42,27 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { } // AddPubkey sets a address-pubkey relation -func (k Keeper) AddPubkey(ctx sdk.Context, pubkey cryptotypes.PubKey) { - addr := pubkey.Address() - - pkStr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, pubkey) +func (k Keeper) AddPubkey(ctx sdk.Context, pubkey cryptotypes.PubKey) error { + bz, err := codec.MarshalAny(k.cdc, pubkey) if err != nil { - panic(fmt.Errorf("error while setting address-pubkey relation: %s", addr)) + return err } - - k.setAddrPubkeyRelation(ctx, addr, pkStr) + store := ctx.KVStore(k.storeKey) + key := types.AddrPubkeyRelationKey(pubkey.Address()) + store.Set(key, bz) + return nil } // GetPubkey returns the pubkey from the adddress-pubkey relation -func (k Keeper) GetPubkey(ctx sdk.Context, address cryptotypes.Address) (cryptotypes.PubKey, error) { +func (k Keeper) GetPubkey(ctx sdk.Context, a cryptotypes.Address) (cryptotypes.PubKey, error) { store := ctx.KVStore(k.storeKey) - - var pubkey gogotypes.StringValue - err := k.cdc.UnmarshalBinaryBare(store.Get(types.AddrPubkeyRelationKey(address)), &pubkey) - if err != nil { - return nil, fmt.Errorf("address %s not found", sdk.ConsAddress(address)) + bz := store.Get(types.AddrPubkeyRelationKey(a)) + if bz == nil { + return nil, fmt.Errorf("address %s not found", sdk.ConsAddress(a)) } - - pkStr, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeConsPub, pubkey.Value) - if err != nil { - return pkStr, err - } - - return pkStr, nil + var pk cryptotypes.PubKey + err := codec.UnmarshalAny(k.cdc, &pk, bz) + return pk, err } // Slash attempts to slash a validator. The slash is delegated to the staking From a4130f5821ab9cc44022de06a7f0c44faef53619 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 19 Nov 2020 02:19:19 +0100 Subject: [PATCH 34/57] remove unused function --- x/slashing/keeper/keeper.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/x/slashing/keeper/keeper.go b/x/slashing/keeper/keeper.go index 5264e45948..b5304a6c5e 100644 --- a/x/slashing/keeper/keeper.go +++ b/x/slashing/keeper/keeper.go @@ -3,8 +3,6 @@ package keeper import ( "fmt" - gogotypes "github.com/gogo/protobuf/types" - "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" @@ -93,13 +91,6 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { k.sk.Jail(ctx, consAddr) } -func (k Keeper) setAddrPubkeyRelation(ctx sdk.Context, addr cryptotypes.Address, pubkey string) { - store := ctx.KVStore(k.storeKey) - - bz := k.cdc.MustMarshalBinaryBare(&gogotypes.StringValue{Value: pubkey}) - store.Set(types.AddrPubkeyRelationKey(addr), bz) -} - func (k Keeper) deleteAddrPubkeyRelation(ctx sdk.Context, addr cryptotypes.Address) { store := ctx.KVStore(k.storeKey) store.Delete(types.AddrPubkeyRelationKey(addr)) From ba4bc4b5c86e56baa4f2589480ff7aa493222655 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 19 Nov 2020 09:48:55 +0000 Subject: [PATCH 35/57] exclude *.pb.gw.go files from codecov.io report (#7981) --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 06e85c907f..b586909335 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -144,6 +144,7 @@ jobs: run: | excludelist="$(find ./ -type f -name '*.go' | xargs grep -l 'DONTCOVER')" excludelist+=" $(find ./ -type f -name '*.pb.go')" + excludelist+=" $(find ./ -type f -name '*.pb.gw.go')" excludelist+=" $(find ./ -type f -path './tests/mocks/*.go')" for filename in ${excludelist}; do filename=$(echo $filename | sed 's/^./github.com\/cosmos\/cosmos-sdk/g') From fdac39813cb6627df843ab7852308330f45d26d2 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Thu, 19 Nov 2020 13:33:27 +0100 Subject: [PATCH 36/57] changelog update --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efca4d9bd3..7b2c97295b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,11 +37,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] ### Improvements -- (SDK) [\#7925](https://github.com/cosmos/cosmos-sdk/pull/7925) Updated dependencies to use gRPC v1.33.2 +* (SDK) [\#7925](https://github.com/cosmos/cosmos-sdk/pull/7925) Updated dependencies to use gRPC v1.33.2 * Updated gRPC dependency to v1.33.2 * Updated iavl dependency to v0.15-rc2 * (version) [\#7848](https://github.com/cosmos/cosmos-sdk/pull/7848) [\#7941](https://github.com/cosmos/cosmos-sdk/pull/7941) `version --long` output now shows the list of build dependencies and replaced build dependencies. +### State Machine Breaking Changes +* (x/upgrade) [\#7979](https://github.com/cosmos/cosmos-sdk/pull/7979) keeper pubkey storage serialization migration from bech32 to protobuf. + ### Bug Fixes * (crypto) [\#7966](https://github.com/cosmos/cosmos-sdk/issues/7966) `Bip44Params` `String()` function now correctly returns the absolute HD path by adding the `m/` prefix. From fcb6c33c34991c5951e804c9a650f45f7069e355 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 19 Nov 2020 16:15:31 +0000 Subject: [PATCH 37/57] revert tiny portion of #7970 (#7984) Testable examples were accidentally converted into tests. --- crypto/hd/hdpath_test.go | 195 +++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 99 deletions(-) diff --git a/crypto/hd/hdpath_test.go b/crypto/hd/hdpath_test.go index 2620e0605c..6dfda043eb 100644 --- a/crypto/hd/hdpath_test.go +++ b/crypto/hd/hdpath_test.go @@ -19,13 +19,6 @@ func mnemonicToSeed(mnemonic string) []byte { return bip39.NewSeed(mnemonic, defaultBIP39Passphrase) } -func TestPathParamsString(t *testing.T) { - path := hd.NewParams(44, 0, 0, false, 0) - require.Equal(t, "m/44'/0'/0'/0/0", path.String()) - path = hd.NewParams(44, 33, 7, true, 9) - require.Equal(t, "m/44'/33'/7'/1/9", path.String()) -} - func TestStringifyFundraiserPathParams(t *testing.T) { path := hd.NewFundraiserParams(4, types.CoinType, 22) require.Equal(t, "m/44'/118'/4'/0/22", path.String()) @@ -99,98 +92,6 @@ func TestParamsFromPath(t *testing.T) { } -func TestBIP32Vecs(t *testing.T) { - - seed := mnemonicToSeed("barrel original fuel morning among eternal " + - "filter ball stove pluck matrix mechanic") - master, ch := hd.ComputeMastersFromSeed(seed) - fmt.Println("keys from fundraiser test-vector (cosmos, bitcoin, ether)") - fmt.Println() - - // cosmos, absolute path - priv, err := hd.DerivePrivateKeyForPath(master, ch, types.FullFundraiserPath) - require.NoError(t, err) - require.NotEmpty(t, priv) - fmt.Println(hex.EncodeToString(priv[:])) - - absPrivKey := hex.EncodeToString(priv[:]) - - // cosmos, relative path - priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/118'/0'/0/0") - require.NoError(t, err) - require.NotEmpty(t, priv) - - relPrivKey := hex.EncodeToString(priv[:]) - - // check compatibility between relative and absolute HD paths - require.Equal(t, relPrivKey, absPrivKey) - - // bitcoin - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/0'/0'/0/0") - require.NoError(t, err) - require.NotEmpty(t, priv) - fmt.Println(hex.EncodeToString(priv[:])) - - // ether - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/60'/0'/0/0") - require.NoError(t, err) - require.NotEmpty(t, priv) - fmt.Println(hex.EncodeToString(priv[:])) - - // INVALID - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/X/0'/0'/0/0") - require.Error(t, err) - require.Empty(t, priv) - - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/-44/0'/0'/0/0") - require.Error(t, err) - require.Empty(t, priv) - - fmt.Println() - fmt.Println("keys generated via https://coinomi.com/recovery-phrase-tool.html") - fmt.Println() - - seed = mnemonicToSeed( - "advice process birth april short trust crater change bacon monkey medal garment " + - "gorilla ranch hour rival razor call lunar mention taste vacant woman sister") - master, ch = hd.ComputeMastersFromSeed(seed) - priv, _ = hd.DerivePrivateKeyForPath(master, ch, "m/44'/1'/1'/0/4") - fmt.Println(hex.EncodeToString(priv[:])) - - seed = mnemonicToSeed("idea naive region square margin day captain habit " + - "gun second farm pact pulse someone armed") - master, ch = hd.ComputeMastersFromSeed(seed) - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/44'/0'/0'/0/420") - require.NoError(t, err) - fmt.Println(hex.EncodeToString(priv[:])) - - fmt.Println() - fmt.Println("BIP 32 example") - fmt.Println() - - // bip32 path: m/0/7 - seed = mnemonicToSeed("monitor flock loyal sick object grunt duty ride develop assault harsh history") - master, ch = hd.ComputeMastersFromSeed(seed) - priv, err = hd.DerivePrivateKeyForPath(master, ch, "m/0/7") - require.NoError(t, err) // TODO: shouldn't this error? - fmt.Println(hex.EncodeToString(priv[:])) - - // Output: keys from fundraiser test-vector (cosmos, bitcoin, ether) - // - // bfcb217c058d8bbafd5e186eae936106ca3e943889b0b4a093ae13822fd3170c - // e77c3de76965ad89997451de97b95bb65ede23a6bf185a55d80363d92ee37c3d - // 7fc4d8a8146dea344ba04c593517d3f377fa6cded36cd55aee0a0bb968e651bc - // - // keys generated via https://coinomi.com/recovery-phrase-tool.html - // - // a61f10c5fecf40c084c94fa54273b6f5d7989386be4a37669e6d6f7b0169c163 - // 32c4599843de3ef161a629a461d12c60b009b676c35050be5f7ded3a3b23501f - // - // BIP 32 example - // - // c4c11d8c03625515905d7e89d25dfc66126fbc629ecca6db489a1a72fc4bda78 -} - func TestCreateHDPath(t *testing.T) { type args struct { coinType uint32 @@ -284,3 +185,99 @@ func TestDeriveHDPathRange(t *testing.T) { }) } } + +func ExampleStringifyPathParams() { + path := hd.NewParams(44, 0, 0, false, 0) + fmt.Println(path.String()) + path = hd.NewParams(44, 33, 7, true, 9) + fmt.Println(path.String()) + // Output: + // m/44'/0'/0'/0/0 + // m/44'/33'/7'/1/9 +} + +func ExampleSomeBIP32TestVecs() { + seed := mnemonicToSeed("barrel original fuel morning among eternal " + + "filter ball stove pluck matrix mechanic") + master, ch := hd.ComputeMastersFromSeed(seed) + fmt.Println("keys from fundraiser test-vector (cosmos, bitcoin, ether)") + fmt.Println() + // cosmos + priv, err := hd.DerivePrivateKeyForPath(master, ch, types.FullFundraiserPath) + if err != nil { + fmt.Println("INVALID") + } else { + fmt.Println(hex.EncodeToString(priv[:])) + } + // bitcoin + priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/0") + if err != nil { + fmt.Println("INVALID") + } else { + fmt.Println(hex.EncodeToString(priv[:])) + } + // ether + priv, err = hd.DerivePrivateKeyForPath(master, ch, "44'/60'/0'/0/0") + if err != nil { + fmt.Println("INVALID") + } else { + fmt.Println(hex.EncodeToString(priv[:])) + } + // INVALID + priv, err = hd.DerivePrivateKeyForPath(master, ch, "X/0'/0'/0/0") + if err != nil { + fmt.Println("INVALID") + } else { + fmt.Println(hex.EncodeToString(priv[:])) + } + priv, err = hd.DerivePrivateKeyForPath(master, ch, "-44/0'/0'/0/0") + if err != nil { + fmt.Println("INVALID") + } else { + fmt.Println(hex.EncodeToString(priv[:])) + } + + fmt.Println() + fmt.Println("keys generated via https://coinomi.com/recovery-phrase-tool.html") + fmt.Println() + + seed = mnemonicToSeed( + "advice process birth april short trust crater change bacon monkey medal garment " + + "gorilla ranch hour rival razor call lunar mention taste vacant woman sister") + master, ch = hd.ComputeMastersFromSeed(seed) + priv, _ = hd.DerivePrivateKeyForPath(master, ch, "44'/1'/1'/0/4") + fmt.Println(hex.EncodeToString(priv[:])) + + seed = mnemonicToSeed("idea naive region square margin day captain habit " + + "gun second farm pact pulse someone armed") + master, ch = hd.ComputeMastersFromSeed(seed) + priv, _ = hd.DerivePrivateKeyForPath(master, ch, "44'/0'/0'/0/420") + fmt.Println(hex.EncodeToString(priv[:])) + + fmt.Println() + fmt.Println("BIP 32 example") + fmt.Println() + + // bip32 path: m/0/7 + seed = mnemonicToSeed("monitor flock loyal sick object grunt duty ride develop assault harsh history") + master, ch = hd.ComputeMastersFromSeed(seed) + priv, _ = hd.DerivePrivateKeyForPath(master, ch, "0/7") + fmt.Println(hex.EncodeToString(priv[:])) + + // Output: keys from fundraiser test-vector (cosmos, bitcoin, ether) + // + // bfcb217c058d8bbafd5e186eae936106ca3e943889b0b4a093ae13822fd3170c + // e77c3de76965ad89997451de97b95bb65ede23a6bf185a55d80363d92ee37c3d + // 7fc4d8a8146dea344ba04c593517d3f377fa6cded36cd55aee0a0bb968e651bc + // INVALID + // INVALID + // + // keys generated via https://coinomi.com/recovery-phrase-tool.html + // + // a61f10c5fecf40c084c94fa54273b6f5d7989386be4a37669e6d6f7b0169c163 + // 32c4599843de3ef161a629a461d12c60b009b676c35050be5f7ded3a3b23501f + // + // BIP 32 example + // + // c4c11d8c03625515905d7e89d25dfc66126fbc629ecca6db489a1a72fc4bda78 +} From 4be5cd34543f206d9f4c546f62509d18047913ef Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Thu, 19 Nov 2020 11:57:10 -0500 Subject: [PATCH 38/57] docs: x/bank: Atlas Doc (#7961) --- x/bank/atlas/atlas-v0.39.1.md | 208 ++++++++++++++++++++++++++++++++++ x/bank/atlas/atlas.toml | 34 ++++++ 2 files changed, 242 insertions(+) create mode 100644 x/bank/atlas/atlas-v0.39.1.md create mode 100644 x/bank/atlas/atlas.toml diff --git a/x/bank/atlas/atlas-v0.39.1.md b/x/bank/atlas/atlas-v0.39.1.md new file mode 100644 index 0000000000..ef34e02e00 --- /dev/null +++ b/x/bank/atlas/atlas-v0.39.1.md @@ -0,0 +1,208 @@ +# x/bank + +The `x/bank` module is responsible for handling multi-asset coin transfers between +accounts and tracking special-case pseudo-transfers which must work differently +with particular kinds of accounts. + +## Usage + +1. Import the module. + + ```go + import ( + "github.com/cosmos/cosmos-sdk/x/bank" + ) + ``` + +2. Add `AppModuleBasic` to your `ModuleBasics`. + + ```go + var ( + ModuleBasics = module.NewBasicManager( + // ... + bank.AppModuleBasic{}, + } + ) + ``` + +3. Create the module's parameter subspace in your application constructor. + + ```go + func NewApp(...) *App { + // ... + app.subspaces[bank.ModuleName] = app.ParamsKeeper.Subspace(bank.DefaultParamspace) + } + ``` + +4. Create the keeper. Note, the `x/bank` module depends on the `x/auth` module + and a list of blacklisted account addresses which funds are not allowed to be + sent to. Your application will need to define this method based your needs. + + ```go + func NewApp(...) *App { + // ... + app.BankKeeper = bank.NewBaseKeeper( + app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(), + ) + } + ``` + +5. Add the `x/bank` module to the app's `ModuleManager`. + + ```go + func NewApp(...) *App { + // ... + app.mm = module.NewManager( + // ... + bank.NewAppModule(app.BankKeeper, app.AccountKeeper), + // ... + ) + } + ``` + +6. Set the `x/bank` module genesis order. + + ```go + func NewApp(...) *App { + // ... + app.mm.SetOrderInitGenesis(..., bank.ModuleName, ...) + } + ``` + +7. Add the `x/bank` module to the simulation manager (if you have one set). + + ```go + func NewApp(...) *App { + // ... + app.sm = module.NewSimulationManager( + // ... + bank.NewAppModule(app.BankKeeper, app.AccountKeeper), + // ... + ) + } + +## Genesis + +The `x/bank` module defines its genesis state as follows: + +```go +type GenesisState struct { + SendEnabled bool `json:"send_enabled" yaml:"send_enabled"` +} +``` + +The `SendEnabled` parameter determines if transfers are enabled or disabled +entirely on the chain. This can be used to start a network without enabling +transfers while ensuring critical network functionality is operating as expected. + +## Messages + +### `MsgSend` + +The `x/bank` module allows for transfer of funds from a source account to a +destination account. + +```go +type MsgSend struct { + FromAddress sdk.AccAddress `json:"from_address" yaml:"from_address"` + ToAddress sdk.AccAddress `json:"to_address" yaml:"to_address"` + Amount sdk.Coins `json:"amount" yaml:"amount"` +} +``` + +### `MsgMultiSend` + +The `x/bank` module also allows for multiple inputs and outputs. The sum of all +inputs must be equivalent to the sum of all outputs. + +```go +type Input struct { + Address sdk.AccAddress `json:"address" yaml:"address"` + Coins sdk.Coins `json:"coins" yaml:"coins"` +} + +type Output struct { + Address sdk.AccAddress `json:"address" yaml:"address"` + Coins sdk.Coins `json:"coins" yaml:"coins"` +} + +type MsgMultiSend struct { + Inputs []Input `json:"inputs" yaml:"inputs"` + Outputs []Output `json:"outputs" yaml:"outputs"` +} +``` + +## Client + +### CLI + +The `x/bank` supports the following transactional commands. + +1. Send tokens via a `MsgSend` message. + + ```shell + $ tx send [from_key_or_address] [to_address] [amount] [...flags] + ``` + +Note, the `x/bank` module does not natively support constructing a `MsgMultiSend` +message. This type of message must be constructed manually, but it may be signed +and broadcasted via the CLI. + +### REST + +The `x/bank` supports various query API endpoints and a `MsgSend` construction +endpoint. + +1. Construct an unsigned `MsgSend` transaction. + + | Method | Path | + | :----- | :----------------------- | + | `POST` | `/bank/accounts/{address}/transfers` | + + Sample payload: + + ```json + { + "base_req": { + "chain_id": "chain-foo", + "from": "cosmos1u3fneykx9carelvurc6av22vpjvptytj9wklk0", + "memo": "memo", + "fees": [ + { + "denom": "stake", + "amount": "25000" + } + ] + }, + "amount": [ + { + "denom": "stake", + "amount": "400000000" + } + ] + } + ``` + +2. Query for an account's balance. + + | Method | Path | + | :----- | :----------------------- | + | `GET` | `/bank/balances/{address}` | + + Sample response: + + ```json + { + "height": "0", + "result": [ + { + "denom": "node0token", + "amount": "1000000000" + }, + { + "denom": "stake", + "amount": "400000000" + } + ] + } + ``` diff --git a/x/bank/atlas/atlas.toml b/x/bank/atlas/atlas.toml new file mode 100644 index 0000000000..f10863e30b --- /dev/null +++ b/x/bank/atlas/atlas.toml @@ -0,0 +1,34 @@ +[module] +description = "The bank module is responsible for handling multi-asset coin transfers between accounts and tracking special-case pseudo-transfers which must work differently with particular kinds of accounts." +homepage = "https://github.com/cosmos/cosmos-sdk" +keywords = [ + "tokens", + "bank", + "transfer", + "asset", + "fungible", + "coins", +] + +name = "x/bank" + +[bug_tracker] +url = "https://github.com/cosmos/cosmos-sdk/issues" + +[[authors]] +name = "alexanderbez" + +[[authors]] +name = "fedekunze" + +[[authors]] +name = "cwgoes" + +[[authors]] +name = "alessio" + +[version] +documentation = "https://raw.githubusercontent.com/cosmos/cosmos-sdk/master/x/bank/atlas/atlas-v0.39.1.md" +repo = "https://github.com/cosmos/cosmos-sdk/releases/tag/v0.39.1" +sdk_compat = "v0.39.x" +version = "v0.39.1" From d8928c6b80a4d8f59580566372c6e3d41458db90 Mon Sep 17 00:00:00 2001 From: Alexander Peters Date: Fri, 20 Nov 2020 15:13:25 +0100 Subject: [PATCH 39/57] CI: Fix codecov flag project config (#7994) --- .codecov.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index e17633a5d3..63c053e74b 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -15,12 +15,15 @@ coverage: threshold: 1% # allow this much decrease on project app: target: 70% - flags: app + flags: + - app modules: target: 70% - flags: modules + flags: + - modules client: - flags: client + flags: + - client changes: false comment: From a7296d3d4ea1f01ee1709d74df4e693d6a0a9993 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 20 Nov 2020 13:00:11 -0500 Subject: [PATCH 40/57] Bump Tendermint v0.34.0 (#7995) * init commit * ibc: remove redundant casting * ci: attempt fix liveness job --- .github/workflows/test.yml | 3 +++ go.mod | 2 +- go.sum | 2 ++ x/ibc/light-clients/07-tendermint/types/fraction.go | 8 ++++---- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b586909335..b3c42073b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -231,6 +231,9 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v2 + - uses: actions/setup-go@v2.1.3 + with: + go-version: 1.15 - uses: technote-space/get-diff-action@v4 id: git_diff with: diff --git a/go.mod b/go.mod index ad65e29a68..39e2804248 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/tendermint/btcd v0.1.1 github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 github.com/tendermint/go-amino v0.16.0 - github.com/tendermint/tendermint v0.34.0-rc6 + github.com/tendermint/tendermint v0.34.0 github.com/tendermint/tm-db v0.6.3 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect diff --git a/go.sum b/go.sum index 3fb9fc93bf..fea22c921e 100644 --- a/go.sum +++ b/go.sum @@ -599,6 +599,8 @@ github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoM github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= github.com/tendermint/tendermint v0.34.0-rc6 h1:SVuKGvvE22KxfuK8QUHctUrmOWJsncZSYXIYtcnoKN0= github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= +github.com/tendermint/tendermint v0.34.0 h1:eXCfMgoqVSzrjzOj6clI9GAejcHH0LvOlRjpCmMJksU= +github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= github.com/tendermint/tm-db v0.6.2 h1:DOn8jwCdjJblrCFJbtonEIPD1IuJWpbRUUdR8GWE4RM= github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= github.com/tendermint/tm-db v0.6.3 h1:ZkhQcKnB8/2jr5EaZwGndN4owkPsGezW2fSisS9zGbg= diff --git a/x/ibc/light-clients/07-tendermint/types/fraction.go b/x/ibc/light-clients/07-tendermint/types/fraction.go index a8d8274146..e445f19ba6 100644 --- a/x/ibc/light-clients/07-tendermint/types/fraction.go +++ b/x/ibc/light-clients/07-tendermint/types/fraction.go @@ -11,15 +11,15 @@ var DefaultTrustLevel = NewFractionFromTm(light.DefaultTrustLevel) // NewFractionFromTm returns a new Fraction instance from a tmmath.Fraction func NewFractionFromTm(f tmmath.Fraction) Fraction { return Fraction{ - Numerator: uint64(f.Numerator), - Denominator: uint64(f.Denominator), + Numerator: f.Numerator, + Denominator: f.Denominator, } } // ToTendermint converts Fraction to tmmath.Fraction func (f Fraction) ToTendermint() tmmath.Fraction { return tmmath.Fraction{ - Numerator: int64(f.Numerator), - Denominator: int64(f.Denominator), + Numerator: f.Numerator, + Denominator: f.Denominator, } } From 6344d626db1fbdba5e0f67425703c1584021bf5b Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Fri, 20 Nov 2020 11:37:45 -0800 Subject: [PATCH 41/57] types/Coin: compile and reuse Regexps to reduce massive RAM+CPU burn (#7989) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * types/Coin: compile and reuse Regexps to reduce massive RAM+CPU burn Fixes a resource (CPU+RAM) burn from recompiling Regexps which would consume 1.2+MiB of RAM and 1.1ms per ParseCoin invocation, which means that 1,000 invocations would consume 1.2GiB of RAM and >1second. With the change, ParseCoin now takes 3.2us down from 1.1ms, with dramatic results: name old time/op new time/op delta ParseCoin-8 1.04ms ± 4% 0.00ms ± 1% -99.69% (p=0.000 n=9+10) name old alloc/op new alloc/op delta ParseCoin-8 1.20MB ± 0% 0.00MB ± 0% -99.94% (p=0.000 n=10+10) name old allocs/op new allocs/op delta ParseCoin-8 17.8k ± 0% 0.0k ± 0% -99.89% (p=0.000 n=10+10) Fixes #7986. * replace the CoinDenomRegex variable with SetCoinDenomRegex() (#7998) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Co-authored-by: Alessio Treglia --- go.mod | 1 + go.sum | 50 --------------------------------------------- types/bench_test.go | 30 +++++++++++++++++++++++++++ types/coin.go | 34 ++++++++++++++++-------------- types/coin_test.go | 6 +++--- types/dec_coin.go | 2 +- 6 files changed, 54 insertions(+), 69 deletions(-) create mode 100644 types/bench_test.go diff --git a/go.mod b/go.mod index 39e2804248..5c05b40b71 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/golang/mock v1.4.4 github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.2 // indirect + github.com/google/go-cmp v0.5.0 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 diff --git a/go.sum b/go.sum index fea22c921e..da0703bd69 100644 --- a/go.sum +++ b/go.sum @@ -4,16 +4,11 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/keyring v1.1.6 h1:kVDC2uCgVwecxCk+9zoCt2uEL6dt+dfVzMvGgnVcIuM= @@ -24,7 +19,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -37,7 +31,6 @@ github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrd github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -50,14 +43,12 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.4 h1:Xqf+7f2Vhl9tsqDYmXhnXInUdcrtgpRNpIA15/uldSc= github.com/armon/go-metrics v0.3.4/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0 h1:0xphMHGMLBrPMfxR2AmVjZKcMEESEgWF8Kru94BNByk= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -67,29 +58,21 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d h1:xG8Pj6Y6J760xwETNmMzmlt38QSwz0BLp1cZ09g27uw= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= -github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -137,18 +120,14 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger/v2 v2.2007.1 h1:t36VcBCpo4SsmAD5M8wVv1ieVzcALyGfaJ92z4ccULM= github.com/dgraph-io/badger/v2 v2.2007.1/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -182,11 +161,9 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -206,11 +183,9 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6 github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -229,12 +204,10 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -244,14 +217,12 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -259,7 +230,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -281,7 +251,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaD github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= @@ -299,7 +268,6 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -312,7 +280,6 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -325,29 +292,24 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -358,7 +320,6 @@ github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNr github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8= github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -373,7 +334,6 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -394,7 +354,6 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -425,13 +384,11 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= @@ -480,7 +437,6 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw= github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM= @@ -497,9 +453,7 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= @@ -508,7 +462,6 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -556,7 +509,6 @@ github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= @@ -597,11 +549,9 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tendermint/tendermint v0.34.0-rc4/go.mod h1:yotsojf2C1QBOw4dZrTcxbyxmPUrT4hNuOQWX9XUwB4= -github.com/tendermint/tendermint v0.34.0-rc6 h1:SVuKGvvE22KxfuK8QUHctUrmOWJsncZSYXIYtcnoKN0= github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX6mjJTgbLHTwi17VDVg= github.com/tendermint/tendermint v0.34.0 h1:eXCfMgoqVSzrjzOj6clI9GAejcHH0LvOlRjpCmMJksU= github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ= -github.com/tendermint/tm-db v0.6.2 h1:DOn8jwCdjJblrCFJbtonEIPD1IuJWpbRUUdR8GWE4RM= github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI= github.com/tendermint/tm-db v0.6.3 h1:ZkhQcKnB8/2jr5EaZwGndN4owkPsGezW2fSisS9zGbg= github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8= diff --git a/types/bench_test.go b/types/bench_test.go new file mode 100644 index 0000000000..be7e0c7f4b --- /dev/null +++ b/types/bench_test.go @@ -0,0 +1,30 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/types" +) + +var coinStrs = []string{ + "2000ATM", + "5000AMX", + "192XXX", + "1e9BTC", +} + +func BenchmarkParseCoin(b *testing.B) { + var blankCoin types.Coin + b.ReportAllocs() + for i := 0; i < b.N; i++ { + for _, coinStr := range coinStrs { + coin, err := types.ParseCoin(coinStr) + if err != nil { + b.Fatal(err) + } + if coin == blankCoin { + b.Fatal("Unexpectedly returned a blank coin") + } + } + } +} diff --git a/types/coin.go b/types/coin.go index 5e2c22bdf8..da2e3c398a 100644 --- a/types/coin.go +++ b/types/coin.go @@ -602,19 +602,13 @@ var ( reAmt = `[[:digit:]]+` reDecAmt = `[[:digit:]]+(?:\.[[:digit:]]+)?|\.[[:digit:]]+` reSpc = `[[:space:]]*` - reDnm = returnReDnm - reCoin = returnReCoin - reDecCoin = returnDecCoin + reDnm *regexp.Regexp + reCoin *regexp.Regexp + reDecCoin *regexp.Regexp ) -func returnDecCoin() *regexp.Regexp { - return regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reDecAmt, reSpc, CoinDenomRegex())) -} -func returnReCoin() *regexp.Regexp { - return regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reAmt, reSpc, CoinDenomRegex())) -} -func returnReDnm() *regexp.Regexp { - return regexp.MustCompile(fmt.Sprintf(`^%s$`, CoinDenomRegex())) +func init() { + SetCoinDenomRegex(DefaultCoinDenomRegex) } // DefaultCoinDenomRegex returns the default regex string @@ -622,12 +616,22 @@ func DefaultCoinDenomRegex() string { return reDnmString } -// CoinDenomRegex returns the current regex string and can be overwritten for custom validation -var CoinDenomRegex = DefaultCoinDenomRegex +// coinDenomRegex returns the current regex string and can be overwritten for custom validation +var coinDenomRegex = DefaultCoinDenomRegex + +// SetCoinDenomRegex allows for coin's custom validation by overriding the regular +// expression string used for denom validation. +func SetCoinDenomRegex(reFn func() string) { + coinDenomRegex = reFn + + reDnm = regexp.MustCompile(fmt.Sprintf(`^%s$`, coinDenomRegex())) + reCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reAmt, reSpc, coinDenomRegex())) + reDecCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reDecAmt, reSpc, coinDenomRegex())) +} // ValidateDenom is the default validation function for Coin.Denom. func ValidateDenom(denom string) error { - if !reDnm().MatchString(denom) { + if !reDnm.MatchString(denom) { return fmt.Errorf("invalid denom: %s", denom) } return nil @@ -645,7 +649,7 @@ func mustValidateDenom(denom string) { func ParseCoin(coinStr string) (coin Coin, err error) { coinStr = strings.TrimSpace(coinStr) - matches := reCoin().FindStringSubmatch(coinStr) + matches := reCoin.FindStringSubmatch(coinStr) if matches == nil { return Coin{}, fmt.Errorf("invalid coin expression: %s", coinStr) } diff --git a/types/coin_test.go b/types/coin_test.go index 0e4bbf739f..ab69f16a17 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -101,9 +101,9 @@ func (s *coinTestSuite) TestCoinIsValid() { func (s *coinTestSuite) TestCustomValidation() { newDnmRegex := `[\x{1F600}-\x{1F6FF}]` - sdk.CoinDenomRegex = func() string { + sdk.SetCoinDenomRegex(func() string { return newDnmRegex - } + }) cases := []struct { coin sdk.Coin @@ -119,7 +119,7 @@ func (s *coinTestSuite) TestCustomValidation() { for i, tc := range cases { s.Require().Equal(tc.expectPass, tc.coin.IsValid(), "unexpected result for IsValid, tc #%d", i) } - sdk.CoinDenomRegex = sdk.DefaultCoinDenomRegex + sdk.SetCoinDenomRegex(sdk.DefaultCoinDenomRegex) } func (s *coinTestSuite) TestAddCoin() { diff --git a/types/dec_coin.go b/types/dec_coin.go index a8ad465c61..6e400d7a05 100644 --- a/types/dec_coin.go +++ b/types/dec_coin.go @@ -615,7 +615,7 @@ func (coins DecCoins) Sort() DecCoins { func ParseDecCoin(coinStr string) (coin DecCoin, err error) { coinStr = strings.TrimSpace(coinStr) - matches := reDecCoin().FindStringSubmatch(coinStr) + matches := reDecCoin.FindStringSubmatch(coinStr) if matches == nil { return DecCoin{}, fmt.Errorf("invalid decimal coin expression: %s", coinStr) } From 966e26d23ddc62553fa46155036cc2d4d25f14ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Mon, 23 Nov 2020 16:10:25 +0100 Subject: [PATCH 42/57] Fix tendermint misbehaviour trusted consensus state age check (#8006) * use TrustingPeriod instead of UnbondingPeriod when verifying the age of the trusted consensus state * update comment --- .../07-tendermint/types/misbehaviour_handle.go | 10 +++++----- .../07-tendermint/types/misbehaviour_handle_test.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go index b27cc06a45..1f1a6943ce 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go @@ -92,12 +92,12 @@ func checkMisbehaviourHeader( return err } - // assert that the timestamp is not from more than an unbonding period ago - if currentTimestamp.Sub(consState.Timestamp) >= clientState.UnbondingPeriod { + // assert that the age of the trusted consensus state is not older than the trusting period + if currentTimestamp.Sub(consState.Timestamp) >= clientState.TrustingPeriod { return sdkerrors.Wrapf( - ErrUnbondingPeriodExpired, - "current timestamp minus the latest consensus state timestamp is greater than or equal to the unbonding period (%d >= %d)", - currentTimestamp.Sub(consState.Timestamp), clientState.UnbondingPeriod, + ErrTrustingPeriodExpired, + "current timestamp minus the latest consensus state timestamp is greater than or equal to the trusting period (%d >= %d)", + currentTimestamp.Sub(consState.Timestamp), clientState.TrustingPeriod, ) } diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go index 6d8cd5e32a..65ec7163d8 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go @@ -256,7 +256,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { false, }, { - "unbonding period expired", + "trusting period expired", types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(time.Time{}, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, @@ -267,7 +267,7 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, - suite.now.Add(ubdPeriod), + suite.now.Add(trustingPeriod), false, }, { From 251a27d10480280ba22561581f8ab268a6a899f3 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Mon, 23 Nov 2020 11:31:17 -0500 Subject: [PATCH 43/57] Update ADR status (#8009) --- docs/architecture/README.md | 8 ++++---- docs/architecture/adr-004-split-denomination-keys.md | 2 +- docs/architecture/adr-021-protobuf-query-encoding.md | 2 +- docs/architecture/adr-023-protobuf-naming.md | 2 +- docs/architecture/adr-031-msg-service.md | 2 +- go.mod | 1 - 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/architecture/README.md b/docs/architecture/README.md index d3ff033688..54cc9c89e4 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -43,18 +43,21 @@ Read about the [PROCESS](./PROCESS.md). - [ADR 001: Coin Source Tracing](./adr-001-coin-source-tracing.md) - [ADR 002: SDK Documentation Structure](./adr-002-docs-structure.md) +- [ADR 004: Split Denomination Keys](./adr-004-split-denomination-keys.md) - [ADR 006: Secret Store Replacement](./adr-006-secret-store-replacement.md) - [ADR 009: Evidence Module](./adr-009-evidence-module.md) - [ADR 010: Modular AnteHandler](./adr-010-modular-antehandler.md) - [ADR 019: Protocol Buffer State Encoding](./adr-019-protobuf-state-encoding.md) - [ADR 020: Protocol Buffer Transaction Encoding](./adr-020-protobuf-transaction-encoding.md) +- [ADR 021: Protocol Buffer Query Encoding](./adr-021-protobuf-query-encoding.md) +- [ADR 023: Protocol Buffer Naming and Versioning](./adr-023-protobuf-naming.md) - [ADR 026: IBC Client Recovery Mechanisms](./adr-026-ibc-client-recovery-mechanisms.md) - [ADR 029: Fee Grant Module](./adr-029-fee-grant-module.md) +- [ADR 031: Protobuf Msg Services](./adr-031-msg-service.md) ### Proposed - [ADR 003: Dynamic Capability Store](./adr-003-dynamic-capability-store.md) -- [ADR 004: Split Denomination Keys](./adr-004-split-denomination-keys.md) - [ADR 011: Generalize Genesis Accounts](./adr-011-generalize-genesis-accounts.md) - [ADR 012: State Accessors](./adr-012-state-accessors.md) - [ADR 013: Metrics](./adr-013-metrics.md) @@ -62,14 +65,11 @@ Read about the [PROCESS](./PROCESS.md). - [ADR 016: Validator Consensus Key Rotation](./adr-016-validator-consensus-key-rotation.md) - [ADR 017: Historical Header Module](./adr-017-historical-header-module.md) - [ADR 018: Extendable Voting Periods](./adr-018-extendable-voting-period.md) -- [ADR 021: Protocol Buffer Query Encoding](./adr-021-protobuf-query-encoding.md) - [ADR 022: Custom baseapp panic handling](./adr-022-custom-panic-handling.md) -- [ADR 023: Protocol Buffer Naming and Versioning](./adr-023-protobuf-naming.md) - [ADR 024: Coin Metadata](./adr-024-coin-metadata.md) - [ADR 025: IBC Passive Channels](./adr-025-ibc-passive-channels.md) - [ADR 027: Deterministic Protobuf Serialization](./adr-027-deterministic-protobuf-serialization.md) - [ADR 028: Public Key Addresses](./adr-028-public-key-addresses.md) -- [ADR 031: Protobuf Msg Services](./adr-031-msg-service.md) - [ADR 032: Typed Events](./adr-032-typed-events.md) - [ADR 035: Rosetta API Support](./adr-035-rosetta-api-support.md) - [ADR 037: Governance Split Votes](./adr-037-gov-split-vote.md) \ No newline at end of file diff --git a/docs/architecture/adr-004-split-denomination-keys.md b/docs/architecture/adr-004-split-denomination-keys.md index d33b7c6d03..a718d9b0ca 100644 --- a/docs/architecture/adr-004-split-denomination-keys.md +++ b/docs/architecture/adr-004-split-denomination-keys.md @@ -96,7 +96,7 @@ the balances and check that they match the expected total supply. ## Status -Proposed. +Accepted. ## Consequences diff --git a/docs/architecture/adr-021-protobuf-query-encoding.md b/docs/architecture/adr-021-protobuf-query-encoding.md index ba0b35cd96..60d4d2b2f6 100644 --- a/docs/architecture/adr-021-protobuf-query-encoding.md +++ b/docs/architecture/adr-021-protobuf-query-encoding.md @@ -6,7 +6,7 @@ ## Status -Proposed +Accepted ## Context diff --git a/docs/architecture/adr-023-protobuf-naming.md b/docs/architecture/adr-023-protobuf-naming.md index e909c33d1d..1322f097f5 100644 --- a/docs/architecture/adr-023-protobuf-naming.md +++ b/docs/architecture/adr-023-protobuf-naming.md @@ -7,7 +7,7 @@ ## Status -Proposed +Accepted ## Context diff --git a/docs/architecture/adr-031-msg-service.md b/docs/architecture/adr-031-msg-service.md index edd906fdb9..a36d86c431 100644 --- a/docs/architecture/adr-031-msg-service.md +++ b/docs/architecture/adr-031-msg-service.md @@ -6,7 +6,7 @@ ## Status -Proposed +Accepted ## Abstract diff --git a/go.mod b/go.mod index 5c05b40b71..39e2804248 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/golang/mock v1.4.4 github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.2 // indirect - github.com/google/go-cmp v0.5.0 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 From 74435137e9bcfeba7c2022b7aafe176bb632ccc5 Mon Sep 17 00:00:00 2001 From: Amaury Date: Tue, 24 Nov 2020 11:28:12 +0100 Subject: [PATCH 44/57] Show height on legacy REST endpoints (#7997) * Fix showing height in rest endpoints * Fix query height * Manually inject req.Height * Small tweaks * Use withHeight Co-authored-by: Aleksandr Bezobchuk Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- baseapp/abci.go | 10 +++---- client/errors.go | 22 ---------------- client/rpc/block.go | 3 +-- x/bank/client/rest/query_test.go | 45 +++++++++++++++++++++++++------- 4 files changed, 41 insertions(+), 39 deletions(-) delete mode 100644 client/errors.go diff --git a/baseapp/abci.go b/baseapp/abci.go index ada95acf1f..d988ead0fc 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -382,6 +382,11 @@ func (app *BaseApp) snapshot(height int64) { func (app *BaseApp) Query(req abci.RequestQuery) abci.ResponseQuery { defer telemetry.MeasureSince(time.Now(), "abci", "query") + // when a client did not provide a query height, manually inject the latest + if req.Height == 0 { + req.Height = app.LastBlockHeight() + } + // handle gRPC routes first rather than calling splitPath because '/' characters // are used as part of gRPC paths if grpcHandler := app.grpcQueryRouter.Route(req.Path); grpcHandler != nil { @@ -742,11 +747,6 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R req.Path = "/" + strings.Join(path[1:], "/") - // when a client did not provide a query height, manually inject the latest - if req.Height == 0 { - req.Height = app.LastBlockHeight() - } - if req.Height <= 1 && req.Prove { return sdkerrors.QueryResult( sdkerrors.Wrap( diff --git a/client/errors.go b/client/errors.go deleted file mode 100644 index d7f7e29664..0000000000 --- a/client/errors.go +++ /dev/null @@ -1,22 +0,0 @@ -package client - -import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ErrInvalidAccount returns a standardized error reflecting that a given -// account address does not exist. -func ErrInvalidAccount(addr sdk.AccAddress) error { - return fmt.Errorf(`no account with address %s was found in the state. -Are you sure there has been a transaction involving it?`, addr) -} - -// ErrVerifyCommit returns a common error reflecting that the blockchain commit at a given -// height can't be verified. The reason is that the base checkpoint of the certifier is -// newer than the given height -func ErrVerifyCommit(height int64) error { - return fmt.Errorf(`the height of base truststore in the light client is higher than height %d. -Can't verify blockchain proof at this height. Please set --trust-node to true and try again`, height) -} diff --git a/client/rpc/block.go b/client/rpc/block.go index a6a42967ce..8bf7f12af8 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/codec/legacy" "github.com/cosmos/cosmos-sdk/types/rest" ) @@ -68,7 +67,7 @@ func getBlock(clientCtx client.Context, height *int64) ([]byte, error) { return nil, err } - return legacy.Cdc.MarshalJSON(res) + return clientCtx.LegacyAmino.MarshalJSON(res) } // get the current blockchain height diff --git a/x/bank/client/rest/query_test.go b/x/bank/client/rest/query_test.go index bbd803ba75..5ca3a15be5 100644 --- a/x/bank/client/rest/query_test.go +++ b/x/bank/client/rest/query_test.go @@ -29,7 +29,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.cfg = cfg s.network = network.New(s.T(), cfg) - _, err := s.network.WaitForHeight(1) + _, err := s.network.WaitForHeight(2) s.Require().NoError(err) } @@ -43,14 +43,26 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { baseURL := val.APIAddress testCases := []struct { - name string - url string - respType fmt.Stringer - expected fmt.Stringer + name string + url string + expHeight int64 + respType fmt.Stringer + expected fmt.Stringer }{ { "total account balance", + fmt.Sprintf("%s/bank/balances/%s", baseURL, val.Address), + -1, + &sdk.Coins{}, + sdk.NewCoins( + sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens), + sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)), + ), + }, + { + "total account balance with height", fmt.Sprintf("%s/bank/balances/%s?height=1", baseURL, val.Address), + 1, &sdk.Coins{}, sdk.NewCoins( sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens), @@ -59,13 +71,15 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { }, { "total account balance of a specific denom", - fmt.Sprintf("%s/bank/balances/%s?height=1&denom=%s", baseURL, val.Address, s.cfg.BondDenom), + fmt.Sprintf("%s/bank/balances/%s?denom=%s", baseURL, val.Address, s.cfg.BondDenom), + -1, &sdk.Coin{}, sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)), }, { "total account balance of a bogus denom", - fmt.Sprintf("%s/bank/balances/%s?height=1&denom=foobar", baseURL, val.Address), + fmt.Sprintf("%s/bank/balances/%s?denom=foobar", baseURL, val.Address), + -1, &sdk.Coin{}, sdk.NewCoin("foobar", sdk.ZeroInt()), }, @@ -74,12 +88,23 @@ func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - resp, err := rest.GetRequest(tc.url) + respJSON, err := rest.GetRequest(tc.url) s.Require().NoError(err) - bz, err := rest.ParseResponseWithHeight(val.ClientCtx.LegacyAmino, resp) + var resp = rest.ResponseWithHeight{} + err = val.ClientCtx.LegacyAmino.UnmarshalJSON(respJSON, &resp) s.Require().NoError(err) - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(bz, tc.respType)) + + // Check height. + if tc.expHeight >= 0 { + s.Require().Equal(resp.Height, tc.expHeight) + } else { + // To avoid flakiness, just test that height is positive. + s.Require().Greater(resp.Height, int64(0)) + } + + // Check result. + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(resp.Result, tc.respType)) s.Require().Equal(tc.expected.String(), tc.respType.String()) }) } From def3c5ba713c567acb2bf2f3b86ad64d8fe825fe Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 24 Nov 2020 11:45:33 +0000 Subject: [PATCH 45/57] Add ConsensusState to IBC Upgrades (#7919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * upgrade progress * fix build minus cli * write state at block before upgrade height * refix build * Apply suggestions from code review Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * fix upgrade and start with tests * fix tendermint tests * add tests and remove unnecessary relayer options on upgradedClient * fix all tests except weird msg panic * add invalid final client test and codec stuff * fix everything but msg issue * remove problematic test for now * safer self validation * upgrade fixes * proto-linting * remove unnecessary last height * add timestamp to committed upgrade consensus state * address final nits * address nit Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- client/docs/swagger-ui/swagger.yaml | 557 ++++++++++++++++++ proto/cosmos/upgrade/v1beta1/query.proto | 23 + proto/ibc/core/client/v1/tx.proto | 13 +- .../tendermint/v1/tendermint.proto | 8 +- x/ibc/core/02-client/keeper/client.go | 8 +- x/ibc/core/02-client/keeper/client_test.go | 66 ++- x/ibc/core/02-client/keeper/keeper.go | 11 +- x/ibc/core/02-client/keeper/keeper_test.go | 4 +- x/ibc/core/02-client/types/codec.go | 1 + x/ibc/core/02-client/types/msgs.go | 52 +- x/ibc/core/02-client/types/msgs_test.go | 59 +- x/ibc/core/02-client/types/tx.pb.go | 202 ++++--- x/ibc/core/exported/client.go | 10 +- x/ibc/core/keeper/msg_server.go | 7 +- x/ibc/core/keeper/msg_server_test.go | 73 ++- .../06-solomachine/types/client_state.go | 2 +- .../07-tendermint/client/cli/tx.go | 5 +- .../07-tendermint/types/client_state.go | 16 +- .../07-tendermint/types/client_state_test.go | 2 +- .../07-tendermint/types/tendermint.pb.go | 164 +++--- .../07-tendermint/types/tendermint_test.go | 3 +- .../07-tendermint/types/upgrade.go | 171 +++--- .../07-tendermint/types/upgrade_test.go | 363 +++++++----- .../09-localhost/types/client_state.go | 2 +- x/ibc/testing/chain.go | 2 +- x/upgrade/abci.go | 15 + x/upgrade/abci_test.go | 73 +++ x/upgrade/keeper/grpc_query.go | 20 + x/upgrade/keeper/keeper.go | 124 ++-- x/upgrade/keeper/keeper_test.go | 29 +- x/upgrade/types/keys.go | 17 +- x/upgrade/types/plan.go | 5 + x/upgrade/types/plan_test.go | 43 +- x/upgrade/types/proposal_test.go | 9 +- x/upgrade/types/query.pb.go | 446 +++++++++++++- x/upgrade/types/query.pb.gw.go | 98 +++ 36 files changed, 2035 insertions(+), 668 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 0b52dcf194..1038e7e698 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -15760,6 +15760,396 @@ paths: } tags: - Query + '/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}': + get: + summary: |- + UpgradedConsensusState queries the consensus state that will serve + as a trusted kernel for the next version of this chain. It will only be + stored at the last height of this chain. + UpgradedConsensusState RPC not supported with legacy querier + operationId: UpgradedConsensusState + responses: + '200': + description: A successful response. + schema: + type: object + properties: + upgraded_consensus_state: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all + types that they + + expect it to use in the context of Any. However, for URLs + which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message + along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in + the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default + use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the last + '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + description: >- + QueryUpgradedConsensusStateResponse is the response type for the + Query/UpgradedConsensusState + + RPC method. + default: + description: An unexpected error response. + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding + a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + parameters: + - name: last_height + description: |- + last height of the current chain must be sent in request + as this is the height under which next consensus state is stored + in: path + required: true + type: string + format: int64 + tags: + - Query /ibc/core/channel/v1beta1/channels: get: summary: Channels queries all the IBC channels of a chain. @@ -31438,6 +31828,173 @@ definitions: RPC method. + cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateResponse: + type: object + properties: + upgraded_consensus_state: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all types + that they + + expect it to use in the context of Any. However, for URLs which + use the + + scheme `http`, `https`, or no scheme, one can optionally set up a + type + + server that maps type URLs to message definitions as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above specified + type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message along + with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in the + form + + of utility functions or additional generated methods of the Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default use + + 'type.googleapis.com/full.type.name' as the type URL and the unpack + + methods only use the fully qualified type name after the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom JSON + + representation, that representation will be embedded adding a field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + description: >- + QueryUpgradedConsensusStateResponse is the response type for the + Query/UpgradedConsensusState + + RPC method. ibc.core.channel.v1.Channel: type: object properties: diff --git a/proto/cosmos/upgrade/v1beta1/query.proto b/proto/cosmos/upgrade/v1beta1/query.proto index d5c6bd7b2b..9eab27e76b 100644 --- a/proto/cosmos/upgrade/v1beta1/query.proto +++ b/proto/cosmos/upgrade/v1beta1/query.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package cosmos.upgrade.v1beta1; +import "google/protobuf/any.proto"; import "google/api/annotations.proto"; import "cosmos/upgrade/v1beta1/upgrade.proto"; @@ -17,6 +18,14 @@ service Query { rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; } + + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; + } } // QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC @@ -43,3 +52,17 @@ message QueryAppliedPlanResponse { // height is the block height at which the plan was applied. int64 height = 1; } + +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateRequest { + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + int64 last_height = 1; +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateResponse { + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/proto/ibc/core/client/v1/tx.proto b/proto/ibc/core/client/v1/tx.proto index fd54a92108..1019e15a03 100644 --- a/proto/ibc/core/client/v1/tx.proto +++ b/proto/ibc/core/client/v1/tx.proto @@ -60,16 +60,21 @@ message MsgUpdateClientResponse {} // MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client state message MsgUpgradeClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // client unique identifier string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; // upgraded client state google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; - // height at which old chain halts and upgrades (i.e last block executed) - Height upgrade_height = 3 [(gogoproto.moretags) = "yaml:\"upgrade_height\""]; + // upgraded consensus state, only contains enough information to serve as a basis of trust in update logic + google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; // proof that old chain committed to new client - bytes proof_upgrade = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade\""]; + bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; + // proof that old chain committed to new consensus state + bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; // signer address - string signer = 5; + string signer = 6; } // MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. diff --git a/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/proto/ibc/lightclients/tendermint/v1/tendermint.proto index 6f9285c057..840bd97739 100644 --- a/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -42,8 +42,12 @@ message ClientState { // Proof specifications used in verifying counterparty state repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; - // Path at which next upgraded client will be committed - string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the chained proof. + // NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` + // ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` + // For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` + repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; // This flag, when set to true, will allow governance to recover a client // which has expired diff --git a/x/ibc/core/02-client/keeper/client.go b/x/ibc/core/02-client/keeper/client.go index 5a6bb78d24..ddb742563c 100644 --- a/x/ibc/core/02-client/keeper/client.go +++ b/x/ibc/core/02-client/keeper/client.go @@ -107,7 +107,8 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H // UpgradeClient upgrades the client to a new client state if this new client was committed to // by the old client at the specified upgrade height -func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte) error { +func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient exported.ClientState, upgradedConsState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte) error { clientState, found := k.GetClientState(ctx, clientID) if !found { return sdkerrors.Wrapf(types.ErrClientNotFound, "cannot update client with ID %s", clientID) @@ -118,13 +119,14 @@ func (k Keeper) UpgradeClient(ctx sdk.Context, clientID string, upgradedClient e return sdkerrors.Wrapf(types.ErrClientFrozen, "cannot update client with ID %s", clientID) } - updatedClientState, updatedConsensusState, err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, k.ClientStore(ctx, clientID), upgradedClient, upgradeHeight, proofUpgrade) + updatedClientState, updatedConsState, err := clientState.VerifyUpgradeAndUpdateState(ctx, k.cdc, k.ClientStore(ctx, clientID), + upgradedClient, upgradedConsState, proofUpgradeClient, proofUpgradeConsState) if err != nil { return sdkerrors.Wrapf(err, "cannot upgrade client with ID %s", clientID) } k.SetClientState(ctx, clientID, updatedClientState) - k.SetClientConsensusState(ctx, clientID, updatedClientState.GetLatestHeight(), updatedConsensusState) + k.SetClientConsensusState(ctx, clientID, updatedClientState.GetLatestHeight(), updatedConsState) k.Logger(ctx).Info("client state upgraded", "client-id", clientID, "height", updatedClientState.GetLatestHeight().String()) diff --git a/x/ibc/core/02-client/keeper/client_test.go b/x/ibc/core/02-client/keeper/client_test.go index c2f5c8144a..8da8ac90b8 100644 --- a/x/ibc/core/02-client/keeper/client_test.go +++ b/x/ibc/core/02-client/keeper/client_test.go @@ -235,10 +235,11 @@ func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { func (suite *KeeperTestSuite) TestUpgradeClient() { var ( - upgradedClient exported.ClientState - upgradeHeight exported.Height - clientA string - proofUpgrade []byte + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight exported.Height + clientA string + proofUpgradedClient, proofUpgradedConsState []byte ) testCases := []struct { @@ -251,12 +252,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -267,7 +272,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: true, }, @@ -276,12 +282,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -292,7 +302,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) clientA = "wrongclientid" }, @@ -303,12 +314,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -319,7 +334,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) // set frozen client in store tmClient, ok := cs.(*ibctmtypes.ClientState) @@ -334,12 +350,16 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { setup: func() { upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, true, true) @@ -351,7 +371,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -363,7 +384,10 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { tc.setup() - err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradeHeight, proofUpgrade) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() + + err := suite.chainA.App.IBCKeeper.ClientKeeper.UpgradeClient(suite.chainA.GetContext(), clientA, upgradedClient, upgradedConsState, proofUpgradedClient, proofUpgradedConsState) if tc.expPass { suite.Require().NoError(err, "verify upgrade failed on valid case: %s", tc.name) diff --git a/x/ibc/core/02-client/keeper/keeper.go b/x/ibc/core/02-client/keeper/keeper.go index 7ebfa33555..cd39dba941 100644 --- a/x/ibc/core/02-client/keeper/keeper.go +++ b/x/ibc/core/02-client/keeper/keeper.go @@ -2,7 +2,6 @@ package keeper import ( "fmt" - "net/url" "reflect" "strings" @@ -246,13 +245,11 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS tmClient.UnbondingPeriod, tmClient.TrustingPeriod) } - if tmClient.UpgradePath != "" { + if len(tmClient.UpgradePath) != 0 { // For now, SDK IBC implementation assumes that upgrade path (if defined) is defined by SDK upgrade module - // Must escape any merkle key before adding it to upgrade path - upgradeKey := url.PathEscape(upgradetypes.KeyUpgradedClient) - expectedUpgradePath := fmt.Sprintf("%s/%s", upgradetypes.StoreKey, upgradeKey) - if tmClient.UpgradePath != expectedUpgradePath { - return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %s, got %s", + expectedUpgradePath := []string{upgradetypes.StoreKey, upgradetypes.KeyUpgradedIBCState} + if !reflect.DeepEqual(expectedUpgradePath, tmClient.UpgradePath) { + return sdkerrors.Wrapf(types.ErrInvalidClient, "upgrade path must be the upgrade path defined by upgrade module. expected %v, got %v", expectedUpgradePath, tmClient.UpgradePath) } } diff --git a/x/ibc/core/02-client/keeper/keeper_test.go b/x/ibc/core/02-client/keeper/keeper_test.go index c031ac37c9..61396655a3 100644 --- a/x/ibc/core/02-client/keeper/keeper_test.go +++ b/x/ibc/core/02-client/keeper/keeper_test.go @@ -166,7 +166,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "success with nil UpgradePath", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), "", false, false), + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil, false, false), true, }, { @@ -216,7 +216,7 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { }, { "invalid upgrade path", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), "bad/upgrade/path", false, false), + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), []string{"bad", "upgrade", "path"}, false, false), false, }, } diff --git a/x/ibc/core/02-client/types/codec.go b/x/ibc/core/02-client/types/codec.go index 64b2a3a4f1..8d79dcdaa4 100644 --- a/x/ibc/core/02-client/types/codec.go +++ b/x/ibc/core/02-client/types/codec.go @@ -37,6 +37,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*sdk.Msg)(nil), &MsgCreateClient{}, &MsgUpdateClient{}, + &MsgUpgradeClient{}, &MsgSubmitMisbehaviour{}, ) diff --git a/x/ibc/core/02-client/types/msgs.go b/x/ibc/core/02-client/types/msgs.go index 04b351eb26..d1d084ddad 100644 --- a/x/ibc/core/02-client/types/msgs.go +++ b/x/ibc/core/02-client/types/msgs.go @@ -182,23 +182,24 @@ func (msg MsgUpdateClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) err // NewMsgUpgradeClient creates a new MsgUpgradeClient instance // nolint: interfacer -func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte, signer sdk.AccAddress) (*MsgUpgradeClient, error) { +func NewMsgUpgradeClient(clientID string, clientState exported.ClientState, consState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte, signer sdk.AccAddress) (*MsgUpgradeClient, error) { anyClient, err := PackClientState(clientState) if err != nil { return nil, err } - - height, ok := upgradeHeight.(Height) - if !ok { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid height type. expected: %T, got: %T", &Height{}, upgradeHeight) + anyConsState, err := PackConsensusState(consState) + if err != nil { + return nil, err } return &MsgUpgradeClient{ - ClientId: clientID, - ClientState: anyClient, - ProofUpgrade: proofUpgrade, - UpgradeHeight: &height, - Signer: signer.String(), + ClientId: clientID, + ClientState: anyClient, + ConsensusState: anyConsState, + ProofUpgradeClient: proofUpgradeClient, + ProofUpgradeConsensusState: proofUpgradeConsState, + Signer: signer.String(), }, nil } @@ -214,21 +215,28 @@ func (msg MsgUpgradeClient) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgUpgradeClient) ValidateBasic() error { + // will not validate client state as committed client may not form a valid client state. + // client implementations are responsible for ensuring final upgraded client is valid. clientState, err := UnpackClientState(msg.ClientState) if err != nil { return err } - if err := clientState.Validate(); err != nil { + // will not validate consensus state here since the trusted kernel may not form a valid consenus state. + // client implementations are responsible for ensuring client can submit new headers against this consensus state. + consensusState, err := UnpackConsensusState(msg.ConsensusState) + if err != nil { return err } - if len(msg.ProofUpgrade) == 0 { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade cannot be empty") + + if clientState.ClientType() != consensusState.ClientType() { + return sdkerrors.Wrapf(ErrInvalidUpgradeClient, "consensus state's client-type does not match client. expected: %s, got: %s", + clientState.ClientType(), consensusState.ClientType()) } - if msg.UpgradeHeight == nil { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "upgrade height cannot be nil") + if len(msg.ProofUpgradeClient) == 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade client cannot be empty") } - if msg.UpgradeHeight.IsZero() { - return sdkerrors.Wrap(ErrInvalidUpgradeClient, "upgrade height cannot be zero") + if len(msg.ProofUpgradeConsensusState) == 0 { + return sdkerrors.Wrap(ErrInvalidUpgradeClient, "proof of upgrade consensus state cannot be empty") } _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -254,8 +262,14 @@ func (msg MsgUpgradeClient) GetSigners() []sdk.AccAddress { // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (msg MsgUpgradeClient) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { - var clientState exported.ClientState - return unpacker.UnpackAny(msg.ClientState, &clientState) + var ( + clientState exported.ClientState + consState exported.ConsensusState + ) + if err := unpacker.UnpackAny(msg.ClientState, &clientState); err != nil { + return err + } + return unpacker.UnpackAny(msg.ConsensusState, &consState) } // NewMsgSubmitMisbehaviour creates a new MsgSubmitMisbehaviour instance. diff --git a/x/ibc/core/02-client/types/msgs_test.go b/x/ibc/core/02-client/types/msgs_test.go index 7373205cc5..7781ea42b7 100644 --- a/x/ibc/core/02-client/types/msgs_test.go +++ b/x/ibc/core/02-client/types/msgs_test.go @@ -339,8 +339,6 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { err error ) - newClientHeight := types.NewHeight(1, 1) - testCases := []struct { name string malleate func() @@ -349,7 +347,8 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { "client upgrades to new tendermint client", func() { tendermintClient := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + tendermintConsState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + msg, err = types.NewMsgUpgradeClient("clientid", tendermintClient, tendermintConsState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, }, @@ -357,7 +356,7 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { "client upgrades to new solomachine client", func() { soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 1) - msg, err = types.NewMsgUpgradeClient("clientid", soloMachine.ClientState(), newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + msg, err = types.NewMsgUpgradeClient("clientid", soloMachine.ClientState(), soloMachine.ConsensusState(), []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, }, @@ -381,8 +380,6 @@ func (suite *TypesTestSuite) TestMarshalMsgUpgradeClient() { newMsg := &types.MsgUpgradeClient{} err = cdc.UnmarshalJSON(bz, newMsg) suite.Require().NoError(err) - - suite.Require().True(proto.Equal(msg, newMsg)) }) } } @@ -412,20 +409,6 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { }, expPass: false, }, - { - name: "upgrade height is nil", - malleate: func(msg *types.MsgUpgradeClient) { - msg.UpgradeHeight = nil - }, - expPass: false, - }, - { - name: "upgrade height is zero", - malleate: func(msg *types.MsgUpgradeClient) { - msg.UpgradeHeight = &types.Height{} - }, - expPass: false, - }, { name: "unpacking clientstate fails", malleate: func(msg *types.MsgUpgradeClient) { @@ -434,19 +417,33 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { expPass: false, }, { - name: "invalid client state", + name: "unpacking consensus state fails", malleate: func(msg *types.MsgUpgradeClient) { - cs := &ibctmtypes.ClientState{} - var err error - msg.ClientState, err = types.PackClientState(cs) - suite.Require().NoError(err) + msg.ConsensusState = nil }, expPass: false, }, { - name: "empty proof", + name: "client and consensus type does not match", malleate: func(msg *types.MsgUpgradeClient) { - msg.ProofUpgrade = nil + soloMachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachine", "", 2) + soloConsensus, err := types.PackConsensusState(soloMachine.ConsensusState()) + suite.Require().NoError(err) + msg.ConsensusState = soloConsensus + }, + expPass: false, + }, + { + name: "empty client proof", + malleate: func(msg *types.MsgUpgradeClient) { + msg.ProofUpgradeClient = nil + }, + expPass: false, + }, + { + name: "empty consensus state proof", + malleate: func(msg *types.MsgUpgradeClient) { + msg.ProofUpgradeConsensusState = nil }, expPass: false, }, @@ -463,18 +460,18 @@ func (suite *TypesTestSuite) TestMsgUpgradeClient_ValidateBasic() { tc := tc clientState := ibctmtypes.NewClientState(suite.chainA.ChainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - newClientHeight := types.NewHeight(1, 1) - msg, _ := types.NewMsgUpgradeClient("testclientid", clientState, newClientHeight, []byte("proofUpgrade"), suite.chainA.SenderAccount.GetAddress()) + consState := &ibctmtypes.ConsensusState{NextValidatorsHash: []byte("nextValsHash")} + msg, err := types.NewMsgUpgradeClient("testclientid", clientState, consState, []byte("proofUpgradeClient"), []byte("proofUpgradeConsState"), suite.chainA.SenderAccount.GetAddress()) + suite.Require().NoError(err) tc.malleate(msg) - err := msg.ValidateBasic() + err = msg.ValidateBasic() if tc.expPass { suite.Require().NoError(err, "valid case %s failed", tc.name) } else { suite.Require().Error(err, "invalid case %s passed", tc.name) } } - } // tests that different misbehaviours within MsgSubmitMisbehaviour can be marshaled diff --git a/x/ibc/core/02-client/types/tx.pb.go b/x/ibc/core/02-client/types/tx.pb.go index 4b637e5ba6..2a1a6b8885 100644 --- a/x/ibc/core/02-client/types/tx.pb.go +++ b/x/ibc/core/02-client/types/tx.pb.go @@ -199,12 +199,14 @@ type MsgUpgradeClient struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` // upgraded client state ClientState *types.Any `protobuf:"bytes,2,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` - // height at which old chain halts and upgrades (i.e last block executed) - UpgradeHeight *Height `protobuf:"bytes,3,opt,name=upgrade_height,json=upgradeHeight,proto3" json:"upgrade_height,omitempty" yaml:"upgrade_height"` + // upgraded consensus state, only contains enough information to serve as a basis of trust in update logic + ConsensusState *types.Any `protobuf:"bytes,3,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty" yaml:"consensus_state"` // proof that old chain committed to new client - ProofUpgrade []byte `protobuf:"bytes,4,opt,name=proof_upgrade,json=proofUpgrade,proto3" json:"proof_upgrade,omitempty" yaml:"proof_upgrade"` + ProofUpgradeClient []byte `protobuf:"bytes,4,opt,name=proof_upgrade_client,json=proofUpgradeClient,proto3" json:"proof_upgrade_client,omitempty" yaml:"proof_upgrade_client"` + // proof that old chain committed to new consensus state + ProofUpgradeConsensusState []byte `protobuf:"bytes,5,opt,name=proof_upgrade_consensus_state,json=proofUpgradeConsensusState,proto3" json:"proof_upgrade_consensus_state,omitempty" yaml:"proof_upgrade_consensus_state"` // signer address - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgUpgradeClient) Reset() { *m = MsgUpgradeClient{} } @@ -240,41 +242,6 @@ func (m *MsgUpgradeClient) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpgradeClient proto.InternalMessageInfo -func (m *MsgUpgradeClient) GetClientId() string { - if m != nil { - return m.ClientId - } - return "" -} - -func (m *MsgUpgradeClient) GetClientState() *types.Any { - if m != nil { - return m.ClientState - } - return nil -} - -func (m *MsgUpgradeClient) GetUpgradeHeight() *Height { - if m != nil { - return m.UpgradeHeight - } - return nil -} - -func (m *MsgUpgradeClient) GetProofUpgrade() []byte { - if m != nil { - return m.ProofUpgrade - } - return nil -} - -func (m *MsgUpgradeClient) GetSigner() string { - if m != nil { - return m.Signer - } - return "" -} - // MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. type MsgUpgradeClientResponse struct { } @@ -407,45 +374,45 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/tx.proto", fileDescriptor_cb5dc4651eb49a04) } var fileDescriptor_cb5dc4651eb49a04 = []byte{ - // 608 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0x3f, 0x6f, 0xd3, 0x40, - 0x14, 0x8f, 0x1b, 0x88, 0xda, 0x6b, 0xd2, 0x56, 0x26, 0x6d, 0x13, 0x23, 0xec, 0xca, 0x30, 0x14, - 0xd1, 0xda, 0x24, 0x0c, 0xa0, 0x4a, 0x0c, 0xa4, 0x0b, 0x0c, 0x91, 0xc0, 0x15, 0x03, 0x08, 0x29, - 0xf8, 0xcf, 0xf5, 0x62, 0x91, 0xf8, 0x22, 0xdf, 0x39, 0x6a, 0xbe, 0x01, 0x23, 0x12, 0x7c, 0x80, - 0x8a, 0x81, 0xcf, 0xc2, 0xc0, 0xd0, 0x91, 0x29, 0x42, 0xc9, 0xc2, 0x9c, 0x4f, 0x80, 0x7c, 0x77, - 0xb1, 0xec, 0x34, 0x89, 0x22, 0x58, 0x98, 0xe2, 0x77, 0xef, 0xf7, 0x7e, 0xef, 0xe7, 0xdf, 0x7b, - 0x17, 0x83, 0xdb, 0xbe, 0xe3, 0x9a, 0x2e, 0x0e, 0xa1, 0xe9, 0x76, 0x7c, 0x18, 0x50, 0xb3, 0x5f, - 0x33, 0xe9, 0x85, 0xd1, 0x0b, 0x31, 0xc5, 0xb2, 0xec, 0x3b, 0xae, 0x11, 0x27, 0x0d, 0x9e, 0x34, - 0xfa, 0x35, 0xa5, 0x8c, 0x30, 0xc2, 0x2c, 0x6d, 0xc6, 0x4f, 0x1c, 0xa9, 0x54, 0x11, 0xc6, 0xa8, - 0x03, 0x4d, 0x16, 0x39, 0xd1, 0xb9, 0x69, 0x07, 0x03, 0x91, 0xd2, 0xe6, 0x74, 0x10, 0x74, 0x0c, - 0xa0, 0x7f, 0x5e, 0x03, 0xdb, 0x4d, 0x82, 0x4e, 0x43, 0x68, 0x53, 0x78, 0xca, 0x32, 0x72, 0x0d, - 0x6c, 0x70, 0x4c, 0xcb, 0xf7, 0x2a, 0xd2, 0x81, 0x74, 0xb8, 0xd1, 0x28, 0x4f, 0x86, 0xda, 0xce, - 0xc0, 0xee, 0x76, 0x4e, 0xf4, 0x24, 0xa5, 0x5b, 0xeb, 0xfc, 0xf9, 0x85, 0x27, 0xbf, 0x04, 0x45, - 0x71, 0x4e, 0xa8, 0x4d, 0x61, 0x65, 0xed, 0x40, 0x3a, 0xdc, 0xac, 0x97, 0x0d, 0xae, 0xcc, 0x98, - 0x2a, 0x33, 0x9e, 0x05, 0x83, 0xc6, 0xfe, 0x64, 0xa8, 0xdd, 0xca, 0x70, 0xb1, 0x1a, 0xdd, 0xda, - 0xe4, 0xe1, 0x59, 0x1c, 0xc9, 0x6f, 0xc0, 0xb6, 0x8b, 0x03, 0x02, 0x03, 0x12, 0x11, 0x41, 0x9a, - 0x5f, 0x42, 0xaa, 0x4c, 0x86, 0xda, 0x9e, 0x20, 0xcd, 0x96, 0xe9, 0xd6, 0x56, 0x72, 0xc2, 0xa9, - 0xf7, 0x40, 0x81, 0xf8, 0x28, 0x80, 0x61, 0xe5, 0x46, 0xfc, 0x72, 0x96, 0x88, 0x4e, 0xd6, 0x3f, - 0x5e, 0x6a, 0xb9, 0xdf, 0x97, 0x5a, 0x4e, 0xaf, 0x82, 0xfd, 0x19, 0x53, 0x2c, 0x48, 0x7a, 0x31, - 0x8b, 0xfe, 0x45, 0x62, 0x86, 0xbd, 0xee, 0x79, 0xff, 0x64, 0xd8, 0x11, 0x28, 0xb4, 0xa1, 0xed, - 0xc1, 0x70, 0x99, 0x55, 0x96, 0xc0, 0xa4, 0x14, 0xe7, 0x97, 0x2a, 0x4e, 0xab, 0x4a, 0x14, 0xff, - 0x58, 0x03, 0x3b, 0x2c, 0x87, 0x42, 0xdb, 0xfb, 0xaf, 0x66, 0xfc, 0x0e, 0x6c, 0x45, 0x5c, 0x55, - 0xab, 0x0d, 0x7d, 0xd4, 0xa6, 0x62, 0xc4, 0x8a, 0x71, 0x7d, 0xf7, 0x8d, 0xe7, 0x0c, 0xd1, 0xa8, - 0x4e, 0x86, 0xda, 0x2e, 0x67, 0xce, 0xd6, 0xea, 0x56, 0x49, 0x1c, 0x70, 0xa4, 0xfc, 0x14, 0x94, - 0x7a, 0x21, 0xc6, 0xe7, 0x2d, 0x71, 0xcc, 0xa6, 0x5d, 0x6c, 0x54, 0x26, 0x43, 0xad, 0xcc, 0x09, - 0x32, 0x69, 0xdd, 0x2a, 0xb2, 0x58, 0xf8, 0x94, 0xf2, 0xfc, 0x66, 0xda, 0x73, 0x5d, 0x01, 0x95, - 0x59, 0x37, 0x13, 0xab, 0xbf, 0x49, 0x60, 0xb7, 0x49, 0xd0, 0x59, 0xe4, 0x74, 0x7d, 0xda, 0xf4, - 0x89, 0x03, 0xdb, 0x76, 0xdf, 0xc7, 0x51, 0xf8, 0x37, 0x7e, 0x3f, 0x01, 0xc5, 0x6e, 0x8a, 0x62, - 0xe9, 0xa2, 0x64, 0x90, 0x2b, 0xac, 0x8b, 0x06, 0xee, 0xcc, 0xd5, 0x39, 0x7d, 0x93, 0xfa, 0xd7, - 0x3c, 0xc8, 0x37, 0x09, 0x92, 0xdf, 0x83, 0x62, 0xe6, 0xbf, 0xe1, 0xee, 0xbc, 0xd1, 0xcc, 0xdc, - 0x15, 0xe5, 0xc1, 0x0a, 0xa0, 0x69, 0xa7, 0xb8, 0x43, 0xe6, 0x32, 0x2d, 0xea, 0x90, 0x06, 0x2d, - 0xec, 0x30, 0xef, 0x02, 0xc8, 0x2e, 0x28, 0x65, 0x97, 0xff, 0xde, 0xc2, 0xea, 0x14, 0x4a, 0x39, - 0x5a, 0x05, 0x95, 0x34, 0x09, 0x81, 0x3c, 0x67, 0xec, 0xf7, 0x17, 0x70, 0x5c, 0x87, 0x2a, 0xb5, - 0x95, 0xa1, 0xd3, 0x9e, 0x8d, 0x57, 0xdf, 0x47, 0xaa, 0x74, 0x35, 0x52, 0xa5, 0x5f, 0x23, 0x55, - 0xfa, 0x34, 0x56, 0x73, 0x57, 0x63, 0x35, 0xf7, 0x73, 0xac, 0xe6, 0xde, 0x3e, 0x46, 0x3e, 0x6d, - 0x47, 0x8e, 0xe1, 0xe2, 0xae, 0xe9, 0x62, 0xd2, 0xc5, 0x44, 0xfc, 0x1c, 0x13, 0xef, 0x83, 0x79, - 0x61, 0x26, 0x9f, 0x85, 0x87, 0xf5, 0x63, 0xf1, 0x65, 0xa0, 0x83, 0x1e, 0x24, 0x4e, 0x81, 0xad, - 0xd5, 0xa3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb1, 0x03, 0x55, 0x1e, 0x9b, 0x06, 0x00, 0x00, + // 598 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x55, 0x3f, 0x6f, 0xd3, 0x4e, + 0x18, 0x8e, 0x9b, 0xdf, 0x2f, 0x6a, 0xaf, 0x81, 0x56, 0x26, 0xb4, 0xa9, 0xab, 0xda, 0x95, 0xe9, + 0x10, 0x44, 0xeb, 0x23, 0x61, 0x00, 0x75, 0x23, 0x9d, 0x18, 0x22, 0x51, 0x57, 0x0c, 0xb0, 0x04, + 0xff, 0xb9, 0x5e, 0xac, 0x26, 0xbe, 0xc8, 0x67, 0x47, 0xcd, 0x37, 0x60, 0x44, 0x82, 0x0f, 0x50, + 0x31, 0xf0, 0x59, 0x18, 0x3b, 0x30, 0x30, 0x45, 0x28, 0x59, 0x98, 0xf3, 0x09, 0x90, 0xef, 0x1c, + 0xcb, 0x76, 0xed, 0x28, 0x82, 0x91, 0xc9, 0x7e, 0xef, 0x7d, 0xee, 0x79, 0x9e, 0x7b, 0xdf, 0xf7, + 0x6c, 0xb0, 0xef, 0x98, 0x16, 0xb4, 0x88, 0x87, 0xa0, 0xd5, 0x77, 0x90, 0xeb, 0xc3, 0x51, 0x13, + 0xfa, 0xd7, 0xda, 0xd0, 0x23, 0x3e, 0x11, 0x45, 0xc7, 0xb4, 0xb4, 0x30, 0xa9, 0xf1, 0xa4, 0x36, + 0x6a, 0x4a, 0x35, 0x4c, 0x30, 0x61, 0x69, 0x18, 0xbe, 0x71, 0xa4, 0xb4, 0x87, 0x09, 0xc1, 0x7d, + 0x04, 0x59, 0x64, 0x06, 0x97, 0xd0, 0x70, 0xc7, 0x51, 0x4a, 0xc9, 0x51, 0x88, 0xe8, 0x18, 0x40, + 0xfd, 0xb4, 0x06, 0xb6, 0x3a, 0x14, 0x9f, 0x79, 0xc8, 0xf0, 0xd1, 0x19, 0xcb, 0x88, 0x4d, 0xb0, + 0xc1, 0x31, 0x5d, 0xc7, 0xae, 0x0b, 0x87, 0x42, 0x63, 0xa3, 0x5d, 0x9b, 0x4f, 0x94, 0xed, 0xb1, + 0x31, 0xe8, 0x9f, 0xaa, 0x71, 0x4a, 0xd5, 0xd7, 0xf9, 0xfb, 0x2b, 0x5b, 0x7c, 0x0d, 0xaa, 0xd1, + 0x3a, 0xf5, 0x0d, 0x1f, 0xd5, 0xd7, 0x0e, 0x85, 0xc6, 0x66, 0xab, 0xa6, 0x71, 0x67, 0xda, 0xc2, + 0x99, 0xf6, 0xd2, 0x1d, 0xb7, 0x77, 0xe7, 0x13, 0xe5, 0x41, 0x8a, 0x8b, 0xed, 0x51, 0xf5, 0x4d, + 0x1e, 0x5e, 0x84, 0x91, 0xf8, 0x16, 0x6c, 0x59, 0xc4, 0xa5, 0xc8, 0xa5, 0x01, 0x8d, 0x48, 0xcb, + 0x4b, 0x48, 0xa5, 0xf9, 0x44, 0xd9, 0x89, 0x48, 0xd3, 0xdb, 0x54, 0xfd, 0x7e, 0xbc, 0xc2, 0xa9, + 0x77, 0x40, 0x85, 0x3a, 0xd8, 0x45, 0x5e, 0xfd, 0xbf, 0xf0, 0x70, 0x7a, 0x14, 0x9d, 0xae, 0x7f, + 0xb8, 0x51, 0x4a, 0xbf, 0x6e, 0x94, 0x92, 0xba, 0x07, 0x76, 0x33, 0x45, 0xd1, 0x11, 0x1d, 0x86, + 0x2c, 0xea, 0x67, 0x81, 0x15, 0xec, 0xcd, 0xd0, 0xfe, 0xab, 0x82, 0x1d, 0x83, 0x4a, 0x0f, 0x19, + 0x36, 0xf2, 0x96, 0x95, 0x4a, 0x8f, 0x30, 0x09, 0xc7, 0xe5, 0xa5, 0x8e, 0x93, 0xae, 0x62, 0xc7, + 0xdf, 0xcb, 0x60, 0x9b, 0xe5, 0xb0, 0x67, 0xd8, 0xff, 0x4a, 0x8f, 0xcf, 0x41, 0x6d, 0xe8, 0x11, + 0x72, 0xd9, 0x0d, 0xf8, 0xb1, 0xbb, 0x5c, 0x97, 0x75, 0xbc, 0xda, 0x56, 0xe6, 0x13, 0x65, 0x9f, + 0x33, 0xe5, 0xa1, 0x54, 0x5d, 0x64, 0xcb, 0xe9, 0x92, 0x5d, 0x81, 0x83, 0x0c, 0x38, 0xe3, 0xfd, + 0x7f, 0xc6, 0xdd, 0x98, 0x4f, 0x94, 0xa3, 0x5c, 0xee, 0xac, 0x67, 0x29, 0x25, 0x52, 0x34, 0xa3, + 0x95, 0x82, 0x8e, 0x4b, 0xa0, 0x9e, 0xed, 0x6a, 0xdc, 0xf2, 0xaf, 0x02, 0x78, 0xd8, 0xa1, 0xf8, + 0x22, 0x30, 0x07, 0x8e, 0xdf, 0x71, 0xa8, 0x89, 0x7a, 0xc6, 0xc8, 0x21, 0x81, 0xf7, 0x27, 0x7d, + 0x7f, 0x01, 0xaa, 0x83, 0x04, 0xc5, 0xd2, 0x81, 0x4d, 0x21, 0x57, 0x18, 0x5b, 0x05, 0x1c, 0xe4, + 0xfa, 0x5c, 0x9c, 0xa4, 0xf5, 0xa5, 0x0c, 0xca, 0x1d, 0x8a, 0xc5, 0xf7, 0xa0, 0x9a, 0xfa, 0x46, + 0x3d, 0xd2, 0xee, 0x7e, 0x1e, 0xb5, 0xcc, 0x9d, 0x95, 0x9e, 0xac, 0x00, 0x5a, 0x28, 0x85, 0x0a, + 0xa9, 0x4b, 0x5d, 0xa4, 0x90, 0x04, 0x15, 0x2a, 0xe4, 0x5d, 0x44, 0xd1, 0x02, 0xf7, 0xd2, 0x13, + 0x75, 0x54, 0xb8, 0x3b, 0x81, 0x92, 0x8e, 0x57, 0x41, 0xc5, 0x22, 0x1e, 0x10, 0x73, 0xda, 0xfe, + 0xb8, 0x80, 0xe3, 0x2e, 0x54, 0x6a, 0xae, 0x0c, 0x5d, 0x68, 0xb6, 0xcf, 0xbf, 0x4d, 0x65, 0xe1, + 0x76, 0x2a, 0x0b, 0x3f, 0xa7, 0xb2, 0xf0, 0x71, 0x26, 0x97, 0x6e, 0x67, 0x72, 0xe9, 0xc7, 0x4c, + 0x2e, 0xbd, 0x7b, 0x8e, 0x1d, 0xbf, 0x17, 0x98, 0x9a, 0x45, 0x06, 0xd0, 0x22, 0x74, 0x40, 0x68, + 0xf4, 0x38, 0xa1, 0xf6, 0x15, 0xbc, 0x86, 0xf1, 0xef, 0xe9, 0x69, 0xeb, 0x24, 0xfa, 0x43, 0xf9, + 0xe3, 0x21, 0xa2, 0x66, 0x85, 0x8d, 0xd5, 0xb3, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x19, + 0x59, 0x52, 0x23, 0x07, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -825,18 +792,25 @@ func (m *MsgUpgradeClient) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- + dAtA[i] = 0x32 + } + if len(m.ProofUpgradeConsensusState) > 0 { + i -= len(m.ProofUpgradeConsensusState) + copy(dAtA[i:], m.ProofUpgradeConsensusState) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgradeConsensusState))) + i-- dAtA[i] = 0x2a } - if len(m.ProofUpgrade) > 0 { - i -= len(m.ProofUpgrade) - copy(dAtA[i:], m.ProofUpgrade) - i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgrade))) + if len(m.ProofUpgradeClient) > 0 { + i -= len(m.ProofUpgradeClient) + copy(dAtA[i:], m.ProofUpgradeClient) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProofUpgradeClient))) i-- dAtA[i] = 0x22 } - if m.UpgradeHeight != nil { + if m.ConsensusState != nil { { - size, err := m.UpgradeHeight.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1052,11 +1026,15 @@ func (m *MsgUpgradeClient) Size() (n int) { l = m.ClientState.Size() n += 1 + l + sovTx(uint64(l)) } - if m.UpgradeHeight != nil { - l = m.UpgradeHeight.Size() + if m.ConsensusState != nil { + l = m.ConsensusState.Size() n += 1 + l + sovTx(uint64(l)) } - l = len(m.ProofUpgrade) + l = len(m.ProofUpgradeClient) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProofUpgradeConsensusState) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1659,7 +1637,7 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UpgradeHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1686,16 +1664,16 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.UpgradeHeight == nil { - m.UpgradeHeight = &Height{} + if m.ConsensusState == nil { + m.ConsensusState = &types.Any{} } - if err := m.UpgradeHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgrade", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgradeClient", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1722,12 +1700,46 @@ func (m *MsgUpgradeClient) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProofUpgrade = append(m.ProofUpgrade[:0], dAtA[iNdEx:postIndex]...) - if m.ProofUpgrade == nil { - m.ProofUpgrade = []byte{} + m.ProofUpgradeClient = append(m.ProofUpgradeClient[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgradeClient == nil { + m.ProofUpgradeClient = []byte{} } iNdEx = postIndex case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofUpgradeConsensusState", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProofUpgradeConsensusState = append(m.ProofUpgradeConsensusState[:0], dAtA[iNdEx:postIndex]...) + if m.ProofUpgradeConsensusState == nil { + m.ProofUpgradeConsensusState = []byte{} + } + iNdEx = postIndex + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/exported/client.go b/x/ibc/core/exported/client.go index 10d437cbce..50cd8bea30 100644 --- a/x/ibc/core/exported/client.go +++ b/x/ibc/core/exported/client.go @@ -39,13 +39,19 @@ type ClientState interface { CheckProposedHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error) // Upgrade functions + // NOTE: proof heights are not included as upgrade to a new version is expected to pass only on the last + // height committed by the current version. Clients are responsible for ensuring that the planned last + // height of the current version is somehow encoded in the proof verification process. + // This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty + // may be cancelled or modified before the last planned height. VerifyUpgradeAndUpdateState( ctx sdk.Context, cdc codec.BinaryMarshaler, store sdk.KVStore, newClient ClientState, - upgradeHeight Height, - proofUpgrade []byte, + newConsState ConsensusState, + proofUpgradeClient, + proofUpgradeConsState []byte, ) (ClientState, ConsensusState, error) // Utility function that zeroes out any client customizable fields in client state // Ledger enforced fields are maintained while all custom fields are zero values diff --git a/x/ibc/core/keeper/msg_server.go b/x/ibc/core/keeper/msg_server.go index c7579fdbba..9ca0697e1f 100644 --- a/x/ibc/core/keeper/msg_server.go +++ b/x/ibc/core/keeper/msg_server.go @@ -83,8 +83,13 @@ func (k Keeper) UpgradeClient(goCtx context.Context, msg *clienttypes.MsgUpgrade if err != nil { return nil, err } + upgradedConsState, err := clienttypes.UnpackConsensusState(msg.ConsensusState) + if err != nil { + return nil, err + } - if err = k.ClientKeeper.UpgradeClient(ctx, msg.ClientId, upgradedClient, msg.UpgradeHeight, msg.ProofUpgrade); err != nil { + if err = k.ClientKeeper.UpgradeClient(ctx, msg.ClientId, upgradedClient, upgradedConsState, + msg.ProofUpgradeClient, msg.ProofUpgradeConsensusState); err != nil { return nil, err } diff --git a/x/ibc/core/keeper/msg_server_test.go b/x/ibc/core/keeper/msg_server_test.go index 69a80fcb72..d2e54debe5 100644 --- a/x/ibc/core/keeper/msg_server_test.go +++ b/x/ibc/core/keeper/msg_server_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "testing" - "time" "github.com/stretchr/testify/suite" @@ -611,10 +610,11 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { func (suite *KeeperTestSuite) TestUpgradeClient() { var ( - clientA string - upgradedClient exported.ClientState - upgradeHeight exported.Height - msg *clienttypes.MsgUpgradeClient + clientA string + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight exported.Height + msg *clienttypes.MsgUpgradeClient ) newClientHeight := clienttypes.NewHeight(1, 1) @@ -628,13 +628,20 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { name: "successful upgrade", setup: func() { - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -645,46 +652,33 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradeClient, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradeHeight, proofUpgrade, suite.chainA.SenderAccount.GetAddress()) + msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, + proofUpgradeClient, proofUpgradedConsState, suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, expPass: true, }, - { - name: "invalid upgrade: msg.ClientState does not contain valid clientstate", - setup: func() { - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - proofUpgrade, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - - consState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("app_hash")), []byte("next_vals_hash")) - consAny, err := clienttypes.PackConsensusState(consState) - suite.Require().NoError(err) - - height, _ := upgradeHeight.(clienttypes.Height) - - msg = &clienttypes.MsgUpgradeClient{ClientId: clientA, ClientState: consAny, UpgradeHeight: &height, ProofUpgrade: proofUpgrade, Signer: suite.chainA.SenderAccount.GetAddress().String()} - }, - expPass: false, - }, { name: "VerifyUpgrade fails", setup: func() { - upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + upgradedClient = ibctmtypes.NewClientState("newChainId", ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod+ibctesting.TrustingPeriod, ibctesting.MaxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + upgradedConsState = &ibctmtypes.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // last Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -692,7 +686,7 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) suite.Require().NoError(err) - msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradeHeight, nil, suite.chainA.SenderAccount.GetAddress()) + msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, nil, nil, suite.chainA.SenderAccount.GetAddress()) suite.Require().NoError(err) }, expPass: false, @@ -711,7 +705,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { suite.Require().NoError(err, "upgrade handler failed on valid case: %s", tc.name) newClient, ok := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(ok) - suite.Require().Equal(upgradedClient, newClient) + newChainSpecifiedClient := newClient.ZeroCustomFields() + suite.Require().Equal(upgradedClient, newChainSpecifiedClient) } else { suite.Require().Error(err, "upgrade handler passed on invalid case: %s", tc.name) } diff --git a/x/ibc/light-clients/06-solomachine/types/client_state.go b/x/ibc/light-clients/06-solomachine/types/client_state.go index 4a6fb86962..e4a4aa72d9 100644 --- a/x/ibc/light-clients/06-solomachine/types/client_state.go +++ b/x/ibc/light-clients/06-solomachine/types/client_state.go @@ -77,7 +77,7 @@ func (cs ClientState) ZeroCustomFields() exported.ClientState { // VerifyUpgradeAndUpdateState returns an error since solomachine client does not support upgrades func (cs ClientState) VerifyUpgradeAndUpdateState( _ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, - _ exported.ClientState, _ exported.Height, _ []byte, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, ) (exported.ClientState, exported.ConsensusState, error) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade solomachine client") } diff --git a/x/ibc/light-clients/07-tendermint/client/cli/tx.go b/x/ibc/light-clients/07-tendermint/client/cli/tx.go index be2b4c4725..3bd2f0c0b7 100644 --- a/x/ibc/light-clients/07-tendermint/client/cli/tx.go +++ b/x/ibc/light-clients/07-tendermint/client/cli/tx.go @@ -39,7 +39,7 @@ func NewCreateClientCmd() *cobra.Command { Long: `Create a new tendermint IBC client. - 'trust-level' flag can be a fraction (eg: '1/3') or 'default' - 'proof-specs' flag can be JSON input, a path to a .json file or 'default' - - 'upgrade-path' flag is a string specifying the upgrade path for this chain where a future upgraded client will be stored. The path represents a keypath for the store with each key separated by a '/'. Any slash within a key must be escaped. + - 'upgrade-path' flag is a string specifying the upgrade path for this chain where a future upgraded client will be stored. The path is a comma-separated list representing the keys in order of the keyPath to the committed upgraded client. e.g. 'upgrade/upgradedClient'`, Example: fmt.Sprintf("%s tx ibc %s create [client-id] [path/to/consensus_state.json] [trusting_period] [unbonding_period] [max_clock_drift] --trust-level default --consensus-params [path/to/consensus-params.json] --proof-specs [path/to/proof-specs.json] --upgrade-path upgrade/upgradedClient --from node0 --home ../node0/cli --chain-id $CID", version.AppName, types.SubModuleName), Args: cobra.ExactArgs(5), @@ -119,7 +119,8 @@ func NewCreateClientCmd() *cobra.Command { allowUpdateAfterExpiry, _ := cmd.Flags().GetBool(flagAllowUpdateAfterExpiry) allowUpdateAfterMisbehaviour, _ := cmd.Flags().GetBool(flagAllowUpdateAfterMisbehaviour) - upgradePath, _ := cmd.Flags().GetString(flagUpgradePath) + upgradePathStr, _ := cmd.Flags().GetString(flagUpgradePath) + upgradePath := strings.Split(upgradePathStr, ",") // validate header if err := header.ValidateBasic(); err != nil { diff --git a/x/ibc/light-clients/07-tendermint/types/client_state.go b/x/ibc/light-clients/07-tendermint/types/client_state.go index 8cfc849541..976c837ad7 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state.go @@ -25,7 +25,7 @@ func NewClientState( chainID string, trustLevel Fraction, trustingPeriod, ubdPeriod, maxClockDrift time.Duration, latestHeight clienttypes.Height, specs []*ics23.ProofSpec, - upgradePath string, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool, + upgradePath []string, allowUpdateAfterExpiry, allowUpdateAfterMisbehaviour bool, ) *ClientState { return &ClientState{ ChainId: chainID, @@ -105,17 +105,15 @@ func (cs ClientState) Validate() error { if cs.ProofSpecs == nil { return sdkerrors.Wrap(ErrInvalidProofSpecs, "proof specs cannot be nil for tm client") } - for _, spec := range cs.ProofSpecs { + for i, spec := range cs.ProofSpecs { if spec == nil { - return sdkerrors.Wrap(ErrInvalidProofSpecs, "proof spec cannot be nil") + return sdkerrors.Wrapf(ErrInvalidProofSpecs, "proof spec cannot be nil at index: %d", i) } } - if cs.UpgradePath != "" { - keys := strings.Split(cs.UpgradePath, "/") - for _, k := range keys { - if strings.TrimSpace(k) == "" { - return sdkerrors.Wrapf(clienttypes.ErrInvalidUpgradeClient, "upgrade path contains an empty string when splitting by '/': %s", cs.UpgradePath) - } + // UpgradePath may be empty, but if it isn't, each key must be non-empty + for i, k := range cs.UpgradePath { + if strings.TrimSpace(k) == "" { + return sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "key in upgrade path at index %d cannot be empty", i) } } diff --git a/x/ibc/light-clients/07-tendermint/types/client_state_test.go b/x/ibc/light-clients/07-tendermint/types/client_state_test.go index 71f9f3fc3b..0e0c049006 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state_test.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state_test.go @@ -38,7 +38,7 @@ func (suite *TendermintTestSuite) TestValidate() { }, { name: "valid client with nil upgrade path", - clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), "", false, false), + clientState: types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), nil, false, false), expPass: true, }, { diff --git a/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go b/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go index df0967ef02..9993ed261d 100644 --- a/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go +++ b/x/ibc/light-clients/07-tendermint/types/tendermint.pb.go @@ -51,8 +51,12 @@ type ClientState struct { LatestHeight types.Height `protobuf:"bytes,7,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height" yaml:"latest_height"` // Proof specifications used in verifying counterparty state ProofSpecs []*_go.ProofSpec `protobuf:"bytes,8,rep,name=proof_specs,json=proofSpecs,proto3" json:"proof_specs,omitempty" yaml:"proof_specs"` - // Path at which next upgraded client will be committed - UpgradePath string `protobuf:"bytes,9,opt,name=upgrade_path,json=upgradePath,proto3" json:"upgrade_path,omitempty" yaml:"upgrade_path"` + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the chained proof. + // NOTE: ClientState must stored under `{upgradePath}/{upgradeHeight}/clientState` + // ConsensusState must be stored under `{upgradepath}/{upgradeHeight}/consensusState` + // For SDK chains using the default upgrade module, upgrade_path should be []string{"upgrade", "upgradedIBCState"}` + UpgradePath []string `protobuf:"bytes,9,rep,name=upgrade_path,json=upgradePath,proto3" json:"upgrade_path,omitempty" yaml:"upgrade_path"` // This flag, when set to true, will allow governance to recover a client // which has expired AllowUpdateAfterExpiry bool `protobuf:"varint,10,opt,name=allow_update_after_expiry,json=allowUpdateAfterExpiry,proto3" json:"allow_update_after_expiry,omitempty" yaml:"allow_update_after_expiry"` @@ -317,75 +321,75 @@ func init() { } var fileDescriptor_c6d6cf2b288949be = []byte{ - // 1079 bytes of a gzipped FileDescriptorProto + // 1081 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcf, 0x6f, 0xe3, 0xc4, - 0x17, 0x6f, 0xda, 0x7e, 0xb7, 0xe9, 0x24, 0xdd, 0xf6, 0xeb, 0x2d, 0xdd, 0xb4, 0x74, 0xe3, 0xc8, - 0xa0, 0xa5, 0x42, 0xaa, 0x4d, 0xb2, 0x48, 0x48, 0x15, 0x17, 0xdc, 0x82, 0x5a, 0xc4, 0x4a, 0x95, - 0xcb, 0x0f, 0x09, 0x09, 0xcc, 0xc4, 0x9e, 0x24, 0xa3, 0xda, 0x1e, 0xe3, 0x99, 0x84, 0x94, 0xbf, + 0x17, 0x6f, 0xda, 0x7e, 0xb7, 0xc9, 0x24, 0xdd, 0xf6, 0xeb, 0x2d, 0xdd, 0xb4, 0x74, 0xe3, 0xc8, + 0xa0, 0x25, 0x42, 0xaa, 0x4d, 0xb2, 0x48, 0x48, 0x15, 0x17, 0xdc, 0x82, 0x5a, 0xc4, 0x4a, 0x95, + 0xcb, 0x0f, 0x09, 0x09, 0xcc, 0xc4, 0x9e, 0xc4, 0xa3, 0xda, 0x1e, 0xe3, 0x99, 0x84, 0x94, 0xbf, 0x00, 0x0e, 0x48, 0x7b, 0x44, 0x9c, 0x38, 0xf0, 0xc7, 0xec, 0xb1, 0x47, 0x4e, 0x06, 0xb5, 0x17, - 0xce, 0x39, 0x72, 0x42, 0xf3, 0xc3, 0xf6, 0x34, 0xdb, 0xa5, 0x5a, 0x2e, 0xed, 0xbc, 0xf7, 0x3e, - 0xef, 0xf3, 0xc9, 0xbc, 0x79, 0xf3, 0xc6, 0xc0, 0xc1, 0xfd, 0xc0, 0x89, 0xf0, 0x70, 0xc4, 0x82, - 0x08, 0xa3, 0x84, 0x51, 0x87, 0xa1, 0x24, 0x44, 0x59, 0x8c, 0x13, 0xe6, 0x4c, 0xba, 0x9a, 0x65, - 0xa7, 0x19, 0x61, 0xc4, 0x68, 0xe3, 0x7e, 0x60, 0xeb, 0x09, 0xb6, 0x06, 0x99, 0x74, 0x77, 0x3a, - 0x5a, 0x3e, 0xbb, 0x48, 0x11, 0x75, 0x26, 0x30, 0xc2, 0x21, 0x64, 0x24, 0x93, 0x0c, 0x3b, 0xbb, - 0x2f, 0x20, 0xc4, 0x5f, 0x15, 0x7d, 0x10, 0x90, 0x64, 0x80, 0x89, 0x93, 0x66, 0x84, 0x0c, 0x0a, - 0x67, 0x7b, 0x48, 0xc8, 0x30, 0x42, 0x8e, 0xb0, 0xfa, 0xe3, 0x81, 0x13, 0x8e, 0x33, 0xc8, 0x30, - 0x49, 0x54, 0xdc, 0x9c, 0x8f, 0x33, 0x1c, 0x23, 0xca, 0x60, 0x9c, 0x16, 0x00, 0xbe, 0xcd, 0x80, - 0x64, 0xc8, 0x91, 0xbf, 0x9a, 0x6f, 0x4d, 0xae, 0x14, 0xe0, 0xad, 0x0a, 0x40, 0xe2, 0x18, 0xb3, - 0xb8, 0x00, 0x95, 0x96, 0x02, 0x6e, 0x0e, 0xc9, 0x90, 0x88, 0xa5, 0xc3, 0x57, 0xd2, 0x6b, 0xfd, - 0xb5, 0x02, 0x1a, 0x87, 0x82, 0xef, 0x8c, 0x41, 0x86, 0x8c, 0x6d, 0x50, 0x0f, 0x46, 0x10, 0x27, - 0x3e, 0x0e, 0x5b, 0xb5, 0x4e, 0x6d, 0x6f, 0xd5, 0x5b, 0x11, 0xf6, 0x49, 0x68, 0x20, 0xd0, 0x60, - 0xd9, 0x98, 0x32, 0x3f, 0x42, 0x13, 0x14, 0xb5, 0x16, 0x3b, 0xb5, 0xbd, 0x46, 0x6f, 0xcf, 0xfe, - 0xf7, 0xb2, 0xda, 0x1f, 0x65, 0x30, 0xe0, 0x1b, 0x76, 0x77, 0x9e, 0xe7, 0xe6, 0xc2, 0x2c, 0x37, - 0x8d, 0x0b, 0x18, 0x47, 0x07, 0x96, 0x46, 0x65, 0x79, 0x40, 0x58, 0x9f, 0x70, 0xc3, 0x18, 0x80, - 0x75, 0x61, 0xe1, 0x64, 0xe8, 0xa7, 0x28, 0xc3, 0x24, 0x6c, 0x2d, 0x09, 0xa9, 0x6d, 0x5b, 0x16, - 0xcb, 0x2e, 0x8a, 0x65, 0x1f, 0xa9, 0x62, 0xba, 0x96, 0xe2, 0xde, 0xd2, 0xb8, 0xab, 0x7c, 0xeb, - 0xe7, 0x3f, 0xcc, 0x9a, 0x77, 0xbf, 0xf0, 0x9e, 0x0a, 0xa7, 0x81, 0xc1, 0xc6, 0x38, 0xe9, 0x93, - 0x24, 0xd4, 0x84, 0x96, 0xef, 0x12, 0x7a, 0x43, 0x09, 0x3d, 0x94, 0x42, 0xf3, 0x04, 0x52, 0x69, - 0xbd, 0x74, 0x2b, 0x29, 0x04, 0xd6, 0x63, 0x38, 0xf5, 0x83, 0x88, 0x04, 0xe7, 0x7e, 0x98, 0xe1, - 0x01, 0x6b, 0xfd, 0xef, 0x15, 0xb7, 0x34, 0x97, 0x2f, 0x85, 0xd6, 0x62, 0x38, 0x3d, 0xe4, 0xce, - 0x23, 0xee, 0x33, 0xbe, 0x02, 0x6b, 0x83, 0x8c, 0x7c, 0x8f, 0x12, 0x7f, 0x84, 0xf8, 0x81, 0xb4, - 0xee, 0x09, 0x91, 0x1d, 0x71, 0x44, 0xbc, 0x45, 0x6c, 0xd5, 0x39, 0x93, 0xae, 0x7d, 0x2c, 0x10, - 0xee, 0xae, 0x52, 0xd9, 0x94, 0x2a, 0x37, 0xd2, 0x2d, 0xaf, 0x29, 0x6d, 0x89, 0xe5, 0xf4, 0x11, - 0x64, 0x88, 0xb2, 0x82, 0x7e, 0xe5, 0x55, 0xe9, 0x6f, 0xa4, 0x5b, 0x5e, 0x53, 0xda, 0x8a, 0xfe, - 0x04, 0x34, 0xc4, 0xd5, 0xf1, 0x69, 0x8a, 0x02, 0xda, 0xaa, 0x77, 0x96, 0xf6, 0x1a, 0xbd, 0x0d, - 0x1b, 0x07, 0xb4, 0xf7, 0xc4, 0x3e, 0xe5, 0x91, 0xb3, 0x14, 0x05, 0xee, 0x56, 0xd5, 0x42, 0x1a, - 0xdc, 0xf2, 0x40, 0x5a, 0x40, 0xa8, 0x71, 0x00, 0x9a, 0xe3, 0x74, 0x98, 0xc1, 0x10, 0xf9, 0x29, - 0x64, 0xa3, 0xd6, 0x2a, 0x6f, 0x64, 0xf7, 0xe1, 0x2c, 0x37, 0x1f, 0xa8, 0x73, 0xd3, 0xa2, 0x96, - 0xd7, 0x50, 0xe6, 0x29, 0x64, 0x23, 0xc3, 0x07, 0xdb, 0x30, 0x8a, 0xc8, 0x77, 0xfe, 0x38, 0x0d, - 0x21, 0x43, 0x3e, 0x1c, 0x30, 0x94, 0xf9, 0x68, 0x9a, 0xe2, 0xec, 0xa2, 0x05, 0x3a, 0xb5, 0xbd, - 0xba, 0xfb, 0xe6, 0x2c, 0x37, 0x3b, 0x92, 0xe8, 0xa5, 0x50, 0xcb, 0xdb, 0x12, 0xb1, 0xcf, 0x44, - 0xe8, 0x03, 0x1e, 0xf9, 0x50, 0x04, 0x8c, 0x6f, 0x81, 0x79, 0x4b, 0x56, 0x8c, 0x69, 0x1f, 0x8d, - 0xe0, 0x04, 0x93, 0x71, 0xd6, 0x6a, 0x08, 0x99, 0xb7, 0x67, 0xb9, 0xf9, 0xf8, 0xa5, 0x32, 0x7a, - 0x82, 0xe5, 0xed, 0xce, 0x8b, 0x3d, 0xd5, 0xc2, 0x07, 0xcb, 0x3f, 0xfc, 0x6a, 0x2e, 0x58, 0xbf, - 0x2d, 0x82, 0xfb, 0x87, 0x24, 0xa1, 0x28, 0xa1, 0x63, 0x2a, 0x6f, 0xbb, 0x0b, 0x56, 0xcb, 0x81, - 0x23, 0xae, 0x3b, 0x3f, 0xce, 0xf9, 0x96, 0xfc, 0xb4, 0x40, 0xb8, 0x75, 0x7e, 0x9c, 0xcf, 0x78, - 0xe7, 0x55, 0x69, 0xc6, 0xfb, 0x60, 0x39, 0x23, 0x84, 0xa9, 0x79, 0x60, 0x69, 0xdd, 0x50, 0x4d, - 0xa0, 0x49, 0xd7, 0x7e, 0x8a, 0xb2, 0xf3, 0x08, 0x79, 0x84, 0x30, 0x77, 0x99, 0xd3, 0x78, 0x22, - 0xcb, 0xf8, 0xb1, 0x06, 0x36, 0x13, 0x34, 0x65, 0x7e, 0x39, 0x6c, 0xa9, 0x3f, 0x82, 0x74, 0x24, - 0xee, 0x7c, 0xd3, 0xfd, 0x62, 0x96, 0x9b, 0xaf, 0xcb, 0x1a, 0xdc, 0x86, 0xb2, 0xfe, 0xce, 0xcd, - 0x77, 0x87, 0x98, 0x8d, 0xc6, 0x7d, 0x2e, 0xa7, 0x3f, 0x01, 0xda, 0x32, 0xc2, 0x7d, 0xea, 0xf4, - 0x2f, 0x18, 0xa2, 0xf6, 0x31, 0x9a, 0xba, 0x7c, 0xe1, 0x19, 0x9c, 0xee, 0xf3, 0x92, 0xed, 0x18, - 0xd2, 0x91, 0x2a, 0xd3, 0x4f, 0x8b, 0xa0, 0xa9, 0x57, 0xcf, 0xe8, 0x82, 0x55, 0xd9, 0xd8, 0xe5, - 0x4c, 0x74, 0x37, 0x67, 0xb9, 0xb9, 0x21, 0x7f, 0x56, 0x19, 0xb2, 0xbc, 0xba, 0x5c, 0x9f, 0x84, - 0x06, 0x04, 0xf5, 0x11, 0x82, 0x21, 0xca, 0xfc, 0xae, 0xaa, 0xcb, 0xe3, 0xbb, 0xe6, 0xe4, 0xb1, - 0xc0, 0xbb, 0xed, 0xab, 0xdc, 0x5c, 0x91, 0xeb, 0xee, 0x2c, 0x37, 0xd7, 0xa5, 0x48, 0x41, 0x66, - 0x79, 0x2b, 0x72, 0xd9, 0xd5, 0x24, 0x7a, 0x6a, 0x3e, 0xfe, 0x07, 0x89, 0xde, 0x0b, 0x12, 0xbd, - 0x52, 0xa2, 0xa7, 0xea, 0xf1, 0xcb, 0x12, 0xb8, 0x27, 0xd1, 0x06, 0x04, 0x6b, 0x14, 0x0f, 0x13, - 0x14, 0xfa, 0x12, 0xa2, 0x5a, 0xa6, 0xad, 0xeb, 0xc8, 0x27, 0xf1, 0x4c, 0xc0, 0x94, 0xe0, 0xee, - 0x65, 0x6e, 0xd6, 0xaa, 0x29, 0x70, 0x83, 0xc2, 0xf2, 0x9a, 0x54, 0xc3, 0xf2, 0x21, 0x53, 0x9e, - 0xb1, 0x4f, 0x51, 0xd1, 0x56, 0xb7, 0x48, 0x94, 0x87, 0x77, 0x86, 0x98, 0xdb, 0xaa, 0xe8, 0x6f, - 0xa4, 0x5b, 0x5e, 0x73, 0xa2, 0xe1, 0x8c, 0x6f, 0x80, 0x7c, 0x06, 0x84, 0xbe, 0x18, 0x62, 0x4b, - 0x77, 0x0e, 0xb1, 0x47, 0x6a, 0x88, 0xbd, 0xa6, 0x3d, 0x2e, 0x65, 0xbe, 0xe5, 0xad, 0x29, 0x87, - 0x1a, 0x63, 0x11, 0x30, 0x0a, 0x44, 0xd5, 0xac, 0xea, 0x61, 0xb9, 0x6b, 0x17, 0x8f, 0x66, 0xb9, - 0xb9, 0x7d, 0x53, 0xa5, 0xe2, 0xb0, 0xbc, 0xff, 0x2b, 0x67, 0xd5, 0xb6, 0xd6, 0xc7, 0xa0, 0x5e, - 0x3c, 0xb0, 0xc6, 0x2e, 0x58, 0x4d, 0xc6, 0x31, 0xca, 0x78, 0x44, 0x9c, 0xcc, 0xb2, 0x57, 0x39, - 0x8c, 0x0e, 0x68, 0x84, 0x28, 0x21, 0x31, 0x4e, 0x44, 0x7c, 0x51, 0xc4, 0x75, 0x97, 0xfb, 0xf5, - 0xf3, 0xab, 0x76, 0xed, 0xf2, 0xaa, 0x5d, 0xfb, 0xf3, 0xaa, 0x5d, 0x7b, 0x76, 0xdd, 0x5e, 0xb8, - 0xbc, 0x6e, 0x2f, 0xfc, 0x7e, 0xdd, 0x5e, 0xf8, 0xf2, 0x48, 0xbb, 0x62, 0x01, 0xa1, 0x31, 0xa1, - 0xea, 0xdf, 0x3e, 0x0d, 0xcf, 0x9d, 0x69, 0xf5, 0x29, 0xb6, 0x5f, 0x7c, 0x8b, 0xbd, 0xf3, 0xde, - 0xfe, 0xfc, 0xc7, 0x52, 0xff, 0x9e, 0x98, 0x28, 0x4f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x4c, - 0xb7, 0x2c, 0x8e, 0xba, 0x09, 0x00, 0x00, + 0xce, 0x39, 0x72, 0x42, 0x9e, 0x19, 0xdb, 0xd3, 0x6c, 0x97, 0x6a, 0xb9, 0xb4, 0xf3, 0xde, 0xfb, + 0xbc, 0xcf, 0x27, 0xf3, 0xe6, 0xcd, 0x1b, 0x03, 0x0b, 0x0f, 0x3d, 0x2b, 0xc4, 0xe3, 0x80, 0x79, + 0x21, 0x46, 0x31, 0xa3, 0x16, 0x43, 0xb1, 0x8f, 0xd2, 0x08, 0xc7, 0xcc, 0x9a, 0xf6, 0x15, 0xcb, + 0x4c, 0x52, 0xc2, 0x88, 0xd6, 0xc1, 0x43, 0xcf, 0x54, 0x13, 0x4c, 0x05, 0x32, 0xed, 0xef, 0x76, + 0x95, 0x7c, 0x76, 0x91, 0x20, 0x6a, 0x4d, 0x61, 0x88, 0x7d, 0xc8, 0x48, 0x2a, 0x18, 0x76, 0xf7, + 0x5e, 0x40, 0xf0, 0xbf, 0x32, 0xfa, 0xc0, 0x23, 0xf1, 0x08, 0x13, 0x2b, 0x49, 0x09, 0x19, 0x15, + 0xce, 0xce, 0x98, 0x90, 0x71, 0x88, 0x2c, 0x6e, 0x0d, 0x27, 0x23, 0xcb, 0x9f, 0xa4, 0x90, 0x61, + 0x12, 0xcb, 0xb8, 0xbe, 0x18, 0x67, 0x38, 0x42, 0x94, 0xc1, 0x28, 0x29, 0x00, 0xf9, 0x36, 0x3d, + 0x92, 0x22, 0x4b, 0xfc, 0xea, 0x7c, 0x6b, 0x62, 0x25, 0x01, 0x6f, 0x55, 0x00, 0x12, 0x45, 0x98, + 0x45, 0x05, 0xa8, 0xb4, 0x24, 0x70, 0x6b, 0x4c, 0xc6, 0x84, 0x2f, 0xad, 0x7c, 0x25, 0xbc, 0xc6, + 0x5f, 0x6b, 0xa0, 0x79, 0xc8, 0xf9, 0xce, 0x18, 0x64, 0x48, 0xdb, 0x01, 0x75, 0x2f, 0x80, 0x38, + 0x76, 0xb1, 0xdf, 0xae, 0x75, 0x6b, 0xbd, 0x86, 0xb3, 0xc6, 0xed, 0x13, 0x5f, 0x43, 0xa0, 0xc9, + 0xd2, 0x09, 0x65, 0x6e, 0x88, 0xa6, 0x28, 0x6c, 0x2f, 0x77, 0x6b, 0xbd, 0xe6, 0xa0, 0x67, 0xfe, + 0x7b, 0x59, 0xcd, 0x8f, 0x52, 0xe8, 0xe5, 0x1b, 0xb6, 0x77, 0x9f, 0x67, 0xfa, 0xd2, 0x3c, 0xd3, + 0xb5, 0x0b, 0x18, 0x85, 0x07, 0x86, 0x42, 0x65, 0x38, 0x80, 0x5b, 0x9f, 0xe4, 0x86, 0x36, 0x02, + 0x1b, 0xdc, 0xc2, 0xf1, 0xd8, 0x4d, 0x50, 0x8a, 0x89, 0xdf, 0x5e, 0xe1, 0x52, 0x3b, 0xa6, 0x28, + 0x96, 0x59, 0x14, 0xcb, 0x3c, 0x92, 0xc5, 0xb4, 0x0d, 0xc9, 0xbd, 0xad, 0x70, 0x57, 0xf9, 0xc6, + 0xcf, 0x7f, 0xe8, 0x35, 0xe7, 0x7e, 0xe1, 0x3d, 0xe5, 0x4e, 0x0d, 0x83, 0xcd, 0x49, 0x3c, 0x24, + 0xb1, 0xaf, 0x08, 0xad, 0xde, 0x25, 0xf4, 0x86, 0x14, 0x7a, 0x28, 0x84, 0x16, 0x09, 0x84, 0xd2, + 0x46, 0xe9, 0x96, 0x52, 0x08, 0x6c, 0x44, 0x70, 0xe6, 0x7a, 0x21, 0xf1, 0xce, 0x5d, 0x3f, 0xc5, + 0x23, 0xd6, 0xfe, 0xdf, 0x2b, 0x6e, 0x69, 0x21, 0x5f, 0x08, 0xad, 0x47, 0x70, 0x76, 0x98, 0x3b, + 0x8f, 0x72, 0x9f, 0xf6, 0x15, 0x58, 0x1f, 0xa5, 0xe4, 0x7b, 0x14, 0xbb, 0x01, 0xca, 0x0f, 0xa4, + 0x7d, 0x8f, 0x8b, 0xec, 0xf2, 0x23, 0xca, 0x5b, 0xc4, 0x94, 0x9d, 0x33, 0xed, 0x9b, 0xc7, 0x1c, + 0x61, 0xef, 0x49, 0x95, 0x2d, 0xa1, 0x72, 0x23, 0xdd, 0x70, 0x5a, 0xc2, 0x16, 0xd8, 0x9c, 0x3e, + 0x84, 0x0c, 0x51, 0x56, 0xd0, 0xaf, 0xbd, 0x2a, 0xfd, 0x8d, 0x74, 0xc3, 0x69, 0x09, 0x5b, 0xd2, + 0x9f, 0x80, 0x26, 0xbf, 0x3a, 0x2e, 0x4d, 0x90, 0x47, 0xdb, 0xf5, 0xee, 0x4a, 0xaf, 0x39, 0xd8, + 0x34, 0xb1, 0x47, 0x07, 0x4f, 0xcc, 0xd3, 0x3c, 0x72, 0x96, 0x20, 0xcf, 0xde, 0xae, 0x5a, 0x48, + 0x81, 0x1b, 0x0e, 0x48, 0x0a, 0x08, 0xd5, 0x0e, 0x40, 0x6b, 0x92, 0x8c, 0x53, 0xe8, 0x23, 0x37, + 0x81, 0x2c, 0x68, 0x37, 0xba, 0x2b, 0xbd, 0x86, 0xfd, 0x70, 0x9e, 0xe9, 0x0f, 0xe4, 0xb9, 0x29, + 0x51, 0xc3, 0x69, 0x4a, 0xf3, 0x14, 0xb2, 0x40, 0x73, 0xc1, 0x0e, 0x0c, 0x43, 0xf2, 0x9d, 0x3b, + 0x49, 0x7c, 0xc8, 0x90, 0x0b, 0x47, 0x0c, 0xa5, 0x2e, 0x9a, 0x25, 0x38, 0xbd, 0x68, 0x83, 0x6e, + 0xad, 0x57, 0xb7, 0xdf, 0x9c, 0x67, 0x7a, 0x57, 0x10, 0xbd, 0x14, 0x6a, 0x38, 0xdb, 0x3c, 0xf6, + 0x19, 0x0f, 0x7d, 0x90, 0x47, 0x3e, 0xe4, 0x01, 0xed, 0x5b, 0xa0, 0xdf, 0x92, 0x15, 0x61, 0x3a, + 0x44, 0x01, 0x9c, 0x62, 0x32, 0x49, 0xdb, 0x4d, 0x2e, 0xf3, 0xf6, 0x3c, 0xd3, 0x1f, 0xbf, 0x54, + 0x46, 0x4d, 0x30, 0x9c, 0xbd, 0x45, 0xb1, 0xa7, 0x4a, 0xf8, 0x60, 0xf5, 0x87, 0x5f, 0xf5, 0x25, + 0xe3, 0xb7, 0x65, 0x70, 0xff, 0x90, 0xc4, 0x14, 0xc5, 0x74, 0x42, 0xc5, 0x6d, 0xb7, 0x41, 0xa3, + 0x1c, 0x38, 0xfc, 0xba, 0xe7, 0xc7, 0xb9, 0xd8, 0x92, 0x9f, 0x16, 0x08, 0xbb, 0x9e, 0x1f, 0xe7, + 0xb3, 0xbc, 0xf3, 0xaa, 0x34, 0xed, 0x7d, 0xb0, 0x9a, 0x12, 0xc2, 0xe4, 0x3c, 0x30, 0x94, 0x6e, + 0xa8, 0x26, 0xd0, 0xb4, 0x6f, 0x3e, 0x45, 0xe9, 0x79, 0x88, 0x1c, 0x42, 0x98, 0xbd, 0x9a, 0xd3, + 0x38, 0x3c, 0x4b, 0xfb, 0xb1, 0x06, 0xb6, 0x62, 0x34, 0x63, 0x6e, 0x39, 0x6c, 0xa9, 0x1b, 0x40, + 0x1a, 0xf0, 0x3b, 0xdf, 0xb2, 0xbf, 0x98, 0x67, 0xfa, 0xeb, 0xa2, 0x06, 0xb7, 0xa1, 0x8c, 0xbf, + 0x33, 0xfd, 0xdd, 0x31, 0x66, 0xc1, 0x64, 0x98, 0xcb, 0xa9, 0x4f, 0x80, 0xb2, 0x0c, 0xf1, 0x90, + 0x5a, 0xc3, 0x0b, 0x86, 0xa8, 0x79, 0x8c, 0x66, 0x76, 0xbe, 0x70, 0xb4, 0x9c, 0xee, 0xf3, 0x92, + 0xed, 0x18, 0xd2, 0x40, 0x96, 0xe9, 0xa7, 0x65, 0xd0, 0x52, 0xab, 0xa7, 0xf5, 0x41, 0x43, 0x34, + 0x76, 0x39, 0x13, 0xed, 0xad, 0x79, 0xa6, 0x6f, 0x8a, 0x9f, 0x55, 0x86, 0x0c, 0xa7, 0x2e, 0xd6, + 0x27, 0xbe, 0x06, 0x41, 0x3d, 0x40, 0xd0, 0x47, 0xa9, 0xdb, 0x97, 0x75, 0x79, 0x7c, 0xd7, 0x9c, + 0x3c, 0xe6, 0x78, 0xbb, 0x73, 0x95, 0xe9, 0x6b, 0x62, 0xdd, 0x9f, 0x67, 0xfa, 0x86, 0x10, 0x29, + 0xc8, 0x0c, 0x67, 0x4d, 0x2c, 0xfb, 0x8a, 0xc4, 0x40, 0xce, 0xc7, 0xff, 0x20, 0x31, 0x78, 0x41, + 0x62, 0x50, 0x4a, 0x0c, 0x64, 0x3d, 0x7e, 0x59, 0x01, 0xf7, 0x04, 0x5a, 0x83, 0x60, 0x9d, 0xe2, + 0x71, 0x8c, 0x7c, 0x57, 0x40, 0x64, 0xcb, 0x74, 0x54, 0x1d, 0xf1, 0x24, 0x9e, 0x71, 0x98, 0x14, + 0xdc, 0xbb, 0xcc, 0xf4, 0x5a, 0x35, 0x05, 0x6e, 0x50, 0x18, 0x4e, 0x8b, 0x2a, 0xd8, 0x7c, 0xc8, + 0x94, 0x67, 0xec, 0x52, 0x54, 0xb4, 0xd5, 0x2d, 0x12, 0xe5, 0xe1, 0x9d, 0x21, 0x66, 0xb7, 0x2b, + 0xfa, 0x1b, 0xe9, 0x86, 0xd3, 0x9a, 0x2a, 0x38, 0xed, 0x1b, 0x20, 0x9e, 0x01, 0xae, 0xcf, 0x87, + 0xd8, 0xca, 0x9d, 0x43, 0xec, 0x91, 0x1c, 0x62, 0xaf, 0x29, 0x8f, 0x4b, 0x99, 0x6f, 0x38, 0xeb, + 0xd2, 0x21, 0xc7, 0x58, 0x08, 0xb4, 0x02, 0x51, 0x35, 0xab, 0x7c, 0x58, 0xee, 0xda, 0xc5, 0xa3, + 0x79, 0xa6, 0xef, 0xdc, 0x54, 0xa9, 0x38, 0x0c, 0xe7, 0xff, 0xd2, 0x59, 0xb5, 0xad, 0xf1, 0x31, + 0xa8, 0x17, 0x0f, 0xac, 0xb6, 0x07, 0x1a, 0xf1, 0x24, 0x42, 0x69, 0x1e, 0xe1, 0x27, 0xb3, 0xea, + 0x54, 0x0e, 0xad, 0x0b, 0x9a, 0x3e, 0x8a, 0x49, 0x84, 0x63, 0x1e, 0x5f, 0xe6, 0x71, 0xd5, 0x65, + 0x7f, 0xfd, 0xfc, 0xaa, 0x53, 0xbb, 0xbc, 0xea, 0xd4, 0xfe, 0xbc, 0xea, 0xd4, 0x9e, 0x5d, 0x77, + 0x96, 0x2e, 0xaf, 0x3b, 0x4b, 0xbf, 0x5f, 0x77, 0x96, 0xbe, 0x3c, 0x52, 0xae, 0x98, 0x47, 0x68, + 0x44, 0xa8, 0xfc, 0xb7, 0x4f, 0xfd, 0x73, 0x6b, 0x56, 0x7d, 0x8a, 0xed, 0x17, 0xdf, 0x62, 0xef, + 0xbc, 0xb7, 0xbf, 0xf8, 0xb1, 0x34, 0xbc, 0xc7, 0x27, 0xca, 0x93, 0x7f, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x8f, 0xde, 0xf9, 0xa9, 0xba, 0x09, 0x00, 0x00, } func (m *ClientState) Marshal() (dAtA []byte, err error) { @@ -429,11 +433,13 @@ func (m *ClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x50 } if len(m.UpgradePath) > 0 { - i -= len(m.UpgradePath) - copy(dAtA[i:], m.UpgradePath) - i = encodeVarintTendermint(dAtA, i, uint64(len(m.UpgradePath))) - i-- - dAtA[i] = 0x4a + for iNdEx := len(m.UpgradePath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.UpgradePath[iNdEx]) + copy(dAtA[i:], m.UpgradePath[iNdEx]) + i = encodeVarintTendermint(dAtA, i, uint64(len(m.UpgradePath[iNdEx]))) + i-- + dAtA[i] = 0x4a + } } if len(m.ProofSpecs) > 0 { for iNdEx := len(m.ProofSpecs) - 1; iNdEx >= 0; iNdEx-- { @@ -756,9 +762,11 @@ func (m *ClientState) Size() (n int) { n += 1 + l + sovTendermint(uint64(l)) } } - l = len(m.UpgradePath) - if l > 0 { - n += 1 + l + sovTendermint(uint64(l)) + if len(m.UpgradePath) > 0 { + for _, s := range m.UpgradePath { + l = len(s) + n += 1 + l + sovTendermint(uint64(l)) + } } if m.AllowUpdateAfterExpiry { n += 2 @@ -1174,7 +1182,7 @@ func (m *ClientState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.UpgradePath = string(dAtA[iNdEx:postIndex]) + m.UpgradePath = append(m.UpgradePath, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 10: if wireType != 0 { diff --git a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go index c30a784a5c..34f0e50ef5 100644 --- a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go +++ b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go @@ -1,7 +1,6 @@ package types_test import ( - "fmt" "testing" "time" @@ -32,7 +31,7 @@ const ( var ( height = clienttypes.NewHeight(0, 4) newClientHeight = clienttypes.NewHeight(1, 1) - upgradePath = fmt.Sprintf("%s/%s", "upgrade", "upgradedClient") + upgradePath = []string{"upgrade", "upgradedIBCState"} ) type TendermintTestSuite struct { diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade.go b/x/ibc/light-clients/07-tendermint/types/upgrade.go index dcd3cd1a5f..e058d77160 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade.go @@ -2,8 +2,6 @@ package types import ( "fmt" - "net/url" - "strings" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,6 +9,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/23-commitment/types" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) // VerifyUpgradeAndUpdateState checks if the upgraded client has been committed by the current client @@ -26,102 +25,130 @@ import ( // and ProofSpecs do not match parameters set by committed client func (cs ClientState) VerifyUpgradeAndUpdateState( ctx sdk.Context, cdc codec.BinaryMarshaler, clientStore sdk.KVStore, - upgradedClient exported.ClientState, upgradeHeight exported.Height, proofUpgrade []byte, + upgradedClient exported.ClientState, upgradedConsState exported.ConsensusState, + proofUpgradeClient, proofUpgradeConsState []byte, ) (exported.ClientState, exported.ConsensusState, error) { - if cs.UpgradePath == "" { + if len(cs.UpgradePath) == 0 { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, no upgrade path set") } - upgradePath, err := constructUpgradeMerklePath(cs.UpgradePath, upgradeHeight) - if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade client, unescaping key with URL format failed: %v", err) - } - // UpgradeHeight must be in same version as client state height - if cs.GetLatestHeight().GetVersionNumber() != upgradeHeight.GetVersionNumber() { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version at which upgrade occurs must be same as current client version. expected version %d, got %d", - cs.GetLatestHeight().GetVersionNumber(), upgradeHeight.GetVersionNumber()) - } + // last height of current counterparty chain must be client's latest height + lastHeight := cs.GetLatestHeight() - // UpgradeHeight must be greater than or equal to current client state height - if cs.GetLatestHeight().GetVersionHeight() > upgradeHeight.GetVersionHeight() { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version height at which upgrade occurs must be greater than or equal to current client height (%d > %d)", - cs.GetLatestHeight().GetVersionHeight(), upgradeHeight.GetVersionHeight(), - ) - } - - if !upgradedClient.GetLatestHeight().GT(cs.GetLatestHeight()) { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be greater than current client height %s", - upgradedClient.GetLatestHeight(), cs.GetLatestHeight()) - } - - if len(proofUpgrade) == 0 { - return nil, nil, sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "proof of upgrade is empty") - } - - var merkleProof commitmenttypes.MerkleProof - if err := cdc.UnmarshalBinaryBare(proofUpgrade, &merkleProof); err != nil { - return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal merkle proof: %v", err) + if upgradedClient.GetLatestHeight().GetVersionNumber() <= lastHeight.GetVersionNumber() { + return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be at greater version than current client height %s", + upgradedClient.GetLatestHeight(), lastHeight) } // counterparty chain must commit the upgraded client with all client-customizable fields zeroed out // at the upgrade path specified by current client - committedClient := upgradedClient.ZeroCustomFields() - bz, err := codec.MarshalAny(cdc, committedClient) - if err != nil { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) + // counterparty must also commit to the upgraded consensus state at a sub-path under the upgrade path specified + tmUpgradeClient, ok := upgradedClient.(*ClientState) + if !ok { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", + &ClientState{}, upgradedClient) + } + tmUpgradeConsState, ok := upgradedConsState.(*ConsensusState) + if !ok { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "upgraded consensus state must be Tendermint consensus state. expected %T, got: %T", + &ConsensusState{}, upgradedConsState) + } + + // unmarshal proofs + var merkleProofClient, merkleProofConsState commitmenttypes.MerkleProof + if err := cdc.UnmarshalBinaryBare(proofUpgradeClient, &merkleProofClient); err != nil { + return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal client merkle proof: %v", err) + } + if err := cdc.UnmarshalBinaryBare(proofUpgradeConsState, &merkleProofConsState); err != nil { + return nil, nil, sdkerrors.Wrapf(commitmenttypes.ErrInvalidProof, "could not unmarshal consensus state merkle proof: %v", err) } // Must prove against latest consensus state to ensure we are verifying against latest upgrade plan // This verifies that upgrade is intended for the provided version, since committed client must exist // at this consensus state - consState, err := GetConsensusState(clientStore, cdc, upgradeHeight) + consState, err := GetConsensusState(clientStore, cdc, lastHeight) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for upgradeHeight") + return nil, nil, sdkerrors.Wrap(err, "could not retrieve consensus state for lastHeight") } if cs.IsExpired(consState.Timestamp, ctx.BlockTime()) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidClient, "cannot upgrade an expired client") } - tmCommittedClient, ok := committedClient.(*ClientState) - if !ok { - return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "upgraded client must be Tendermint client. expected: %T got: %T", - &ClientState{}, upgradedClient) + // Verify client proof + bz, err := codec.MarshalAny(cdc, upgradedClient) + if err != nil { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClient, "could not marshal client state: %v", err) } - - // Relayer chosen client parameters are ignored. - // All chain-chosen parameters come from committed client, all client-chosen parameters - // come from current client. - updatedClientState := NewClientState( - tmCommittedClient.ChainId, cs.TrustLevel, cs.TrustingPeriod, tmCommittedClient.UnbondingPeriod, - cs.MaxClockDrift, tmCommittedClient.LatestHeight, tmCommittedClient.ProofSpecs, tmCommittedClient.UpgradePath, - cs.AllowUpdateAfterExpiry, cs.AllowUpdateAfterMisbehaviour, - ) - - if err := updatedClientState.Validate(); err != nil { - return nil, nil, sdkerrors.Wrap(err, "updated client state failed basic validation") - } - - if err := merkleProof.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradePath, bz); err != nil { + // construct clientState Merkle path + upgradeClientPath := constructUpgradeClientMerklePath(cs.UpgradePath, lastHeight) + if err := merkleProofClient.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeClientPath, bz); err != nil { return nil, nil, err } - // TODO: Return valid consensus state https://github.com/cosmos/cosmos-sdk/issues/7708 - return updatedClientState, &ConsensusState{}, nil + // Verify consensus state proof + bz, err = codec.MarshalAny(cdc, upgradedConsState) + if err != nil { + return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidConsensus, "could not marshal consensus state: %v", err) + } + // construct consensus state Merkle path + upgradeConsStatePath := constructUpgradeConsStateMerklePath(cs.UpgradePath, lastHeight) + if err := merkleProofConsState.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeConsStatePath, bz); err != nil { + return nil, nil, err + } + + // Construct new client state and consensus state + // Relayer chosen client parameters are ignored. + // All chain-chosen parameters come from committed client, all client-chosen parameters + // come from current client. + newClientState := NewClientState( + tmUpgradeClient.ChainId, cs.TrustLevel, cs.TrustingPeriod, tmUpgradeClient.UnbondingPeriod, + cs.MaxClockDrift, tmUpgradeClient.LatestHeight, tmUpgradeClient.ProofSpecs, tmUpgradeClient.UpgradePath, + cs.AllowUpdateAfterExpiry, cs.AllowUpdateAfterMisbehaviour, + ) + + if err := newClientState.Validate(); err != nil { + return nil, nil, sdkerrors.Wrap(err, "updated client state failed basic validation") + } + + // The new consensus state is merely used as a trusted kernel against which headers on the new + // chain can be verified. The root is empty as it cannot be known in advance, thus no proof verification will pass. + // The timestamp and the NextValidatorsHash of the consensus state is the blocktime and NextValidatorsHash + // of the last block committed by the old chain. This will allow the first block of the new chain to be verified against + // the last validators of the old chain so long as it is submitted within the TrustingPeriod of this client. + newConsState := NewConsensusState( + tmUpgradeConsState.Timestamp, commitmenttypes.MerkleRoot{}, tmUpgradeConsState.NextValidatorsHash, + ) + + return newClientState, newConsState, nil } -// construct MerklePath from upgradePath -func constructUpgradeMerklePath(upgradePath string, upgradeHeight exported.Height) (commitmenttypes.MerklePath, error) { - // assume that all keys here are separated by `/` and - // any `/` within a merkle key is correctly escaped - upgradeKeys := strings.Split(upgradePath, "/") - // unescape the last key so that we can append `/{height}` to the last key - lastKey, err := url.PathUnescape(upgradeKeys[len(upgradeKeys)-1]) - if err != nil { - return commitmenttypes.MerklePath{}, err - } - // append upgradeHeight to last key in merkle path +// construct MerklePath for the committed client from upgradePath +func constructUpgradeClientMerklePath(upgradePath []string, lastHeight exported.Height) commitmenttypes.MerklePath { + // copy all elements from upgradePath except final element + clientPath := make([]string, len(upgradePath)-1) + copy(clientPath, upgradePath) + + // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath // this will create the IAVL key that is used to store client in upgrade store - upgradeKeys[len(upgradeKeys)-1] = fmt.Sprintf("%s/%d", lastKey, upgradeHeight.GetVersionHeight()) - return commitmenttypes.NewMerklePath(upgradeKeys...), nil + lastKey := upgradePath[len(upgradePath)-1] + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetVersionHeight(), upgradetypes.KeyUpgradedClient) + + clientPath = append(clientPath, appendedKey) + return commitmenttypes.NewMerklePath(clientPath...) +} + +// construct MerklePath for the committed consensus state from upgradePath +func constructUpgradeConsStateMerklePath(upgradePath []string, lastHeight exported.Height) commitmenttypes.MerklePath { + // copy all elements from upgradePath except final element + consPath := make([]string, len(upgradePath)-1) + copy(consPath, upgradePath) + + // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath + // this will create the IAVL key that is used to store client in upgrade store + lastKey := upgradePath[len(upgradePath)-1] + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetVersionHeight(), upgradetypes.KeyUpgradedConsState) + + consPath = append(consPath, appendedKey) + return commitmenttypes.NewMerklePath(consPath...) } diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go index 6bffb19408..3db9d2dbae 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go @@ -10,10 +10,11 @@ import ( func (suite *TendermintTestSuite) TestVerifyUpgrade() { var ( - upgradedClient exported.ClientState - upgradeHeight clienttypes.Height - clientA string - proofUpgrade []byte + upgradedClient exported.ClientState + upgradedConsState exported.ConsensusState + lastHeight clienttypes.Height + clientA string + proofUpgradedClient, proofUpgradedConsState []byte ) testCases := []struct { @@ -26,12 +27,16 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -42,52 +47,26 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: true, }, { - name: "successful upgrade with different client chosen parameters set in upgraded client", + name: "unsuccessful upgrade: upgrade height version height is more than the current client version height", setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + // upgrade Height is 10 blocks from now + lastHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()+10)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - // Previous client-chosen parameters must be the same as upgraded client chosen parameters - tmClient, _ := cs.(*types.ClientState) - oldClient := types.NewClientState(tmClient.ChainId, types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, tmClient.LatestHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) - suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, oldClient) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - }, - expPass: true, - }, - { - name: "unsuccessful upgrade: upgrade height version does not match current client version", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -98,47 +77,26 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, - { - name: "unsuccessful upgrade: upgrade height version height is less than the current client version height", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()-1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // commit upgrade store changes and update clients - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - }, - expPass: false, - }, - { name: "unsuccessful upgrade: chain-specified parameters do not match committed client", setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, true) @@ -150,7 +108,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -158,12 +117,17 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client-specified parameters do not match previous client", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) // change upgradedClient client-specified parameters - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) suite.coordinator.CommitBlock(suite.chainB) err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) @@ -172,39 +136,124 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, { - name: "unsuccessful upgrade: proof is empty", + name: "unsuccessful upgrade: relayer-submitted consensus state does not match counterparty-committed consensus state", setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - proofUpgrade = []byte{} - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: proof unmarshal failed", - setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - proofUpgrade = []byte("proof") - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: proof verification failed", - setup: func() { - // create but do not store upgraded client - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + // zero custom fields and store in upgrade store + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + + // change submitted upgradedConsensusState + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("maliciousValidators"), + } + + // commit upgrade store changes and update clients + + suite.coordinator.CommitBlock(suite.chainB) + err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + suite.Require().NoError(err) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: client proof unmarshal failed", + setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + + proofUpgradedClient = []byte("proof") + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: consensus state proof unmarshal failed", + setup: func() { + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + + proofUpgradedConsState = []byte("proof") + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: client proof verification failed", + setup: func() { + // create but do not store upgraded client + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: consensus state proof verification failed", + setup: func() { + // create but do not store upgraded client + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -213,12 +262,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -229,41 +281,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) // SetClientState with empty upgrade path tmClient, _ := cs.(*types.ClientState) - tmClient.UpgradePath = "" - suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient) - }, - expPass: false, - }, - { - name: "unsuccessful upgrade: upgrade path is malformed and cannot be correctly unescaped", - setup: func() { - - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) - - // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - - // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) - - // commit upgrade store changes and update clients - - suite.coordinator.CommitBlock(suite.chainB) - err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) - suite.Require().True(found) - - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - - // SetClientState with nil upgrade path - tmClient, _ := cs.(*types.ClientState) - tmClient.UpgradePath = "upgraded%Client" + tmClient.UpgradePath = []string{""} suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), clientA, tmClient) }, expPass: false, @@ -273,12 +296,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -289,7 +315,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -298,12 +325,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -314,7 +344,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -322,9 +353,13 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { name: "unsuccessful upgrade: client is expired", setup: func() { - upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, upgradeHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -338,7 +373,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -347,12 +383,15 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } // upgrade Height is at next block - upgradeHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(upgradeHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -363,7 +402,39 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgrade, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(upgradeHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + }, + expPass: false, + }, + { + name: "unsuccessful upgrade: final client is not valid", + setup: func() { + + // new client has smaller unbonding period such that old trusting period is no longer valid + upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + upgradedConsState = &types.ConsensusState{ + NextValidatorsHash: []byte("nextValsHash"), + } + + // upgrade Height is at next block + lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) + + // zero custom fields and store in upgrade store + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + + // commit upgrade store changes and update clients + + suite.coordinator.CommitBlock(suite.chainB) + err := suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + suite.Require().NoError(err) + + cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) + suite.Require().True(found) + + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) }, expPass: false, }, @@ -382,13 +453,17 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs := suite.chainA.GetClientState(clientA) clientStore := suite.chainA.App.IBCKeeper.ClientKeeper.ClientStore(suite.chainA.GetContext(), clientA) + // Call ZeroCustomFields on upgraded clients to clear any client-chosen parameters in test-case upgradedClient + upgradedClient = upgradedClient.ZeroCustomFields() + clientState, consensusState, err := cs.VerifyUpgradeAndUpdateState( suite.chainA.GetContext(), suite.cdc, clientStore, upgradedClient, - upgradeHeight, - proofUpgrade, + upgradedConsState, + proofUpgradedClient, + proofUpgradedConsState, ) if tc.expPass { diff --git a/x/ibc/light-clients/09-localhost/types/client_state.go b/x/ibc/light-clients/09-localhost/types/client_state.go index 32b799fccd..0db79e8612 100644 --- a/x/ibc/light-clients/09-localhost/types/client_state.go +++ b/x/ibc/light-clients/09-localhost/types/client_state.go @@ -105,7 +105,7 @@ func (cs ClientState) CheckProposedHeaderAndUpdateState( // VerifyUpgradeAndUpdateState returns an error since localhost cannot be upgraded func (cs ClientState) VerifyUpgradeAndUpdateState( _ sdk.Context, _ codec.BinaryMarshaler, _ sdk.KVStore, - _ exported.ClientState, _ exported.Height, _ []byte, + _ exported.ClientState, _ exported.ConsensusState, _, _ []byte, ) (exported.ClientState, exported.ConsensusState, error) { return nil, nil, sdkerrors.Wrap(clienttypes.ErrInvalidUpgradeClient, "cannot upgrade localhost client") } diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index 2d3172b938..0c285a275c 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -67,7 +67,7 @@ var ( TestHash = tmhash.Sum([]byte("TESTING HASH")) TestCoin = sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)) - UpgradePath = fmt.Sprintf("%s/%s", "upgrade", "upgradedClient") + UpgradePath = []string{"upgrade", "upgradedIBCState"} ConnectionVersion = connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions())[0] diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index 71a2609d22..9ca8f1a3f9 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -10,6 +10,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ) // BeginBlock will check if there is a scheduled plan and if it is ready to be executed. @@ -28,6 +30,19 @@ func BeginBlocker(k keeper.Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { return } + // Once we are at the last block this chain will commit, set the upgraded consensus state + // so that IBC clients can use the last NextValidatorsHash as a trusted kernel for verifying + // headers on the next version of the chain. + // Set the time to the last block time of the current chain. + // In order for a client to upgrade successfully, the first block of the new chain must be committed + // within the trusting period of the last block time on this chain. + if plan.IsIBCPlan() && ctx.BlockHeight() == plan.Height-1 { + upgradedConsState := &ibctmtypes.ConsensusState{ + Timestamp: ctx.BlockTime(), + NextValidatorsHash: ctx.BlockHeader().NextValidatorsHash, + } + k.SetUpgradedConsensusState(ctx, ctx.BlockHeight(), upgradedConsState) + } // To make sure clear upgrade is executed at the same block if plan.ShouldExecute(ctx) { // If skip upgrade has been set for current height, we clear the upgrade plan diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index e2dd5c8a12..20ca573d13 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -120,6 +120,58 @@ func TestCanOverwriteScheduleUpgrade(t *testing.T) { VerifyDoUpgrade(t) } +func VerifyDoIBCLastBlock(t *testing.T) { + t.Log("Verify that chain committed to consensus state on the last height it will commit") + nextValsHash := []byte("nextValsHash") + newCtx := s.ctx.WithBlockHeader(tmproto.Header{ + Height: s.ctx.BlockHeight(), + NextValidatorsHash: nextValsHash, + }) + + req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} + s.module.BeginBlock(newCtx, req) + + consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err) + require.Equal(t, &ibctmtypes.ConsensusState{Timestamp: newCtx.BlockTime(), NextValidatorsHash: nextValsHash}, consState) +} + +func VerifyDoIBCUpgrade(t *testing.T) { + t.Log("Verify that a panic happens at the upgrade time/height") + newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) + + // Check IBC state is set before upgrade using last height: s.ctx.BlockHeight() + cs, err := s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err, "could not retrieve upgraded client before upgrade plan is applied") + require.NotNil(t, cs, "IBC client is nil before upgrade") + + consState, err := s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.NoError(t, err, "could not retrieve upgraded consensus state before upgrade plan is applied") + require.NotNil(t, consState, "IBC consensus state is nil before upgrade") + + req := abci.RequestBeginBlock{Header: newCtx.BlockHeader()} + require.Panics(t, func() { + s.module.BeginBlock(newCtx, req) + }) + + t.Log("Verify that the upgrade can be successfully applied with a handler") + s.keeper.SetUpgradeHandler("test", func(ctx sdk.Context, plan types.Plan) {}) + require.NotPanics(t, func() { + s.module.BeginBlock(newCtx, req) + }) + + VerifyCleared(t, newCtx) + + // Check IBC state is cleared after upgrade using last height: s.ctx.BlockHeight() + cs, err = s.keeper.GetUpgradedClient(newCtx, s.ctx.BlockHeight()) + require.Error(t, err, "retrieved upgraded client after upgrade plan is applied") + require.Nil(t, cs, "IBC client is not-nil after upgrade") + + consState, err = s.keeper.GetUpgradedConsensusState(newCtx, s.ctx.BlockHeight()) + require.Error(t, err, "retrieved upgraded consensus state after upgrade plan is applied") + require.Nil(t, consState, "IBC consensus state is not-nil after upgrade") +} + func VerifyDoUpgrade(t *testing.T) { t.Log("Verify that a panic happens at the upgrade time/height") newCtx := s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1).WithBlockTime(time.Now()) @@ -414,6 +466,27 @@ func TestUpgradeWithoutSkip(t *testing.T) { VerifyDone(t, s.ctx, "test") } +func TestIBCUpgradeWithoutSkip(t *testing.T) { + s := setupTest(10, map[int64]bool{}) + cs, err := clienttypes.PackClientState(&ibctmtypes.ClientState{}) + require.NoError(t, err) + err = s.handler(s.ctx, &types.SoftwareUpgradeProposal{ + Title: "prop", + Plan: types.Plan{ + Name: "test", + Height: s.ctx.BlockHeight() + 1, + UpgradedClientState: cs, + }, + }) + require.Nil(t, err) + + t.Log("Verify if last height stores consensus state") + VerifyDoIBCLastBlock(t) + + VerifyDoUpgrade(t) + VerifyDone(t, s.ctx, "test") +} + func TestDumpUpgradeInfoToFile(t *testing.T) { s := setupTest(10, map[int64]bool{}) diff --git a/x/upgrade/keeper/grpc_query.go b/x/upgrade/keeper/grpc_query.go index ba7bd959c6..26e7860c86 100644 --- a/x/upgrade/keeper/grpc_query.go +++ b/x/upgrade/keeper/grpc_query.go @@ -4,6 +4,7 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) @@ -32,3 +33,22 @@ func (k Keeper) AppliedPlan(c context.Context, req *types.QueryAppliedPlanReques return &types.QueryAppliedPlanResponse{Height: applied}, nil } + +// UpgradedConsensusState implements the Query/UpgradedConsensusState gRPC method +func (k Keeper) UpgradedConsensusState(c context.Context, req *types.QueryUpgradedConsensusStateRequest) (*types.QueryUpgradedConsensusStateResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + consState, err := k.GetUpgradedConsensusState(ctx, req.LastHeight) + if err != nil { + return nil, err + } + + cs, err := clienttypes.PackConsensusState(consState) + if err != nil { + return nil, err + } + + return &types.QueryUpgradedConsensusStateResponse{ + UpgradedConsensusState: cs, + }, nil +} diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index cc9965f7a7..861fd0393a 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -8,8 +8,6 @@ import ( "os" "path" "path/filepath" - "strconv" - "strings" "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -76,39 +74,33 @@ func (k Keeper) ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error { } store := ctx.KVStore(k.storeKey) + + // clear any old IBC state stored by previous plan + oldPlan, exists := k.GetUpgradePlan(ctx) + if exists && oldPlan.IsIBCPlan() { + k.ClearIBCState(ctx, oldPlan.Height-1) + } + bz := k.cdc.MustMarshalBinaryBare(&plan) store.Set(types.PlanKey(), bz) - if plan.UpgradedClientState == nil { - // if latest UpgradedClientState is nil, but upgraded client exists in store, - // then delete client state from store. - _, height, _ := k.GetUpgradedClient(ctx) - if height != 0 { - store.Delete(types.UpgradedClientKey(height)) + if plan.IsIBCPlan() { + // Set UpgradedClientState in store + clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err) } - return nil + // sets the new upgraded client in last height committed on this chain is at plan.Height - 1, + // since the chain will panic at plan.Height and new chain will resume at plan.Height + return k.SetUpgradedClient(ctx, plan.Height-1, clientState) } - - // Set UpgradedClientState in store - clientState, err := clienttypes.UnpackClientState(plan.UpgradedClientState) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not unpack clientstate: %v", err) - } - // deletes any previously stored upgraded client and sets the new upgraded client in - return k.SetUpgradedClient(ctx, plan.Height, clientState) + return nil } -// SetUpgradedClient sets the expected upgraded client for the next version of this chain -func (k Keeper) SetUpgradedClient(ctx sdk.Context, upgradeHeight int64, cs ibcexported.ClientState) error { +// SetUpgradedClient sets the expected upgraded client for the next version of this chain at the last height the current chain will commit. +func (k Keeper) SetUpgradedClient(ctx sdk.Context, lastHeight int64, cs ibcexported.ClientState) error { store := ctx.KVStore(k.storeKey) - // delete any previously stored upgraded client before setting a new one - // since there should only ever be one upgraded client in the store at any given time - _, setHeight, _ := k.GetUpgradedClient(ctx) - if setHeight != 0 { - store.Delete(types.UpgradedClientKey(setHeight)) - } - // zero out any custom fields before setting cs = cs.ZeroCustomFields() bz, err := clienttypes.MarshalClientState(k.cdc, cs) @@ -116,49 +108,52 @@ func (k Keeper) SetUpgradedClient(ctx sdk.Context, upgradeHeight int64, cs ibcex return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal clientstate: %v", err) } - store.Set(types.UpgradedClientKey(upgradeHeight), bz) + store.Set(types.UpgradedClientKey(lastHeight), bz) return nil } // GetUpgradedClient gets the expected upgraded client for the next version of this chain -// along with the planned upgrade height -// Since there is only ever one upgraded client in store, we do not need to know key beforehand -func (k Keeper) GetUpgradedClient(ctx sdk.Context) (ibcexported.ClientState, int64, error) { +func (k Keeper) GetUpgradedClient(ctx sdk.Context, height int64) (ibcexported.ClientState, error) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte(types.KeyUpgradedClient)) - var ( - count, height int - bz []byte - ) - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - count++ - // we must panic if the upgraded clients in store is ever more than one since - // that would break upgrade functionality and chain must halt and fix issue manually - if count > 1 { - panic("more than 1 upgrade client stored in state") - } - - keySplit := strings.Split(string(iterator.Key()), "/") - var err error - height, err = strconv.Atoi(keySplit[len(keySplit)-1]) - if err != nil { - return nil, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not parse upgrade height from key: %s", err) - } - - bz = iterator.Value() - } - - if count == 0 { - return nil, 0, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "upgrade client not found in store") + bz := store.Get(types.UpgradedClientKey(height)) + if len(bz) == 0 { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded client not found in store for height %d", height) } clientState, err := clienttypes.UnmarshalClientState(k.cdc, bz) if err != nil { - return nil, 0, err + return nil, err } - return clientState, int64(height), nil + return clientState, nil +} + +// SetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain +// using the last height committed on this chain. +func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, lastHeight int64, cs ibcexported.ConsensusState) error { + store := ctx.KVStore(k.storeKey) + bz, err := clienttypes.MarshalConsensusState(k.cdc, cs) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "could not marshal consensus state: %v", err) + } + + store.Set(types.UpgradedConsStateKey(lastHeight), bz) + return nil +} + +// GetUpgradedConsensusState set the expected upgraded consensus state for the next version of this chain +func (k Keeper) GetUpgradedConsensusState(ctx sdk.Context, lastHeight int64) (ibcexported.ConsensusState, error) { + store := ctx.KVStore(k.storeKey) + + bz := store.Get(types.UpgradedConsStateKey(lastHeight)) + if len(bz) == 0 { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "upgraded consensus state not found in store for height: %d", lastHeight) + } + consState, err := clienttypes.UnmarshalConsensusState(k.cdc, bz) + if err != nil { + return nil, err + } + return consState, nil } // GetDoneHeight returns the height at which the given upgrade was executed @@ -172,6 +167,14 @@ func (k Keeper) GetDoneHeight(ctx sdk.Context, name string) int64 { return int64(binary.BigEndian.Uint64(bz)) } +// ClearIBCState clears any planned IBC state +func (k Keeper) ClearIBCState(ctx sdk.Context, lastHeight int64) { + // delete IBC client and consensus state from store if this is IBC plan + store := ctx.KVStore(k.storeKey) + store.Delete(types.UpgradedClientKey(lastHeight)) + store.Delete(types.UpgradedConsStateKey(lastHeight)) +} + // ClearUpgradePlan clears any schedule upgrade func (k Keeper) ClearUpgradePlan(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) @@ -219,6 +222,11 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { handler(ctx, plan) + // Must clear IBC state after upgrade is applied as it is stored separately from the upgrade plan. + // This will prevent resubmission of upgrade msg after upgrade is already completed. + if plan.IsIBCPlan() { + k.ClearIBCState(ctx, plan.Height-1) + } k.ClearUpgradePlan(ctx) k.setDone(ctx, plan.Name) } diff --git a/x/upgrade/keeper/keeper_test.go b/x/upgrade/keeper/keeper_test.go index c53a2d3857..f22edc00d6 100644 --- a/x/upgrade/keeper/keeper_test.go +++ b/x/upgrade/keeper/keeper_test.go @@ -235,13 +235,12 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { if tc.expPass { s.Require().NoError(err, "valid test case failed") if tc.plan.UpgradedClientState != nil { - got, height, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height-1) s.Require().NoError(err) - s.Require().Equal(tc.plan.Height, height, "upgradedClient not stored at correct upgrade height") s.Require().Equal(clientState, got, "upgradedClient not equal to expected value") } else { // check that upgraded client is empty if latest plan does not specify an upgraded client - got, _, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + got, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.plan.Height-1) s.Require().Error(err) s.Require().Nil(got) } @@ -255,36 +254,24 @@ func (s *KeeperTestSuite) TestScheduleUpgrade() { func (s *KeeperTestSuite) TestSetUpgradedClient() { var ( clientState ibcexported.ClientState - height int64 ) cases := []struct { name string + height int64 setup func() exists bool }{ { name: "no upgraded client exists", + height: 10, setup: func() {}, exists: false, }, { - name: "success", + name: "success", + height: 10, setup: func() { clientState = &ibctmtypes.ClientState{ChainId: "gaiachain"} - height = 10 - - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, clientState) - }, - exists: true, - }, - { - name: "successful overwrite", - setup: func() { - clientState = &ibctmtypes.ClientState{ChainId: "gaiachain"} - altCs := &ibctmtypes.ClientState{ChainId: "ethermint"} - height = 10 - - s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 50, altCs) s.app.UpgradeKeeper.SetUpgradedClient(s.ctx, 10, clientState) }, exists: true, @@ -298,14 +285,12 @@ func (s *KeeperTestSuite) TestSetUpgradedClient() { // setup test case tc.setup() - gotCs, gotHeight, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx) + gotCs, err := s.app.UpgradeKeeper.GetUpgradedClient(s.ctx, tc.height) if tc.exists { s.Require().Equal(clientState, gotCs, "valid case: %s did not retrieve correct client state", tc.name) - s.Require().Equal(height, gotHeight, "valid case: %s did not retrieve correct upgrade height", tc.name) s.Require().NoError(err, "valid case: %s returned error") } else { s.Require().Nil(gotCs, "invalid case: %s retrieved valid client state", tc.name) - s.Require().Equal(int64(0), gotHeight, "invalid case: %s retrieved valid upgrade height", tc.name) s.Require().Error(err, "invalid case: %s did not return error", tc.name) } } diff --git a/x/upgrade/types/keys.go b/x/upgrade/types/keys.go index cef1f09366..410f63597c 100644 --- a/x/upgrade/types/keys.go +++ b/x/upgrade/types/keys.go @@ -22,8 +22,14 @@ const ( // DoneByte is a prefix for to look up completed upgrade plan by name DoneByte = 0x1 - // KeyUpgradedClient is the key under which upgraded client is stored in the upgrade store + // KeyUpgradedIBCState is the key under which upgraded ibc state is stored in the upgrade store + KeyUpgradedIBCState = "upgradedIBCState" + + // KeyUpgradedClient is the sub-key under which upgraded client state will be stored KeyUpgradedClient = "upgradedClient" + + // KeyUpgradedConsState is the sub-key under which upgraded consensus state will be stored + KeyUpgradedConsState = "upgradedConsState" ) // PlanKey is the key under which the current plan is saved @@ -36,5 +42,12 @@ func PlanKey() []byte { // Connecting IBC chains can verify against the upgraded client in this path before // upgrading their clients func UpgradedClientKey(height int64) []byte { - return []byte(fmt.Sprintf("%s/%d", KeyUpgradedClient, height)) + return []byte(fmt.Sprintf("%s/%d/%s", KeyUpgradedIBCState, height, KeyUpgradedClient)) +} + +// UpgradedConsStateKey is the key under which the upgraded consensus state is saved +// Connecting IBC chains can verify against the upgraded consensus state in this path before +// upgrading their clients. +func UpgradedConsStateKey(height int64) []byte { + return []byte(fmt.Sprintf("%s/%d/%s", KeyUpgradedIBCState, height, KeyUpgradedConsState)) } diff --git a/x/upgrade/types/plan.go b/x/upgrade/types/plan.go index e853ac6797..f9f9db15e9 100644 --- a/x/upgrade/types/plan.go +++ b/x/upgrade/types/plan.go @@ -72,6 +72,11 @@ func (p Plan) DueAt() string { return fmt.Sprintf("height: %d", p.Height) } +// IsIBCPlan will return true if plan includes IBC client information +func (p Plan) IsIBCPlan() bool { + return p.UpgradedClientState != nil +} + // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (p Plan) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { // UpgradedClientState may be nil diff --git a/x/upgrade/types/plan_test.go b/x/upgrade/types/plan_test.go index 881a1a3229..436cb83a94 100644 --- a/x/upgrade/types/plan_test.go +++ b/x/upgrade/types/plan_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "fmt" @@ -12,6 +12,7 @@ import ( clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types" ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -29,11 +30,11 @@ func TestPlanString(t *testing.T) { require.NoError(t, err) cases := map[string]struct { - p Plan + p types.Plan expect string }{ "with time": { - p: Plan{ + p: types.Plan{ Name: "due_time", Info: "https://foo.bar", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -41,7 +42,7 @@ func TestPlanString(t *testing.T) { expect: "Upgrade Plan\n Name: due_time\n Time: 2019-07-08T11:33:55Z\n Info: https://foo.bar.\n Upgraded IBC Client: no upgraded client provided", }, "with height": { - p: Plan{ + p: types.Plan{ Name: "by height", Info: "https://foo.bar/baz", Height: 7890, @@ -49,7 +50,7 @@ func TestPlanString(t *testing.T) { expect: "Upgrade Plan\n Name: by height\n Height: 7890\n Info: https://foo.bar/baz.\n Upgraded IBC Client: no upgraded client provided", }, "with IBC client": { - p: Plan{ + p: types.Plan{ Name: "by height", Info: "https://foo.bar/baz", Height: 7890, @@ -59,7 +60,7 @@ func TestPlanString(t *testing.T) { }, "neither": { - p: Plan{ + p: types.Plan{ Name: "almost-empty", }, expect: "Upgrade Plan\n Name: almost-empty\n Height: 0\n Info: .\n Upgraded IBC Client: no upgraded client provided", @@ -80,11 +81,11 @@ func TestPlanValid(t *testing.T) { require.NoError(t, err) cases := map[string]struct { - p Plan + p types.Plan valid bool }{ "proper": { - p: Plan{ + p: types.Plan{ Name: "all-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -92,7 +93,7 @@ func TestPlanValid(t *testing.T) { valid: true, }, "proper ibc upgrade": { - p: Plan{ + p: types.Plan{ Name: "ibc-all-good", Info: "some text here", Height: 123450000, @@ -101,31 +102,31 @@ func TestPlanValid(t *testing.T) { valid: true, }, "proper by height": { - p: Plan{ + p: types.Plan{ Name: "all-good", Height: 123450000, }, valid: true, }, "no name": { - p: Plan{ + p: types.Plan{ Height: 123450000, }, }, "no due at": { - p: Plan{ + p: types.Plan{ Name: "missing", Info: "important", }, }, "negative height": { - p: Plan{ + p: types.Plan{ Name: "minus", Height: -12345, }, }, "time due date defined for IBC plan": { - p: Plan{ + p: types.Plan{ Name: "ibc-all-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -151,13 +152,13 @@ func TestPlanValid(t *testing.T) { func TestShouldExecute(t *testing.T) { cases := map[string]struct { - p Plan + p types.Plan ctxTime time.Time ctxHeight int64 expected bool }{ "past time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Info: "some text here", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -167,7 +168,7 @@ func TestShouldExecute(t *testing.T) { expected: false, }, "on time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Time: mustParseTime("2019-07-08T11:33:55Z"), }, @@ -176,7 +177,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "future time": { - p: Plan{ + p: types.Plan{ Name: "do-good", Time: mustParseTime("2019-07-08T11:33:55Z"), }, @@ -185,7 +186,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "past height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, @@ -194,7 +195,7 @@ func TestShouldExecute(t *testing.T) { expected: false, }, "on height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, @@ -203,7 +204,7 @@ func TestShouldExecute(t *testing.T) { expected: true, }, "future height": { - p: Plan{ + p: types.Plan{ Name: "do-good", Height: 1234, }, diff --git a/x/upgrade/types/proposal_test.go b/x/upgrade/types/proposal_test.go index 0756776ddf..8f5ffb07a7 100644 --- a/x/upgrade/types/proposal_test.go +++ b/x/upgrade/types/proposal_test.go @@ -1,4 +1,4 @@ -package types +package types_test import ( "testing" @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" gov "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) type ProposalWrapper struct { @@ -23,7 +24,7 @@ func TestContentAccessors(t *testing.T) { str string }{ "upgrade": { - p: NewSoftwareUpgradeProposal("Title", "desc", Plan{ + p: types.NewSoftwareUpgradeProposal("Title", "desc", types.Plan{ Name: "due_time", Info: "https://foo.bar", Time: mustParseTime("2019-07-08T11:33:55Z"), @@ -34,7 +35,7 @@ func TestContentAccessors(t *testing.T) { str: "Software Upgrade Proposal:\n Title: Title\n Description: desc\n", }, "cancel": { - p: NewCancelSoftwareUpgradeProposal("Cancel", "bad idea"), + p: types.NewCancelSoftwareUpgradeProposal("Cancel", "bad idea"), title: "Cancel", desc: "bad idea", typ: "CancelSoftwareUpgrade", @@ -44,7 +45,7 @@ func TestContentAccessors(t *testing.T) { cdc := codec.NewLegacyAmino() gov.RegisterLegacyAminoCodec(cdc) - RegisterLegacyAminoCodec(cdc) + types.RegisterLegacyAminoCodec(cdc) for name, tc := range cases { tc := tc // copy to local variable for scopelint diff --git a/x/upgrade/types/query.pb.go b/x/upgrade/types/query.pb.go index 5175e183ed..3c49f6c4ad 100644 --- a/x/upgrade/types/query.pb.go +++ b/x/upgrade/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + types "github.com/cosmos/cosmos-sdk/codec/types" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -207,11 +208,107 @@ func (m *QueryAppliedPlanResponse) GetHeight() int64 { return 0 } +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +type QueryUpgradedConsensusStateRequest struct { + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + LastHeight int64 `protobuf:"varint,1,opt,name=last_height,json=lastHeight,proto3" json:"last_height,omitempty"` +} + +func (m *QueryUpgradedConsensusStateRequest) Reset() { *m = QueryUpgradedConsensusStateRequest{} } +func (m *QueryUpgradedConsensusStateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedConsensusStateRequest) ProtoMessage() {} +func (*QueryUpgradedConsensusStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_4a334d07ad8374f0, []int{4} +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedConsensusStateRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedConsensusStateRequest.Merge(m, src) +} +func (m *QueryUpgradedConsensusStateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedConsensusStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedConsensusStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedConsensusStateRequest proto.InternalMessageInfo + +func (m *QueryUpgradedConsensusStateRequest) GetLastHeight() int64 { + if m != nil { + return m.LastHeight + } + return 0 +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +type QueryUpgradedConsensusStateResponse struct { + UpgradedConsensusState *types.Any `protobuf:"bytes,1,opt,name=upgraded_consensus_state,json=upgradedConsensusState,proto3" json:"upgraded_consensus_state,omitempty"` +} + +func (m *QueryUpgradedConsensusStateResponse) Reset() { *m = QueryUpgradedConsensusStateResponse{} } +func (m *QueryUpgradedConsensusStateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUpgradedConsensusStateResponse) ProtoMessage() {} +func (*QueryUpgradedConsensusStateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4a334d07ad8374f0, []int{5} +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUpgradedConsensusStateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUpgradedConsensusStateResponse.Merge(m, src) +} +func (m *QueryUpgradedConsensusStateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUpgradedConsensusStateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUpgradedConsensusStateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUpgradedConsensusStateResponse proto.InternalMessageInfo + +func (m *QueryUpgradedConsensusStateResponse) GetUpgradedConsensusState() *types.Any { + if m != nil { + return m.UpgradedConsensusState + } + return nil +} + func init() { proto.RegisterType((*QueryCurrentPlanRequest)(nil), "cosmos.upgrade.v1beta1.QueryCurrentPlanRequest") proto.RegisterType((*QueryCurrentPlanResponse)(nil), "cosmos.upgrade.v1beta1.QueryCurrentPlanResponse") proto.RegisterType((*QueryAppliedPlanRequest)(nil), "cosmos.upgrade.v1beta1.QueryAppliedPlanRequest") proto.RegisterType((*QueryAppliedPlanResponse)(nil), "cosmos.upgrade.v1beta1.QueryAppliedPlanResponse") + proto.RegisterType((*QueryUpgradedConsensusStateRequest)(nil), "cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateRequest") + proto.RegisterType((*QueryUpgradedConsensusStateResponse)(nil), "cosmos.upgrade.v1beta1.QueryUpgradedConsensusStateResponse") } func init() { @@ -219,30 +316,38 @@ func init() { } var fileDescriptor_4a334d07ad8374f0 = []byte{ - // 362 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3d, 0x4f, 0xfa, 0x40, - 0x1c, 0xc7, 0x39, 0xfe, 0xfc, 0x49, 0x3c, 0xb6, 0x1b, 0x10, 0x09, 0x69, 0xcc, 0x85, 0x18, 0x13, - 0xa1, 0xc7, 0xc3, 0x2b, 0x50, 0x13, 0x27, 0x07, 0x65, 0x74, 0x31, 0x07, 0xfc, 0x52, 0x1a, 0xcb, - 0xdd, 0xd1, 0xbb, 0x1a, 0x89, 0x71, 0xf1, 0x15, 0x98, 0xb8, 0xbb, 0xf9, 0x5e, 0x1c, 0x49, 0x5c, - 0x1c, 0x0d, 0xf8, 0x42, 0x0c, 0xd7, 0x62, 0x6a, 0xa0, 0xc1, 0xa9, 0x6d, 0xfa, 0x7d, 0xf8, 0xdc, - 0xb7, 0xc5, 0x74, 0x20, 0xf5, 0x58, 0x6a, 0x16, 0x29, 0x2f, 0xe4, 0x43, 0x60, 0xb7, 0xed, 0x3e, - 0x18, 0xde, 0x66, 0x93, 0x08, 0xc2, 0xa9, 0xab, 0x42, 0x69, 0x24, 0x29, 0xc7, 0x1a, 0x37, 0xd1, - 0xb8, 0x89, 0xa6, 0x5a, 0xf3, 0xa4, 0xf4, 0x02, 0x60, 0x5c, 0xf9, 0x8c, 0x0b, 0x21, 0x0d, 0x37, - 0xbe, 0x14, 0x3a, 0x76, 0x55, 0xeb, 0x19, 0xc9, 0xab, 0x14, 0xab, 0xa2, 0x7b, 0x78, 0xf7, 0x72, - 0x59, 0x75, 0x1a, 0x85, 0x21, 0x08, 0x73, 0x11, 0x70, 0xd1, 0x83, 0x49, 0x04, 0xda, 0xd0, 0x73, - 0x5c, 0x59, 0x7f, 0xa5, 0x95, 0x14, 0x1a, 0x48, 0x0b, 0x17, 0x54, 0xc0, 0x45, 0x05, 0xed, 0xa3, - 0xc3, 0x52, 0xa7, 0xe6, 0x6e, 0x26, 0x74, 0xad, 0xc7, 0x2a, 0x69, 0x33, 0x29, 0x3a, 0x56, 0x2a, - 0xf0, 0x61, 0x98, 0x2a, 0x22, 0x04, 0x17, 0x04, 0x1f, 0x83, 0x0d, 0xdb, 0xe9, 0xd9, 0x7b, 0xda, - 0x49, 0xca, 0x7f, 0xc9, 0x93, 0xf2, 0x32, 0x2e, 0x8e, 0xc0, 0xf7, 0x46, 0xc6, 0x3a, 0xfe, 0xf5, - 0x92, 0xa7, 0xce, 0x2c, 0x8f, 0xff, 0x5b, 0x13, 0x79, 0x41, 0xb8, 0x94, 0xc2, 0x26, 0x2c, 0x0b, - 0x30, 0xe3, 0xec, 0xd5, 0xd6, 0xdf, 0x0d, 0x31, 0x14, 0x6d, 0x3c, 0xbe, 0x7f, 0x3d, 0xe7, 0x0f, - 0x48, 0x9d, 0x65, 0xec, 0x3e, 0x88, 0x4d, 0xd7, 0xcb, 0x35, 0xc8, 0x2b, 0xc2, 0xa5, 0xd4, 0xd1, - 0xb6, 0x00, 0xae, 0x6f, 0xb6, 0x05, 0x70, 0xc3, 0x6a, 0xb4, 0x6b, 0x01, 0x9b, 0xe4, 0x28, 0x0b, - 0x90, 0xc7, 0x26, 0x0b, 0xc8, 0xee, 0x97, 0x5f, 0xe1, 0xe1, 0xe4, 0xec, 0x6d, 0xee, 0xa0, 0xd9, - 0xdc, 0x41, 0x9f, 0x73, 0x07, 0x3d, 0x2d, 0x9c, 0xdc, 0x6c, 0xe1, 0xe4, 0x3e, 0x16, 0x4e, 0xee, - 0xaa, 0xe1, 0xf9, 0x66, 0x14, 0xf5, 0xdd, 0x81, 0x1c, 0xaf, 0x02, 0xe3, 0x4b, 0x53, 0x0f, 0x6f, - 0xd8, 0xdd, 0x4f, 0xba, 0x99, 0x2a, 0xd0, 0xfd, 0xa2, 0xfd, 0xdb, 0xba, 0xdf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0xca, 0xa9, 0x39, 0xfe, 0xef, 0x02, 0x00, 0x00, + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0x41, 0x8b, 0x13, 0x31, + 0x18, 0x6d, 0xb4, 0x2e, 0x98, 0xde, 0x82, 0xd4, 0x6e, 0x59, 0x46, 0x89, 0x8b, 0x08, 0x6e, 0x93, + 0xdd, 0xee, 0x4d, 0x41, 0x5c, 0x17, 0x17, 0x0f, 0x22, 0x5a, 0xf1, 0xe2, 0xa5, 0xa4, 0x9d, 0x38, + 0x1d, 0x9c, 0x26, 0xd9, 0x49, 0x22, 0x96, 0x65, 0x2f, 0xfe, 0x02, 0xc1, 0xbb, 0x37, 0x6f, 0xfe, + 0x10, 0x8f, 0x0b, 0x5e, 0xf4, 0x26, 0xad, 0x3f, 0x44, 0x26, 0xc9, 0x48, 0x97, 0x76, 0x66, 0xc5, + 0x53, 0x3b, 0x93, 0xf7, 0xbe, 0xf7, 0xbe, 0xbc, 0x37, 0x10, 0x8f, 0xa5, 0x9e, 0x4a, 0x4d, 0xad, + 0x4a, 0x72, 0x16, 0x73, 0xfa, 0x6e, 0x6f, 0xc4, 0x0d, 0xdb, 0xa3, 0xc7, 0x96, 0xe7, 0x33, 0xa2, + 0x72, 0x69, 0x24, 0x6a, 0x7b, 0x0c, 0x09, 0x18, 0x12, 0x30, 0xdd, 0xcd, 0x44, 0xca, 0x24, 0xe3, + 0xd4, 0xa1, 0x46, 0xf6, 0x0d, 0x65, 0x22, 0x50, 0xba, 0x5b, 0xe1, 0x88, 0xa9, 0x94, 0x32, 0x21, + 0xa4, 0x61, 0x26, 0x95, 0x42, 0x87, 0xd3, 0xed, 0x0a, 0xd1, 0x52, 0xc0, 0xa1, 0xf0, 0x26, 0xbc, + 0xfe, 0xa2, 0x70, 0x71, 0x68, 0xf3, 0x9c, 0x0b, 0xf3, 0x3c, 0x63, 0x62, 0xc0, 0x8f, 0x2d, 0xd7, + 0x06, 0x3f, 0x85, 0x9d, 0xd5, 0x23, 0xad, 0xa4, 0xd0, 0x1c, 0xed, 0xc2, 0xa6, 0xca, 0x98, 0xe8, + 0x80, 0x9b, 0xe0, 0x4e, 0xab, 0xbf, 0x45, 0xd6, 0x9b, 0x27, 0x8e, 0xe3, 0x90, 0xb8, 0x17, 0x84, + 0x0e, 0x94, 0xca, 0x52, 0x1e, 0x2f, 0x09, 0x21, 0x04, 0x9b, 0x82, 0x4d, 0xb9, 0x1b, 0x76, 0x75, + 0xe0, 0xfe, 0xe3, 0x7e, 0x10, 0x3f, 0x07, 0x0f, 0xe2, 0x6d, 0xb8, 0x31, 0xe1, 0x69, 0x32, 0x31, + 0x8e, 0x71, 0x79, 0x10, 0x9e, 0xf0, 0x63, 0x88, 0x1d, 0xe7, 0x95, 0x77, 0x11, 0x1f, 0x16, 0x68, + 0xa1, 0xad, 0x7e, 0x69, 0x98, 0xe1, 0xa5, 0xda, 0x0d, 0xd8, 0xca, 0x98, 0x36, 0xc3, 0x73, 0x23, + 0x60, 0xf1, 0xea, 0x89, 0x1f, 0x63, 0xe1, 0xad, 0xda, 0x31, 0xc1, 0xc5, 0x33, 0xd8, 0x09, 0xeb, + 0xc6, 0xc3, 0x71, 0x09, 0x19, 0xea, 0x02, 0x13, 0xae, 0xe5, 0x1a, 0xf1, 0x01, 0x91, 0x32, 0x3b, + 0x72, 0x20, 0x66, 0x83, 0xb6, 0x5d, 0x3b, 0xb7, 0xff, 0xb5, 0x09, 0xaf, 0x38, 0x5d, 0xf4, 0x19, + 0xc0, 0xd6, 0xd2, 0xa5, 0x23, 0x5a, 0x75, 0xbd, 0x15, 0xc9, 0x75, 0x77, 0xff, 0x9d, 0xe0, 0x97, + 0xc1, 0x3b, 0x1f, 0xbe, 0xff, 0xfe, 0x74, 0xe9, 0x36, 0xda, 0xa6, 0x15, 0xad, 0x19, 0x7b, 0xd2, + 0xb0, 0xc8, 0x12, 0x7d, 0x01, 0xb0, 0xb5, 0x14, 0xcc, 0x05, 0x06, 0x57, 0x13, 0xbf, 0xc0, 0xe0, + 0x9a, 0xcc, 0xf1, 0xbe, 0x33, 0xd8, 0x43, 0x77, 0xab, 0x0c, 0x32, 0x4f, 0x72, 0x06, 0xe9, 0x49, + 0xd1, 0xa1, 0x53, 0xf4, 0x13, 0xc0, 0xf6, 0xfa, 0x14, 0xd1, 0xbd, 0x5a, 0x07, 0xb5, 0x0d, 0xea, + 0xde, 0xff, 0x2f, 0x6e, 0x58, 0xe4, 0xc8, 0x2d, 0xf2, 0x10, 0x3d, 0xa0, 0xf5, 0xdf, 0xe7, 0x4a, + 0xa9, 0xe8, 0xc9, 0x52, 0x6d, 0x4f, 0x1f, 0x1d, 0x7d, 0x9b, 0x47, 0xe0, 0x6c, 0x1e, 0x81, 0x5f, + 0xf3, 0x08, 0x7c, 0x5c, 0x44, 0x8d, 0xb3, 0x45, 0xd4, 0xf8, 0xb1, 0x88, 0x1a, 0xaf, 0x77, 0x92, + 0xd4, 0x4c, 0xec, 0x88, 0x8c, 0xe5, 0xb4, 0xd4, 0xf0, 0x3f, 0x3d, 0x1d, 0xbf, 0xa5, 0xef, 0xff, + 0x0a, 0x9a, 0x99, 0xe2, 0x7a, 0xb4, 0xe1, 0xca, 0xb9, 0xff, 0x27, 0x00, 0x00, 0xff, 0xff, 0xee, + 0x4b, 0xe2, 0xe8, 0xa4, 0x04, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -261,6 +366,11 @@ type QueryClient interface { CurrentPlan(ctx context.Context, in *QueryCurrentPlanRequest, opts ...grpc.CallOption) (*QueryCurrentPlanResponse, error) // AppliedPlan queries a previously applied upgrade plan by its name. AppliedPlan(ctx context.Context, in *QueryAppliedPlanRequest, opts ...grpc.CallOption) (*QueryAppliedPlanResponse, error) + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + UpgradedConsensusState(ctx context.Context, in *QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*QueryUpgradedConsensusStateResponse, error) } type queryClient struct { @@ -289,12 +399,26 @@ func (c *queryClient) AppliedPlan(ctx context.Context, in *QueryAppliedPlanReque return out, nil } +func (c *queryClient) UpgradedConsensusState(ctx context.Context, in *QueryUpgradedConsensusStateRequest, opts ...grpc.CallOption) (*QueryUpgradedConsensusStateResponse, error) { + out := new(QueryUpgradedConsensusStateResponse) + err := c.cc.Invoke(ctx, "/cosmos.upgrade.v1beta1.Query/UpgradedConsensusState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // CurrentPlan queries the current upgrade plan. CurrentPlan(context.Context, *QueryCurrentPlanRequest) (*QueryCurrentPlanResponse, error) // AppliedPlan queries a previously applied upgrade plan by its name. AppliedPlan(context.Context, *QueryAppliedPlanRequest) (*QueryAppliedPlanResponse, error) + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + UpgradedConsensusState(context.Context, *QueryUpgradedConsensusStateRequest) (*QueryUpgradedConsensusStateResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -307,6 +431,9 @@ func (*UnimplementedQueryServer) CurrentPlan(ctx context.Context, req *QueryCurr func (*UnimplementedQueryServer) AppliedPlan(ctx context.Context, req *QueryAppliedPlanRequest) (*QueryAppliedPlanResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AppliedPlan not implemented") } +func (*UnimplementedQueryServer) UpgradedConsensusState(ctx context.Context, req *QueryUpgradedConsensusStateRequest) (*QueryUpgradedConsensusStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpgradedConsensusState not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -348,6 +475,24 @@ func _Query_AppliedPlan_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Query_UpgradedConsensusState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUpgradedConsensusStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UpgradedConsensusState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.upgrade.v1beta1.Query/UpgradedConsensusState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UpgradedConsensusState(ctx, req.(*QueryUpgradedConsensusStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmos.upgrade.v1beta1.Query", HandlerType: (*QueryServer)(nil), @@ -360,6 +505,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "AppliedPlan", Handler: _Query_AppliedPlan_Handler, }, + { + MethodName: "UpgradedConsensusState", + Handler: _Query_UpgradedConsensusState_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmos/upgrade/v1beta1/query.proto", @@ -481,6 +630,69 @@ func (m *QueryAppliedPlanResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *QueryUpgradedConsensusStateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUpgradedConsensusStateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LastHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.LastHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryUpgradedConsensusStateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUpgradedConsensusStateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUpgradedConsensusStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UpgradedConsensusState != nil { + { + size, err := m.UpgradedConsensusState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -539,6 +751,31 @@ func (m *QueryAppliedPlanResponse) Size() (n int) { return n } +func (m *QueryUpgradedConsensusStateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.LastHeight != 0 { + n += 1 + sovQuery(uint64(m.LastHeight)) + } + return n +} + +func (m *QueryUpgradedConsensusStateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.UpgradedConsensusState != nil { + l = m.UpgradedConsensusState.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -844,6 +1081,167 @@ func (m *QueryAppliedPlanResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryUpgradedConsensusStateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastHeight", wireType) + } + m.LastHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUpgradedConsensusStateResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUpgradedConsensusStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpgradedConsensusState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UpgradedConsensusState == nil { + m.UpgradedConsensusState = &types.Any{} + } + if err := m.UpgradedConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/upgrade/types/query.pb.gw.go b/x/upgrade/types/query.pb.gw.go index 6d311b5778..cf1f9def8e 100644 --- a/x/upgrade/types/query.pb.gw.go +++ b/x/upgrade/types/query.pb.gw.go @@ -103,6 +103,60 @@ func local_request_Query_AppliedPlan_0(ctx context.Context, marshaler runtime.Ma } +func request_Query_UpgradedConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedConsensusStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["last_height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "last_height") + } + + protoReq.LastHeight, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "last_height", err) + } + + msg, err := client.UpgradedConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UpgradedConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUpgradedConsensusStateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["last_height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "last_height") + } + + protoReq.LastHeight, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "last_height", err) + } + + msg, err := server.UpgradedConsensusState(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -149,6 +203,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_UpgradedConsensusState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UpgradedConsensusState_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UpgradedConsensusState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -230,6 +304,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_UpgradedConsensusState_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UpgradedConsensusState_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UpgradedConsensusState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -237,10 +331,14 @@ var ( pattern_Query_CurrentPlan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "upgrade", "v1beta1", "current_plan"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_AppliedPlan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "upgrade", "v1beta1", "applied_plan", "name"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UpgradedConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "upgrade", "v1beta1", "upgraded_consensus_state", "last_height"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( forward_Query_CurrentPlan_0 = runtime.ForwardResponseMessage forward_Query_AppliedPlan_0 = runtime.ForwardResponseMessage + + forward_Query_UpgradedConsensusState_0 = runtime.ForwardResponseMessage ) From 53294f526993173e139daf21b4bdfbfe5dee48de Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 24 Nov 2020 12:27:35 +0000 Subject: [PATCH 46/57] check clients against params and consensus against clients (#8016) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> --- x/ibc/core/02-client/types/genesis.go | 22 +++++++++---- x/ibc/core/02-client/types/genesis_test.go | 37 +++++++++++++++++++--- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/x/ibc/core/02-client/types/genesis.go b/x/ibc/core/02-client/types/genesis.go index fc3ba12d19..4da2f5e920 100644 --- a/x/ibc/core/02-client/types/genesis.go +++ b/x/ibc/core/02-client/types/genesis.go @@ -101,6 +101,12 @@ func (gs GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return err + } + + validClients := make(map[string]bool) + for i, client := range gs.Clients { if err := host.ClientIdentifierValidator(client.ClientId); err != nil { return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", client.ClientId, i, err) @@ -110,14 +116,22 @@ func (gs GenesisState) Validate() error { if !ok { return fmt.Errorf("invalid client state with ID %s", client.ClientId) } + + if !gs.Params.IsAllowedClient(clientState.ClientType()) { + return fmt.Errorf("client type %s not allowed by genesis params", clientState.ClientType()) + } if err := clientState.Validate(); err != nil { return fmt.Errorf("invalid client %v index %d: %w", client, i, err) } + + // add client id to validClients map + validClients[client.ClientId] = true } for i, cc := range gs.ClientsConsensus { - if err := host.ClientIdentifierValidator(cc.ClientId); err != nil { - return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", cc.ClientId, i, err) + // check that consensus state is for a client in the genesis clients list + if !validClients[cc.ClientId] { + return fmt.Errorf("consensus state in genesis has a client id %s that does not map to a genesis client", cc.ClientId) } for _, consensusState := range cc.ConsensusStates { @@ -136,10 +150,6 @@ func (gs GenesisState) Validate() error { } } - if err := gs.Params.Validate(); err != nil { - return err - } - if gs.CreateLocalhost && !gs.Params.IsAllowedClient(exported.Localhost) { return fmt.Errorf("localhost client is not registered on the allowlist") } diff --git a/x/ibc/core/02-client/types/genesis_test.go b/x/ibc/core/02-client/types/genesis_test.go index d6caca0e68..1b60fb5c44 100644 --- a/x/ibc/core/02-client/types/genesis_test.go +++ b/x/ibc/core/02-client/types/genesis_test.go @@ -88,7 +88,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, ), }, - types.NewParams(exported.Tendermint), + types.NewParams(exported.Tendermint, exported.Localhost), false, ), expPass: true, @@ -106,7 +106,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, []types.ClientConsensusStates{ types.NewClientConsensusStates( - clientID, + "/~@$*", []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( header.GetHeight().(types.Height), @@ -138,7 +138,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { expPass: false, }, { - name: "invalid consensus state client id", + name: "consensus state client id does not match client id in genesis clients", genState: types.NewGenesisState( []types.IdentifiedClientState{ types.NewIdentifiedClientState( @@ -150,7 +150,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { }, []types.ClientConsensusStates{ types.NewClientConsensusStates( - "(CLIENTID2)", + "wrongclientid", []types.ConsensusStateWithHeight{ types.NewConsensusStateWithHeight( types.ZeroHeight(), @@ -224,6 +224,35 @@ func (suite *TypesTestSuite) TestValidateGenesis() { ), expPass: false, }, + { + name: "client in genesis clients is disallowed by params", + genState: types.NewGenesisState( + []types.IdentifiedClientState{ + types.NewIdentifiedClientState( + clientID, ibctmtypes.NewClientState(chainID, ibctesting.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + ), + types.NewIdentifiedClientState( + exported.Localhost, localhosttypes.NewClientState("chainID", clientHeight), + ), + }, + []types.ClientConsensusStates{ + types.NewClientConsensusStates( + clientID, + []types.ConsensusStateWithHeight{ + types.NewConsensusStateWithHeight( + header.GetHeight().(types.Height), + ibctmtypes.NewConsensusState( + header.GetTime(), commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), header.Header.NextValidatorsHash, + ), + ), + }, + ), + }, + types.NewParams(exported.Solomachine), + false, + ), + expPass: false, + }, { name: "invalid params", genState: types.NewGenesisState( From 13bc504bec93c8c84870bcd2f4d6103b8958096f Mon Sep 17 00:00:00 2001 From: Amaury Date: Tue, 24 Nov 2020 15:34:20 +0100 Subject: [PATCH 47/57] docs: Add REST endpoints migration guide (#8011) * Add REST endpoints migration guide * add bank, distrib, evidence * Add slashing, mint * Add staking * Add query * Add todo * Typos * Add link to interact node * grammar * Better wording * Update docs/migrations/rest.md Co-authored-by: Robert Zaremba * Update docs/migrations/rest.md * Add footnote Co-authored-by: Robert Zaremba --- client/rest/rest.go | 7 ++- docs/migrations/rest.md | 89 +++++++++++++++++++++++++++++++++++++ x/auth/client/rest/query.go | 6 ++- 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 docs/migrations/rest.md diff --git a/client/rest/rest.go b/client/rest/rest.go index 9a0f901840..ac05891e04 100644 --- a/client/rest/rest.go +++ b/client/rest/rest.go @@ -6,12 +6,17 @@ import ( "github.com/gorilla/mux" ) +// DeprecationURL is the URL for migrating deprecated REST endpoints to newer ones. +// TODO Switch to `/` (not `/master`) once v0.40 docs are deployed. +// https://github.com/cosmos/cosmos-sdk/issues/8019 +const DeprecationURL = "https://docs.cosmos.network/master/migrations/rest.html" + // addHTTPDeprecationHeaders is a mux middleware function for adding HTTP // Deprecation headers to a http handler func addHTTPDeprecationHeaders(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Deprecation", "true") - w.Header().Set("Link", "; rel=\"deprecation\"") + w.Header().Set("Link", "<"+DeprecationURL+">; rel=\"deprecation\"") w.Header().Set("Warning", "199 - \"this endpoint is deprecated and may not work as before, see deprecation link for more info\"") h.ServeHTTP(w, r) }) diff --git a/docs/migrations/rest.md b/docs/migrations/rest.md new file mode 100644 index 0000000000..4de2946faa --- /dev/null +++ b/docs/migrations/rest.md @@ -0,0 +1,89 @@ +# REST Endpoints Migration + +Migrate your REST endpoints to the Stargate ones. {synopsis} + +## Deprecation of Legacy REST Endpoints + +The Cosmos SDK versions v0.39 and earlier provided REST endpoints to query the state and broadcast transactions. These endpoints are kept in Cosmos SDK v0.40 (Stargate), but they are marked as deprecated, and will be removed in v0.41. We therefore call these endpoints legacy REST endpoints. + +Some important information concerning all legacy REST endpoints: + +- Most of these endpoints are backwards-comptatible. All breaking changes are described in the next section. +- In particular, these endpoints still output Amino JSON. Cosmos v0.40 introduced Protobuf as the default encoding library throughout the codebase, but legacy REST endpoints are one of the few places where the encoding is hardcoded to Amino. For more information about Protobuf and Amino, please read our [encoding guide](../core/encoding.md). +- All legacy REST endpoints include a [HTTP deprecation header](https://tools.ietf.org/id/draft-dalal-deprecation-header-01.html) which links to this document. + +## Breaking Changes in Legacy REST Endpoints + +| Legacy REST Endpoint | Description | Breaking Change | +| ------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `GET /txs/{hash}` | Query tx by hash | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | +| `GET /txs` | Query tx by events | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | +| `GET /staking/validators` | Get all validators | BondStatus is now a protobuf enum instead of an int32, and JSON serialized using its protobuf name, so expect query parameters like `?status=BOND_STATUS_{BONDED,UNBONDED,UNBONDING}` as opposed to `?status={bonded,unbonded,unbonding}`. | + +1: Transactions that don't support Amino serialization are the ones that contain one or more `Msg`s that are not registered with the Amino codec. Currently in the SDK, only IBC `Msg`s fall into this case. + +## Migrating to New REST Endpoints + +Thanks to the Protocol Buffers migration in v0.40 we are able to take advantage of a vast number of gRPC tools and solutions. For most of the legacy REST endpoints, Cosmos SDK v0.40 provides new REST endpoints generated from [gRPC `Query` services](../building-modules/query-services.md) using [grpc-gateway](https://grpc-ecosystem.github.io/grpc-gateway/). We usually call them _gGPC-gateway REST endpoints_. + +Some modules expose legacy `POST` endpoints to generate unsigned transactions for their `Msg`s. These `POST` endpoints have been removed. We recommend to use [service `Msg`s](../building-modules/msg-services.md) directly, and use Protobuf to do client-side transaction generation. A guide can be found [here (TODO)](https://github.com/cosmos/cosmos-sdk/issues/7657). + +| Legacy REST Endpoint | Description | New gGPC-gateway REST Endpoint | +| ------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `GET /txs/{hash}` | Query tx by hash | `GET /cosmos/tx/v1beta1/tx/{hash}` | +| `GET /txs` | Query tx by events | `GET /cosmos/tx/v1beta1/txs` | +| `POST /txs` | Broadcast tx | `POST /cosmos/tx/v1beta1/txs` | +| `POST /txs/encode` | Encodes an Amino JSON tx to an Amino binary tx | N/A, use Protobuf directly | +| `POST /txs/decode` | Decodes an Amino binary tx into an Amino JSON tx | N/A, use Protobuf directly | +| `POST /bank/*` | Create unsigned `Msg`s for bank tx | N/A, use Protobuf directly | +| `GET /bank/balances/{address}` | Get the balance of an address | `GET /cosmos/bank/v1beta1/balances/{address}/{denom}` | +| `GET /bank/total` | Get the total supply of all coins | `GET /cosmos/bank/v1beta1/supply` | +| `GET /bank/total/{denom}` | Get the total supply of one coin | `GET /cosmos/bank/v1beta1/supply/{denom}` | +| `POST /distribution/delegators/{delegatorAddr}/rewards` | Withdraw all delegator rewards | N/A, use Protobuf directly | +| `POST /distribution/*` | Create unsigned `Msg`s for distribution | N/A, use Protobuf directly | +| `GET /distribution/delegators/{delegatorAddr}/rewards` | Get the total rewards balance from all delegations | `GET /cosmos/distribution/v1beta1/v1beta1/delegators/{delegator_address}/rewards` | +| `GET /distribution/delegators/{delegatorAddr}/rewards/{validatorAddr}` | Query a delegation reward | `GET /cosmos/distribution/v1beta1/delegators/{delegatorAddr}/rewards/{validatorAddr}` | +| `GET /distribution/delegators/{delegatorAddr}/withdraw_address` | Get the rewards withdrawal address | `GET /cosmos/distribution/v1beta1/delegators/{delegatorAddr}/withdraw_address` | +| `GET /distribution/validators/{validatorAddr}` | Validator distribution information | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}` | +| `GET /distribution/validators/{validatorAddr}/rewards` | Commission and self-delegation rewards of a single a validator | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}/rewards` | +| `GET /distribution/validators/{validatorAddr}/outstanding_rewards` | Outstanding rewards of a single validator | `GET /cosmos/distribution/v1beta1/validators/{validatorAddr}/outstanding_rewards` | +| `GET /distribution/parameters` | Get the current distribution parameter values | `GET /cosmos/distribution/v1beta1/params` | +| `GET /distribution/community_pool` | Get the amount held in the community pool | `GET /cosmos/distribution/v1beta1/community_pool` | +| `GET /evidence/{evidence-hash}` | Get evidence by hash | `GET /cosmos/evidence/v1beta1/evidence/{evidence_hash}` | +| `GET /evidence` | Get all evidence | `GET /cosmos/evidence/v1beta1/evidence` | +| `POST /gov/*` | Create unsigned `Msg`s for gov | N/A, use Protobuf directly | +| `GET /gov/parameters/{type}` | Get government parameters | `GET /cosmos/gov/v1beta1/params/{type}` | +| `GET /gov/proposals` | Get all proposals | `GET /cosmos/gov/v1beta1/proposals` | +| `GET /gov/proposals/{proposal-id}` | Get proposal by id | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}` | +| `GET /gov/proposals/{proposal-id}/proposer` | Get proposer of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}` (Get proposer from `Proposal` struct) | +| `GET /gov/proposals/{proposal-id}/deposits` | Get deposits of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/deposits` | +| `GET /gov/proposals/{proposal-id}/deposits/{depositor}` | Get depositor a of deposit | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/deposits/{depositor}` | +| `GET /gov/proposals/{proposal-id}/tally` | Get tally of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/tally` | +| `GET /gov/proposals/{proposal-id}/votes` | Get votes of a proposal | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/votes` | +| `GET /gov/proposals/{proposal-id}/votes/{vote}` | Get a particular vote | `GET /cosmos/gov/v1beta1/proposals/{proposal-id}/votes/{vote}` | +| `GET /minting/parameters` | Get parameters for minting | `GET /cosmos/minting/v1beta1/params` | +| `GET /minting/inflation` | Get minting inflation | `GET /cosmos/minting/v1beta1/inflation` | +| `GET /minting/annual-provisions` | Get minting annual provisions | `GET /cosmos/minting/v1beta1/annual_provisions` | +| `POST /slashing/*` | Create unsigned `Msg`s for slashing | N/A, use Protobuf directly | +| `GET /slashing/validators/{validatorPubKey}/signing_info` | Get validator signing info | `GET /cosmos/slashing/v1beta1/signing_infos/{cons_address}` (Use consensus address instead of pubkey) | +| `GET /slashing/signing_infos` | Get all signing infos | `GET /cosmos/slashing/v1beta1/signing_infos` | +| `GET /slashing/parameters` | Get slashing parameters | `GET /cosmos/slashing/v1beta1/params` | +| `POST /staking/*` | Create unsigned `Msg`s for staking | N/A, use Protobuf directly | +| `GET /staking/delegators/{delegatorAddr}/delegations` | Get all delegations from a delegator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/delegations` | +| `GET /staking/delegators/{delegatorAddr}/unbonding_delegations` | Get all unbonding delegations from a delegator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations` | +| `GET /staking/delegators/{delegatorAddr}/txs` | Get all staking txs (i.e msgs) from a delegator | Removed | +| `GET /staking/delegators/{delegatorAddr}/validators` | Query all validators that a delegator is bonded to | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators` | +| `GET /staking/delegators/{delegatorAddr}/validators/{validatorAddr}` | Query a validator that a delegator is bonded to | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/validators/{validatorAddr}` | +| `GET /staking/delegators/{delegatorAddr}/delegations/{validatorAddr}` | Query a delegation between a delegator and a validator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/delegations/{validatorAddr}` | +| `GET /staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}` | Query all unbonding delegations between a delegator and a validator | `GET /cosmos/staking/v1beta1/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}` | +| `GET /staking/redelegations` | Query redelegations | `GET /cosmos/staking/v1beta1/v1beta1/delegators/{delegator_addr}/redelegations` | +| `GET /staking/validators` | Get all validators | `GET /cosmos/staking/v1beta1/validators` | +| `GET /staking/validators/{validatorAddr}` | Get a single validator info | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}` | +| `GET /staking/validators/{validatorAddr}/delegations` | Get all delegations to a validator | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}/delegations` | +| `GET /staking/validators/{validatorAddr}/unbonding_delegations` | Get all unbonding delegations from a validator | `GET /cosmos/staking/v1beta1/validators/{validatorAddr}/unbonding_delegations` | +| `GET /staking/historical_info/{height}` | Get HistoricalInfo at a given height | `GET /cosmos/staking/v1beta1/historical_info/{height}` | +| `GET /staking/pool` | Get the current state of the staking pool | `GET /cosmos/staking/v1beta1/pool` | +| `GET /staking/parameters` | Get the current staking parameter values | `GET /cosmos/staking/v1beta1/params` | +| `POST /upgrade/*` | Create unsigned `Msg`s for upgrade | N/A, use Protobuf directly | +| `GET /upgrade/current` | Get the current plan | `GET /cosmos/upgrade/v1beta1/current_plan` | +| `GET /upgrade/applied_plan/{name}` | Get a previously applied plan | `GET /cosmos/upgrade/v1beta1/applied/{name}` | diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index d60028abc5..674e24a008 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -9,6 +9,7 @@ import ( "github.com/gorilla/mux" "github.com/cosmos/cosmos-sdk/client" + clientrest "github.com/cosmos/cosmos-sdk/client/rest" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" @@ -19,7 +20,7 @@ import ( const unRegisteredConcreteTypeErr = "unregistered concrete type" -// query accountREST Handler +// QueryAccountRequestHandlerFn is the query accountREST Handler. func QueryAccountRequestHandlerFn(storeName string, clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -206,7 +207,8 @@ func checkSignModeError(w http.ResponseWriter, ctx client.Context, resp interfac rest.WriteErrorResponse(w, http.StatusInternalServerError, "This transaction was created with the new SIGN_MODE_DIRECT signing method, and therefore cannot be displayed"+ " via legacy REST handlers, please use CLI or directly query the Tendermint RPC endpoint to query"+ - " this transaction. gRPC gateway endpoint is "+grpcEndPoint) + " this transaction. gRPC gateway endpoint is "+grpcEndPoint+". Please also see the REST endpoints migration"+ + " guide at "+clientrest.DeprecationURL+".") return err } From ccd0d63f80b65db2dead1feb96fea38c940e498d Mon Sep 17 00:00:00 2001 From: Amaury Date: Tue, 24 Nov 2020 16:03:20 +0100 Subject: [PATCH 48/57] Update "Core Concepts" docs (#7948) * Update "Core Concepts" docs * Update tags * Update more subsctions * Revert basics * ADd link to run-node * Typo * Add sign modes * Finish transaction.md * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Wording * Update docs/core/baseapp.md Co-authored-by: Marie Gauthier * Revert basics changes * revert space change * typo * Update docs/core/transactions.md Co-authored-by: Marie Gauthier * Update docs/core/node.md Co-authored-by: Robert Zaremba * Update docs/core/store.md Co-authored-by: Robert Zaremba Co-authored-by: Marie Gauthier Co-authored-by: Robert Zaremba Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- docs/building-modules/msg-services.md | 4 + docs/core/README.md | 2 +- docs/core/baseapp.md | 194 +++++++++++++------------- docs/core/context.md | 40 ++---- docs/core/node.md | 55 ++++---- docs/core/store.md | 83 +++++------ docs/core/transactions.md | 144 +++++++++++++------ docs/run-node/keyring.md | 2 +- docs/run-node/run-node.md | 6 +- simapp/simd/cmd/root.go | 1 + 10 files changed, 286 insertions(+), 245 deletions(-) diff --git a/docs/building-modules/msg-services.md b/docs/building-modules/msg-services.md index 0cde42b195..0df12fa911 100644 --- a/docs/building-modules/msg-services.md +++ b/docs/building-modules/msg-services.md @@ -16,6 +16,10 @@ All `Msg` processing is done by a [`Msg`](messages-and-queries.md#msg-services) As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code. +Based on the definition of the `Msg` service, Protobuf generates a `MsgServer` interface. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `Msg`s: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/types/tx.pb.go#L285-L291 + When possible, the existing module's [`Keeper`](keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`: +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc1/x/bank/keeper/msg_server.go#L14-L16 diff --git a/docs/core/README.md b/docs/core/README.md index 9cb69b4c71..20b344d3a0 100644 --- a/docs/core/README.md +++ b/docs/core/README.md @@ -8,7 +8,7 @@ parent: This repository contains reference documentation on the core concepts of the Cosmos SDK. -1. [`Baseapp`](./baseapp.md) +1. [`BaseApp`](./baseapp.md) 2. [Transaction](./transactions.md) 3. [Context](./context.md) 4. [Node Client](./node.md) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 0b9417cfe6..421ed74c93 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -2,7 +2,7 @@ order: 1 --> -# Baseapp +# BaseApp This document describes `BaseApp`, the abstraction that implements the core functionalities of an SDK application. {synopsis} @@ -15,11 +15,9 @@ This document describes `BaseApp`, the abstraction that implements the core func `BaseApp` is a base type that implements the core of an SDK application, namely: -- The [Application Blockchain Interface](#abci), for the state-machine to communicate with the -underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route messages and queries to the appropriate module. -- Different [states](#states), as the state-machine can have different volatile -states updated based on the ABCI message received. +- The [Application Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- [Service Routers](#service-routers), to route messages and queries to the appropriate module. +- Different [states](#states), as the state-machine can have different volatile states updated based on the ABCI message received. The goal of `BaseApp` is to provide the fundamental layer of an SDK application that developers can easily extend to build their own custom application. Usually, @@ -40,67 +38,67 @@ type App struct { Extending the application with `BaseApp` gives the former access to all of `BaseApp`'s methods. This allows developers to compose their custom application with the modules they want, while not -having to concern themselves with the hard work of implementing the ABCI, the routing and state +having to concern themselves with the hard work of implementing the ABCI, the service routers and state management logic. ## Type Definition The `BaseApp` type holds many important parameters for any Cosmos SDK based application. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L54-L108 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/baseapp.go#L46-L131 Let us go through the most important components. -> __Note__: Not all parameters are described, only the most important ones. Refer to the -type definition for the full list. +> **Note**: Not all parameters are described, only the most important ones. Refer to the +> type definition for the full list. First, the important parameters that are initialized during the bootstrapping of the application: - [`CommitMultiStore`](./store.md#commitmultistore): This is the main store of the application, -which holds the canonical state that is committed at the [end of each block](#commit). This store -is **not** cached, meaning it is not used to update the application's volatile (un-committed) states. -The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application -uses one or multiple `KVStores` in the multi-store to persist their subset of the state. + which holds the canonical state that is committed at the [end of each block](#commit). This store + is **not** cached, meaning it is not used to update the application's volatile (un-committed) states. + The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application + uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - Database: The `db` is used by the `CommitMultiStore` to handle data persistence. -- [Router](#message-routing): The `router` facilitates the routing of `messages` to the appropriate -module for it to be processed. Here a `message` refers to the transaction components that need to be -processed by the application in order to update the state, and not to ABCI messages which implement -the interface between the application and the underlying consensus engine. -- [Query Router](#query-routing): The `query router` facilitates the routing of queries to the -appropriate module for it to be processed. These `queries` are not ABCI messages themselves, but they -are relayed to the application from the underlying consensus engine via the ABCI message [`Query`](#query). +- [`Msg` Service Router](#msg-service-router): The `msgServiceRouter` facilitates the routing of service `Msg`s to the appropriate + module for it to be processed. Here a service `Msg` refers to the transaction components that need to be + processed by the application in order to update the state, and not to ABCI messages which implement + the interface between the application and the underlying consensus engine. +- [gRPC Query Router](#grpc-query-router): The `grpcQueryRouter` facilitates the routing of gRPC queries to the + appropriate module for it to be processed. These queries are not ABCI messages themselves, but they + are relayed to the relevant module's gRPC `Query` service. - [`TxDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder): It is used to decode -raw transaction bytes relayed by the underlying Tendermint engine. + raw transaction bytes relayed by the underlying Tendermint engine. - [`ParamStore`](#paramstore): The parameter store used to get and set application consensus parameters. - [`AnteHandler`](#antehandler): This handler is used to handle signature verification, fee payment, -and other pre-message execution checks when a transaction is received. It's executed during -[`CheckTx/RecheckTx`](#checktx) and [`DeliverTx`](#delivertx). + and other pre-message execution checks when a transaction is received. It's executed during + [`CheckTx/RecheckTx`](#checktx) and [`DeliverTx`](#delivertx). - [`InitChainer`](../basics/app-anatomy.md#initchainer), -[`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are -the functions executed when the application receives the `InitChain`, `BeginBlock` and `EndBlock` -ABCI messages from the underlying Tendermint engine. + [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are + the functions executed when the application receives the `InitChain`, `BeginBlock` and `EndBlock` + ABCI messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). - `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and set to `nil` on -[`Commit`](#commit) and gets re-initialized on BeginBlock. + [`Commit`](#commit) and gets re-initialized on BeginBlock. Finally, a few more important parameterd: - `voteInfos`: This parameter carries the list of validators whose precommit is missing, either -because they did not vote or because the proposer did not include their vote. This information is -carried by the [Context](#context) and can be used by the application for various things like -punishing absent validators. + because they did not vote or because the proposer did not include their vote. This information is + carried by the [Context](#context) and can be used by the application for various things like + punishing absent validators. - `minGasPrices`: This parameter defines the minimum gas prices accepted by the node. This is a -**local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the -`AnteHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction -enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) -only if the gas prices of the transaction are greater than one of the minimum gas price in -`minGasPrices` (e.g. if `minGasPrices == 1uatom,1photon`, the `gas-price` of the transaction must be -greater than `1uatom` OR `1photon`). + **local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the + `AnteHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction + enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) + only if the gas prices of the transaction are greater than one of the minimum gas price in + `minGasPrices` (e.g. if `minGasPrices == 1uatom,1photon`, the `gas-price` of the transaction must be + greater than `1uatom` OR `1photon`). - `appVersion`: Version of the application. It is set in the -[application's constructor function](../basics/app-anatomy.md#constructor-function). + [application's constructor function](../basics/app-anatomy.md#constructor-function). ## Constructor @@ -114,7 +112,7 @@ func NewBaseApp( ``` The `BaseApp` constructor function is pretty straightforward. The only thing worth noting is the -possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/options.go) +possibility to provide additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/options.go) to the `BaseApp`, which will execute them in order. The `options` are generally `setter` functions for important parameters, like `SetPruning()` to set pruning options or `SetMinGasPrices()` to set the node's `min-gas-prices`. @@ -143,7 +141,7 @@ the root `CommitMultiStore`. Any subsequent reads and writes happen on cached ve ### CheckTx State Updates During `CheckTx`, the `checkState`, which is based off of the last committed state from the root -store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a router +store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a service router exists for every message in the transaction. Note, when we execute the `AnteHandler`, we cache-wrap the already cache-wrapped `checkState`. This has the side effect that if the `AnteHandler` fails, the state transitions won't be reflected in the `checkState` -- i.e. `checkState` is only updated on @@ -186,23 +184,23 @@ parameters are non-nil, they are set in the BaseApp's `ParamStore`. Behind the s is actually managed by an `x/params` module `Subspace`. This allows the parameters to be tweaked via on-chain governance. -## Routing +## Service Routers -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `BaseApp`, which holds a `msgServiceRouter` for messages, and a `grpcQueryRouter` for queries. -### Message Routing +### `Msg` Service Router -[Messages](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a router which maps string paths to the appropriate module [handler](../building-modules/msg-services.md#handler-type) using the `.Route(ctx sdk.Context, path string)` function. Usually, the `path` is the name of the module. +[`Msg`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `BaseApp` holds a `msgServiceRouter` which maps fully-qualified service methods (`string`, defined in each module's `Msg` Protobuf service) to the appropriate module's `Msg` server implementation. -The [default router included in baseapp](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into the `Route` function of the [Router interface](https://github.com/cosmos/cosmos-sdk/blob/master/types/router.go#L12). For a stateless router that doesn't want to make use of this, can just ignore the ctx. +The [default `msgServiceRouter` included in `BaseApp`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/msg_service_router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into each [route handler inside `msgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/msg_service_router.go#L31-L32). For a stateless router that doesn't want to make use of this, you can just ignore the `ctx`. -The application's `router` is initilalized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `msgServiceRouter` is initialized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). -### Query Routing +### gRPC Query Router -Similar to `message`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [querier](../building-modules/query-services.md). To do so, `baseapp` holds a `query router`, which maps module names to module `querier`s. The `queryRouter` is called during the initial stages of `query` processing, which is done via the [`Query` ABCI message](#query). +Similar to `Msg`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [`Query` service](../building-modules/query-services.md). To do so, `BaseApp` holds a `grpcQueryRouter`, which maps modules' fully-qualified service methods (`string`, defined in their Protobuf `Query` gRPC) to their `Query` server implementation. The `grpcQueryRouter` is called during the initial stages of query processing, which can be either by directly sending a gRPC query to the gRPC endpoint, or via the [`Query` ABCI message](#query) on the Tendermint RPC endpoint. -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](../building-modules/module-manager.md), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +Just like the `msgServiceRouter`, the `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../building-modules/module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages @@ -211,11 +209,11 @@ The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) ( The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. -Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) +Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `BaseApp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `BaseApp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ### CheckTx @@ -228,18 +226,18 @@ Unconfirmed transactions are relayed to peers only if they pass `CheckTx`. make them lightweight. In the Cosmos SDK, after [decoding transactions](./encoding.md), `CheckTx()` is implemented to do the following checks: -1. Extract the `message`s from the transaction. -2. Perform _stateless_ checks by calling `ValidateBasic()` on each of the `messages`. This is done +1. Extract the `Msg`s from the transaction. +2. Perform _stateless_ checks by calling `ValidateBasic()` on each of the `Msg`s. This is done first, as _stateless_ checks are less computationally expensive than _stateful_ checks. If `ValidateBasic()` fail, `CheckTx` returns before running _stateful_ checks, which saves resources. 3. Perform non-module related _stateful_ checks on the [account](../basics/accounts.md). This step is mainly about checking - that the `message` signatures are valid, that enough fees are provided and that the sending account + that the `Msg` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](../basics/gas-fees.md) counting occurs here, - as `message`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided + as `Msg`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually - process `message`s. `Message`s only need to be processed when the canonical state need to be updated, +4. Ensure that each `Msg`'s fully-qualified service method matches on of the routes inside the `msgServiceRouter`, but do **not** actually + process `Msg`s. `Msg`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. Steps 2. and 3. are performed by the [`AnteHandler`](../basics/gas-fees.md#antehandler) in the [`RunTx()`](#runtx-antehandler-and-runmsgs) @@ -257,11 +255,11 @@ is actually included in a block, because `checkState` never gets committed to th `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. - `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction. Next is an example: +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/ante/basic.go#L104 - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. @@ -280,27 +278,27 @@ This allows certain checks like signature verification can be skipped during `Ch When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: 1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -2. For each message in the transaction, route to the appropriate module's [`handler`](../building-modules/msg-services.md#handler-type). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +2. For each `Msg` in the transaction, route to the appropriate module's [`Msg` service](../building-modules/msg-services.md). Additional _stateful_ checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `Msg` service returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L142-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L153-L162 -At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseDeliverTx`](https://tendermint.com/docs/spec/abci/abci.html#delivertx). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction, and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction, and by adding gas each time a read/write to the store occurs. - `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. - `Codespace (string)`: Namespace for the Code. @@ -308,41 +306,41 @@ At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0 ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx()` calls `ValidateBasic()` on each `message`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. +After that, `RunTx()` calls `ValidateBasic()` on each `Msg`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `Msg` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L587 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/baseapp/baseapp.go#L623-L630 -This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. -Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. +Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `Msg`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. ### AnteHandler -The `AnteHandler` is a special handler that implements the `anteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. +The `AnteHandler` is a special handler that implements the `AnteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/handler.go#L8 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/handler.go#L6-L8 The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. +- Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). +`BaseApp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante/ante.go). -Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. +Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `Msg`s. -First, it retreives the message's `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/msg-services.md#handler-type) function for the message is executed, before `RunMsgs` returns. +First, it retrieves the `Msg`'s fully-qualified service method name, by checking the `type_url` of the Protobuf `Any` representing the service `Msg`. Then, using the application's [`msgServiceRouter`](#msg-service-router), it checks for the existence of this fully-qualified service method. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`Msg` server](../building-modules/msg-services.md) implementation for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -350,49 +348,49 @@ First, it retreives the message's `route` using the `Msg.Route()` method. Then, The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/gas-fees.md#block-gas-meter), with infinite gas to process genesis transactions. -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the `genesis file` and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. +Finally, the `InitChain(req abci.RequestInitChain)` method of `BaseApp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the `genesis file` and, if defined, call the [`InitGenesis`](../building-modules/genesis.md#initgenesis) function of each of the application's modules. ### BeginBlock The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the `setDeliverState` function. +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/baseapp/baseapp.go#L387-L397 -This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). -- Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. + This function also resets the [main gas meter](../basics/gas-fees.md#main-gas-meter). +- Initialize the [block gas meter](../basics/gas-fees.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`beginBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`BeginBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose _precommit_ for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transaction in the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transaction in the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`EndBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the [`EndBlocker()`](../building-modules/beginblock-endblock.md#beginblock) method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received _precommits_ from 2/3+ of validators (weighted by voting power). On the `BaseApp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `BaseApp` will return the application's name, version and the hash of the last commit of `app.cms`. ### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It used to be the main entrypoint to build interfaces with the application, but with the introduction of [gRPC queries](../building-modules/query-services.md) in Cosmos SDK v0.40, its usage is more limited. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). -Each `query` comes with a `path`, which contains multiple `string`s. By convention, the first element of the `path` (`path[0]`) contains the category of `query` (`app`, `p2p`, `store` or `custom`). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving these 4 main categories of queries: +Each Tendermint `query` comes with a `path`, which is a `string` which denotes what to query. If the `path` matches a gRPC fully-qualified service method, then `BaseApp` will defer the query to the `grpcQueryRouter` and let it handle it like explained [above](#grpc-query-router). Otherwise, the `path` represents a query that is not (yet) handled by the gRPC router. `BaseApp` splits the `path` string with the `/` delimiter. By convention, the first element of the splitted string (`splitted[0]`) contains the category of `query` (`app`, `p2p`, `store` or `custom` ). The `BaseApp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving these 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. - Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's `querier`. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `BaseApp`'s [constructor](#constructor). +- Custom queries, which encompass legacy queries (before the introduction of gRPC queries), are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from `app.queryRouter` to map the query to the appropriate module's [legacy `querier`](../building-modules/query-services.md#legacy-queriers). ## Next {hide} diff --git a/docs/core/context.md b/docs/core/context.md index e7c42bd339..cc0628b5eb 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -15,25 +15,9 @@ The `context` is a data structure intended to be passed from function to functio The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) as its base, and has many additional types within its definition that are specific to the Cosmos SDK. he `Context` is integral to transaction processing in that it allows modules to easily access their respective [store](./store.md#base-layer-kvstores) in the [`multistore`](./store.md#multistore) and retrieve transactional context such as the block header and gas meter. -```go -type Context struct { - ctx context.Context - ms MultiStore - header tmproto.Header - chainID string - txBytes []byte - logger log.Logger - voteInfo []abci.VoteInfo - gasMeter GasMeter - blockGasMeter GasMeter - checkTx bool - minGasPrice DecCoins - consParams *abci.ConsensusParams - eventManager *EventManager -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L16-L39 -- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. +- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. - **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./store.md#multistore) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their respective [`KVStore`](./store.md#base-layer-kvstores) using their unique `StoreKey`. - **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. - **Chain ID:** The unique identification number of the blockchain a block pertains to. @@ -42,10 +26,10 @@ type Context struct { - **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. - **Gas Meters:** Specifically, a [`gasMeter`](../basics/gas-fees.md#main-gas-meter) for the transaction currently being processed using the context and a [`blockGasMeter`](../basics/gas-fees.md#block-gas-meter) for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/gas-fees.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. - **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. -- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**. +- **Min Gas Price:** The minimum [gas](../basics/gas-fees.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually, and should therefore **not be used in any functions used in sequences leading to state-transitions**. - **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which specify certain limits for the blockchain, such as maximum gas for a block. - **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](./events.md). Modules may define module specific -`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example: + `Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, and `EndBlock` and are returned to Tendermint for indexing. For example: ```go ctx.EventManager().EmitEvent(sdk.NewEvent( @@ -63,7 +47,7 @@ are also designed to enable concurrency and to be used in goroutines. Contexts are intended to be **immutable**; they should never be edited. Instead, the convention is to create a child context from its parent using a `With` function. For example: -``` go +```go childCtx = parentCtx.WithBlockHeader(header) ``` @@ -79,12 +63,12 @@ goes wrong. The pattern of usage for a Context is as follows: 1. A process receives a Context `ctx` from its parent process, which provides information needed to perform the process. -2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution. +2. The `ctx.ms` is **cache wrapped**, i.e. a cached copy of the [multistore](./store.md#multistore) is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms`. This is useful to protect the underlying multistore in case the changes need to be reverted at some point in the execution. 3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass -`ctx` to it as needed. + `ctx` to it as needed. 4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing -needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to -the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. + needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to + the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-and-runmsgs) function in [`baseapp`](./baseapp.md): @@ -106,12 +90,12 @@ if result.IsOK() { Here is the process: 1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()` -to cache-wrap the context and multistore. + to cache-wrap the context and multistore. 2. The cache-wrapped context, `runMsgCtx`, is used in `runMsgs` to return a result. 3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the -changes - the result is returned immediately. + changes - the result is returned immediately. 4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates -a successful run over all the messages, the cached multistore is written back to the original. + a successful run over all the messages, the cached multistore is written back to the original. ## Next {hide} diff --git a/docs/core/node.md b/docs/core/node.md index 54ae46e753..825344040d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -12,60 +12,65 @@ The main endpoint of an SDK application is the daemon client, otherwise known as ## `main` function -The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./cmd/appd/main.go` file. Running this function creates an executable `.appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. +The full-node client of any SDK application is built by running a `main` function. The client is generally named by appending the `-d` suffix to the application name (e.g. `appd` for an application named `app`), and the `main` function is defined in a `./appd/cmd/main.go` file. Running this function creates an executable `appd` that comes with a set of commands. For an app named `app`, the main command is [`appd start`](#start-command), which starts the full-node. In general, developers will implement the `main.go` function with the following structure: -- First, a [`codec`](./encoding.md) is instanciated for the application. +- First, an [`appCodec`](./encoding.md) is instanciated for the application. - Then, the `config` is retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for [addresses and pubkeys](../basics/accounts.md#addresses-and-pubkeys). - +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/config.go#L10-L21 -- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. -- Add default server commands to `rootCmd` using the `server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). + +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/config.go#L13-L24 +- Using [cobra](https://github.com/spf13/cobra), the root command of the full-node client is created. After that, all the custom commands of the application are added using the `AddCommand()` method of `rootCmd`. +- Add default server commands to `rootCmd` using the `server.AddCommands()` method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the [`start` command](#start-command). - Prepare and execute the `executor`. - +++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/libs/cli/setup.go#L75-L78 + +++ https://github.com/tendermint/tendermint/blob/v0.34.0-rc6/libs/cli/setup.go#L74-L78 -See an example of `main` function from the [`gaia`](https://github.com/cosmos/gaia) application: +See an example of `main` function from the `simapp` application, the SDK's application for demo purposes: -+++ https://github.com/cosmos/gaia/blob/f41a660cdd5bea173139965ade55bd25d1ee3429/cmd/gaiad/main.go ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/main.go ## `start` command The `start` command is defined in the `/server` folder of the Cosmos SDK. It is added to the root command of the full-node client in the [`main` function](#main-function) and called by the end-user to start their node: -```go -// For an example app named "app", the following command starts the full-node - +```bash +# For an example app named "app", the following command starts the full-node. appd start + +# Using the SDK's own simapp, the following commands start the simapp node. +simd start ``` -As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. +As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node. -The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. +The flow of the `start` command is pretty straightforward. First, it retrieves the `config` from the `context` in order to open the `db` (a [`leveldb`](https://github.com/syndtr/goleveldb) instance by default). This `db` contains the latest known state of the application (empty if the application is started from the first time. With the `db`, the `start` command creates a new instance of the application using an `appCreator` function: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L144 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L227 -Note that an `appCreator` is a function that fulfills the `AppCreator` signature. In practice, the [constructor the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. +Note that an `appCreator` is a function that fulfills the `AppCreator` signature: ++++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/types/app.go#L48-L50 -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/constructors.go#L17-L25 +In practice, the [constructor of the application](../basics/app-anatomy.md#constructor-function) is passed as the `appCreator`. + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/simapp/simd/cmd/root.go#L170-L215 Then, the instance of `app` is used to instanciate a new Tendermint node: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/server/start.go#L153-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L235-L244 -The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/application.go#L11-L26) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. +The Tendermint node can be created with `app` because the latter satisfies the [`abci.Application` interface](https://github.com/tendermint/tendermint/blob/v0.34.0/abci/types/application.go#L7-L32) (given that `app` extends [`baseapp`](./baseapp.md)). As part of the `NewNode` method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative, `NewNode` will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is `0`, the Tendermint node will call [`InitChain`](./baseapp.md#initchain) on the application to initialize the state from the genesis file. Once the Tendermint node is instanciated and in sync with the application, the node can be started: -```go -if err := tmNode.Start(); err != nil { - return nil, err -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/server/start.go#L250-L252 -Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. +Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress. + +## Other commands + +To discover how to concretely run a node and interact with it, please refer to our [Running a Node](../run-node/README.md) guide. ## Next {hide} -Learn about the [store](./store.md) {hide} \ No newline at end of file +Learn about the [store](./store.md) {hide} diff --git a/docs/core/store.md b/docs/core/store.md index 1be9c505ee..b9e97163ba 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -58,11 +58,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and implements a `GetStoreType()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L12-L15 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L15-L18 The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that specifies cache-wrapping and `Write` methods: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L217-L238 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L240-L264 Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A cache-wrapper creates a light snapshot of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. If a state-transition sequence is performed without issue, the cached store can be committed to the underlying store at the end of the sequence. @@ -70,11 +70,11 @@ Cache-wrapping is used ubiquitously in the Cosmos SDK and required to be impleme A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L24-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L29-L33 The `Committer` is an interface that defines methods to persist changes to disk: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L17-L22 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L20-L27 The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`. @@ -86,27 +86,27 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L83-L112 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L104-L133 -If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. +If tracing is enabled, then cache-wrapping the multistore will wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store) before caching them. ### CommitMultiStore The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L120-L158 ++++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L141-L184 -As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. +As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/rootmulti/store.go#L27-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/rootmulti/store.go#L43-L61 The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md). ### CacheMultiStore -Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. +Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachemulti/store.go#L17-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachemulti/store.go#L17-L28 `cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores. @@ -114,50 +114,37 @@ Whenever the `rootMulti.Store` needs to be cached-wrapped, a [`cachemulti.Store` ### `KVStore` and `CommitKVStore` Interfaces -A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer. +A `KVStore` is a simple key-value store used to store and retrieve data. A `CommitKVStore` is a `KVStore` that also implements a `Committer`. By default, stores mounted in `baseapp`'s main `CommitMultiStore` are `CommitKVStore`s. The `KVStore` interface is primarily used to restrict modules from accessing the committer. Individual `KVStore`s are used by modules to manage a subset of the global state. `KVStores` can be accessed by objects that hold a specific key. This `key` should only be exposed to the [`keeper`](../building-modules/keeper.md) of the module that defines the store. -`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. +`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/store.go#L163-L193 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L189-L219 -Apart from the traditional `Get` and `Set` methods, a `KVStore` is expected to implement an `Iterator()` method which returns an `Iterator` object. The `Iterator()` method is used to iterate over a domain of keys, typically keys that share a common prefix. Here is a common pattern of using an `Iterator` that might be found in a module's `keeper`: +Apart from the traditional `Get` and `Set` methods, a `KVStore` must provide an `Iterator(start, end)` method which returns an `Iterator` object. It is used to iterate over a range of keys, typically keys that share a common prefix. Below is an example from the bank's module keeper, used to iterate over all account balances: -```go -store := ctx.KVStore(keeper.storeKey) -iterator := sdk.KVStorePrefixIterator(store, prefix) // proxy for store.Iterator - -defer iterator.Close() -for ; iterator.Valid(); iterator.Next() { - var object types.Object - keeper.cdc.MustUnmarshalBinaryBare(iterator.Value(), &object) - - if cb(object) { - break - } -} -``` ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/keeper/view.go#L115-L134 ### `IAVL` Store The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the `iavl.Store`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/iavl/store.go#L32-L47 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/iavl/store.go#L37-L40 - `iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: +`iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that: - `Get` and `Set` operations are O(log n), where n is the number of elements in the tree. - Iteration efficiently returns the sorted elements within the range. -- Each tree version is immutable and can be retrieved even after a commit (depending on the pruning settings). +- Each tree version is immutable and can be retrieved even after a commit (depending on the pruning settings). -The documentation on the IAVL Tree is located [here](https://github.com/tendermint/iavl/blob/f9d4b446a226948ed19286354f0d433a887cc4a3/docs/overview.md). +The documentation on the IAVL Tree is located [here](https://github.com/cosmos/iavl/blob/v0.15.0-rc5/docs/overview.md). ### `DbAdapter` Store `dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/dbadapter/store.go#L13-L16 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/dbadapter/store.go#L13-L16 `dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores) @@ -165,17 +152,17 @@ The documentation on the IAVL Tree is located [here](https://github.com/tendermi `Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/transient/store.go#L14-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/transient/store.go#L13-L16 `Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected. -This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). +This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block). -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/params/subspace/subspace.go#L24-L32 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/params/types/subspace.go#L20-L30 Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L215-L218 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L232-L235 ## KVStore Wrappers @@ -183,9 +170,9 @@ Transient stores are typically accessed via the [`context`](./context.md) via th `cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/cachekv/store.go#L26-L33 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachekv/store.go#L27-L34 -This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). +This is the type used whenever an IAVL Store needs to be cache-wrapped (typically when setting value that might be reverted later). #### `Get` @@ -201,27 +188,27 @@ This is the type used whenever an IAVL Store needs to be cache-wrapped (typicall ### `GasKv` Store -Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. +Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/gaskv/store.go#L11-L17 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go#L13-L19 When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L141-L150 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L153-L162 By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md): -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/context.go#L210-L213 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L227-L230 In this case, the default gas configuration is used: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/types/gas.go#L152-L163 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L164-L175 ### `TraceKv` Store -`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. +`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/tracekv/store.go#L20-L43 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/tracekv/store.go#L20-L43 When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. @@ -229,7 +216,7 @@ When each `KVStore` methods are called, `tracekv.Store` automatically logs `trac `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/store/prefix/store.go#L17-L20 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/prefix/store.go#L15-L21 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 8bd5ae17f4..a2ccbfdb70 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -8,84 +8,146 @@ order: 2 ## Pre-requisite Readings -* [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} +- [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq} ## Transactions -Transactions are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md). +Transactions are comprised of metadata held in [contexts](./context.md) and [`Msg`s](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [`Msg` service](../building-modules/msg-services.md). -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `message`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's `Msg`s must be signed using the private key associated with the appropriate account(s), before the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Type Definition Transaction objects are SDK types that implement the `Tx` interface -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L34-L41 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/tx_msg.go#L49-L57 It contains the following methods: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for *`messages`*, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. -* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. +- **GetMsgs:** unwraps the transaction and returns a list of its `Msg`s - one transaction may have one or multiple [`Msg`s](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +- **ValidateBasic:** includes lightweight, [_stateless_](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from the `ValidateBasic` functions for `Msg`s, which perform basic validity checks on messages only. For example, when [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -The most used implementation of the `Tx` interface is [`StdTx` from the `auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go). As a developer, using `StdTx` as your transaction format is as simple as importing the `auth` module in your application (which can be done in the [constructor of the application](../basics/app-anatomy.md#constructor-function)) +As a developer, you should rarely manipulate `Tx` directly, as `Tx` is really an intermediate type used for transaction generation. Instead, developers should prefer the `TxBuilder` interface, which you can learn more about [below](#transaction-generation). + +### Signing Transactions + +Every message in a transaction must be signed by the addresses specified by its `GetSigners`. The SDK currently allows signing transactions in two different ways. + +#### `SIGN_MODE_DIRECT` (preferred) + +The most used implementation of the `Tx` interface is the Protobuf `Tx` message, which is used in `SIGN_MODE_DIRECT`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L12-L25 + +Because Protobuf serialization is not deterministic, the SDK uses an additional `TxRaw` type to denote the pinned bytes over which a transaction is signed. Any user can generate a valid `body` and `auth_info` for a transaction, and serialize these two messages using Protobuf. `TxRaw` then pins the user's exact binary representation of `body` and `auth_info`, called respectively `body_bytes` and `auth_info_bytes`. The document that is signed by all signers of the transaction is `SignDoc` (deterministically serialized using [ADR-027](../architecture/adr-027-deterministic-protobuf-serialization.md)): + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/tx.proto#L47-L64 + +Once signed by all signers, the `body_bytes`, `auth_info_bytes` and `signatures` are gathered into `TxRaw`, whose serialized bytes are broadcasted over the network. + +#### `SIGN_MODE_LEGACY_AMINO_JSON` + +The legacy implemention of the `Tx` interface is the `StdTx` struct from `x/auth`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdtx.go#L120-L130 + +The document signed by all signers is `StdSignDoc`: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdsign.go#L20-L33 + +which is encoded into bytes using Amino JSON. Once all signatures are gathered into `StdTx`, `StdTx` is serialized using Amino JSON, and these bytes are broadcasted over the network. + +#### Other Sign Modes + +Other sign modes, most notably `SIGN_MODE_TEXTUAL`, are being discussed. If you wish to learn more about them, please refer to [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md). ## Transaction Process -A transaction is created by an end-user through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. +The process of an end-user sending a transaction is: -### CLI and REST Interfaces +- decide on the messages to put into the transaction, +- generate the transaction using the SDK's `TxBuilder`, +- broadcast the transaction using one of the available interfaces. -Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. - -For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/module-interfaces.md#legacy-rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. - -When users interact with the application's interfaces, they invoke the underlying modules' handlers or command functions, directly creating messages. +The next paragraphs will describe each of these components, in this order. ### Messages -**`Message`s** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the `Msg` interface, and also define a [`Handler`](../building-modules/msg-services.md#handler-type) to process them. +::: tip +Module `Msg`s are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +::: -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/tx_msg.go#L8-L29 +**Messages** (or `Msg`s) are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by adding methods to the Protobuf [`Msg` service](../building-modules/msg-services.md), and also implement the corresponding `MsgServer`. -`Message`s in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's `message`s is defined in a `handler.go` file. +`Msg`s in a module are defined as methods in the [`Msg` service] inside each module's `tx.proto` file. Since `Msg`s are module-specific, each module needs a to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To achieve this, Protobuf generates a `MsgServer` interface for each module, and the module developer needs to implement this interface. The methods on the `MsgServer` interface corresponds on how to handle each of the different `Msg`. -Note: module `messages` are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. - -To learn more about `message`s, click [here](../building-modules/messages-and-queries.md#messages). +To learn more about `Msg` services and how to implement `MsgServer`, click [here](../building-modules/msg-services.md). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `Context`. ### Transaction Generation -Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). +The `TxBuilder` interface contains data closely related with the generation of transactions, which an end-user can freely set to generate the desired transaction: -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`Context`](../interfaces/query-lifecycle.md#context) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/client/tx_config.go#L32-L45 -The `TxBuilder` contains data closely related with the processing of transactions. +- `Msg`s, the array of [messages](#messages) included in the transaction. +- `GasLimit`, option chosen by the users for how to calculate how much gas they will need to pay. +- `Memo`, to send with the transaction. +- `FeeAmount`, the maximum amount the user is willing to pay in fees. +- `TimeoutHeight`, block height until which the transaction is valid. +- `Signatures`, the array of signatures from all signers of the transaction. -+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L18-L31 +As there are currently two sign modes for signing transactions, there are also two implementations of `TxBuilder`: -* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. -* `Keybase` that manages the user's keys and is used to perform signing operations. -* `AccountNumber` from which this transaction originated. -* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. -* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. -* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. -* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. -* `ChainID` representing which blockchain this transaction pertains to. -* `Memo` to send with the transaction. -* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. -* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. +- [wrapper](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/tx/builder.go#L19-L33) for creating transactions for `SIGN_MODE_DIRECT`, +- [StdTxBuilder](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/auth/legacy/legacytx/stdtx_builder.go#L14-L20) for `SIGN_MODE_LEGACY_AMINO_JSON`. -The `Context` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `Context` [here](../interfaces/query-lifecycle.md#context). +However, the two implementation of `TxBuilder` should be hidden away from end-users, as they should prefer using the overarching `TxConfig` interface: -Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `Context` is used to broadcast transactions. ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/client/tx_config.go#L21-L30 -### Handlers +`TxConfig` is an app-wide configuration for managing transactions. Most importantly, it holds the information about whether to sign each transaction with `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`. By calling `txBuilder := txConfig.NewTxBuilder()`, a new `TxBuilder` will be created with the appropriate sign mode. -Since messages are module-specific types, each module needs a [`handler`](../building-modules/msg-services.md#handler-type) to process all of its message types and trigger state changes within the module's scope. This design puts more responsibility on module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about `handler`s, click [here](../building-modules/msg-services.md#handler-type). +Once `TxBuilder` is correctly populated with the setters exposed above, `TxConfig` will also take care of correctly encoding the bytes (again, either using `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`). Here's a pseudo-code snippet of how to generate and encode a transaction, using the `TxEncoder()` method: + +```go +txBuilder := txConfig.NewTxBuilder() +txBuilder.SetMsgs(...) // and other setters on txBuilder + +bz, err := txConfig.TxEncoder()(txBuilder.GetTx()) +// bz are bytes to be broadcasted over the network +``` + +### Broadcasting the Transaction + +Once the transaction bytes are generated, there are currently three ways of broadcasting it. + +#### CLI + +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) and/or [REST interface](../interfaces/rest.md), typically found in the application's `./cmd` folder. These interfaces allow users to interact with the application through command-line. + +For the [command-line interface](../building-modules/module-interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. CLI commands actually bundle all the steps of transaction processing into one simple command: creating messages, generating transactions and broadcasting. For concrete examples, see the [Interacting with a Node](../run-node/interact-node.md) section. An example transaction made using CLI looks like: + +```bash +simd tx send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000stake +``` + +#### gRPC + +[gRPC](https://grpc.io) is introduced in Cosmos SDK 0.40 as the main component for the SDK's RPC layer. The principal usage of gRPC is in the context of modules' [`Query` services](../building-modules). However, the SDK also exposes a few other module-agnostic gRPC services, one of them being the `Tx` service: + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/proto/cosmos/tx/v1beta1/service.proto + +The `Tx` service exposes a handful of utility functions, such as simulating a transaction or querying a transaction, and also one method to broadcast transactions. + +An example of broadcasting a transaction is shown in [TODO](https://github.com/cosmos/cosmos-sdk/issues/7657). Please note that the `BroadcastTx` endpoint takes `TxRaw`, not bytes. + +#### REST + +Each gRPC method has its corresponding REST endpoint, generated using [gRPC-gateway](https://github.com/grpc-ecosystem/grpc-gateway). Therefore, instead of using gRPC, you can also use HTTP to broadcast the same transaction, on the `POST /cosmos/tx/v1beta1/broadcast_tx` endpoint. + +An example can be seen [here TODO](https://github.com/cosmos/cosmos-sdk/issues/7657) ## Next {hide} diff --git a/docs/run-node/keyring.md b/docs/run-node/keyring.md index 9725007c9f..a0bc0254f7 100644 --- a/docs/run-node/keyring.md +++ b/docs/run-node/keyring.md @@ -101,7 +101,7 @@ information. Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets. ::: -Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp). +Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp). You can use `simd keys` for help about the keys command and `simd keys [command] --help` for more information about a particular subcommand. diff --git a/docs/run-node/run-node.md b/docs/run-node/run-node.md index 05708e63d4..768726d602 100644 --- a/docs/run-node/run-node.md +++ b/docs/run-node/run-node.md @@ -4,7 +4,7 @@ order: 2 # Running a Node -Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp), and its corresponding CLI binary `simd`. {synopsis} +Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp), and its corresponding CLI binary `simd`. {synopsis} ## Pre-requisite Readings @@ -47,7 +47,7 @@ Now that you have created a local account, go ahead and grant it some `stake` to simd add-genesis-account $MY_VALIDATOR_ADDRESS 100000000stake ``` -Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the SDK have the `{amount}{denom}` format: `amount` is is a 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp). For your own chain with its own staking denom, that token identifier should be used instead. +Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the SDK have the `{amount}{denom}` format: `amount` is is a 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc3/simapp). For your own chain with its own staking denom, that token identifier should be used instead. Now that your account has some tokens, you need to add a validator to your chain. Validators are special full-nodes that participate in the consensus process (implemented in the [underlying consensus engine](../intro/sdk-app-architecture.md#tendermint)) in order to add new blocks to the chain. Any account can declare its intention to become a validator operator, but only those with sufficient delegation get to enter the active set (for example, only the top 125 validator candidates with the most delegation get to be validators in the Cosmos Hub). For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`: @@ -83,7 +83,7 @@ You should see blocks come in. The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them. -The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/docker-compose.yml). +The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/docker-compose.yml). ## Next {hide} diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 6fa3325c79..dd6132095c 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -167,6 +167,7 @@ func txCommand() *cobra.Command { return cmd } +// newApp is an AppCreator func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { var cache sdk.MultiStorePersistentCache From 88e03e4f4056e8614847fd6adf17ce9252b6a89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 24 Nov 2020 16:28:20 +0100 Subject: [PATCH 49/57] Deterministic connection and channel identifiers (#7993) * add generate identifier functions for connection and channel * update proto types and begin open init changes remove unnecessary field from open init msgs. Update connectionopeninit handshake, begin updating channel handshake * finish connection handshake chanes and some channel handshake changes Finish updating connection handshake changes, update genesis for connection and channel, some channel handshake changes, fix build for tests but still failing * finish channel handshake changes * fix more tests * fix connection handshake tests * fix more tests * fix build * changes from self review * address @fedekunze review suggestions * update spec * fix build * fix tests * Update x/ibc/testing/chain.go Co-authored-by: Aditya * Update x/ibc/core/03-connection/types/msgs.go Co-authored-by: Aditya * address @AdityaSripal comments * reflect spec changes * address @AdityaSripal review suggestions * nit * add connection/channel identifier parsing and validation as per @AdityaSripal suggestion, cc @fedekunze * Fix auth rest test Change dummy channel id to a valid channel id given the updated stricter channel identifier checks cc @amaurymartiny Co-authored-by: Aditya --- proto/ibc/core/channel/v1/genesis.proto | 2 + proto/ibc/core/channel/v1/tx.proto | 46 +-- proto/ibc/core/connection/v1/genesis.proto | 2 + proto/ibc/core/connection/v1/tx.proto | 34 +- .../solomachine/v1/solomachine.proto | 10 +- .../tendermint/v1/tendermint.proto | 2 +- x/auth/client/rest/rest_test.go | 4 +- .../transfer/keeper/relay_test.go | 4 +- x/ibc/applications/transfer/module_test.go | 10 +- .../applications/transfer/types/msgs_test.go | 2 +- x/ibc/core/03-connection/client/cli/tx.go | 21 +- x/ibc/core/03-connection/genesis.go | 1 + .../03-connection/keeper/grpc_query_test.go | 14 +- x/ibc/core/03-connection/keeper/handshake.go | 124 ++++---- .../03-connection/keeper/handshake_test.go | 157 ++-------- x/ibc/core/03-connection/keeper/keeper.go | 28 ++ .../03-connection/types/connection_test.go | 2 +- x/ibc/core/03-connection/types/genesis.go | 11 +- x/ibc/core/03-connection/types/genesis.pb.go | 55 +++- .../core/03-connection/types/genesis_test.go | 4 + x/ibc/core/03-connection/types/keys.go | 44 +++ x/ibc/core/03-connection/types/keys_test.go | 44 +++ x/ibc/core/03-connection/types/msgs.go | 64 ++-- x/ibc/core/03-connection/types/msgs_test.go | 70 ++--- x/ibc/core/03-connection/types/tx.pb.go | 289 ++++++----------- x/ibc/core/04-channel/client/cli/tx.go | 31 +- x/ibc/core/04-channel/genesis.go | 1 + x/ibc/core/04-channel/handler.go | 22 +- x/ibc/core/04-channel/keeper/handshake.go | 133 ++++---- .../core/04-channel/keeper/handshake_test.go | 97 ++---- x/ibc/core/04-channel/keeper/keeper.go | 28 ++ x/ibc/core/04-channel/keeper/keeper_test.go | 10 +- x/ibc/core/04-channel/keeper/packet_test.go | 20 +- x/ibc/core/04-channel/types/genesis.go | 30 +- x/ibc/core/04-channel/types/genesis.pb.go | 100 ++++-- x/ibc/core/04-channel/types/genesis_test.go | 1 + x/ibc/core/04-channel/types/keys.go | 44 +++ x/ibc/core/04-channel/types/keys_test.go | 44 +++ x/ibc/core/04-channel/types/msgs.go | 69 +++-- x/ibc/core/04-channel/types/msgs_test.go | 72 ++--- x/ibc/core/04-channel/types/tx.pb.go | 291 ++++++------------ x/ibc/core/24-host/validate.go | 4 +- x/ibc/core/genesis_test.go | 5 + x/ibc/core/keeper/msg_server.go | 24 +- x/ibc/core/spec/01_concepts.md | 48 +-- x/ibc/core/spec/06_events.md | 2 - x/ibc/testing/chain.go | 45 ++- x/ibc/testing/coordinator.go | 48 ++- x/ibc/testing/types.go | 37 +-- 49 files changed, 1153 insertions(+), 1097 deletions(-) create mode 100644 x/ibc/core/03-connection/types/keys_test.go create mode 100644 x/ibc/core/04-channel/types/keys_test.go diff --git a/proto/ibc/core/channel/v1/genesis.proto b/proto/ibc/core/channel/v1/genesis.proto index a89e69c7dd..d3b2c0424e 100644 --- a/proto/ibc/core/channel/v1/genesis.proto +++ b/proto/ibc/core/channel/v1/genesis.proto @@ -18,6 +18,8 @@ message GenesisState { [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; } // PacketSequence defines the genesis type necessary to retrieve and store diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index c60ecc4363..5f84264124 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -46,10 +46,9 @@ message MsgChannelOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - Channel channel = 3 [(gogoproto.nullable) = false]; - string signer = 4; + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; } // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. @@ -61,15 +60,16 @@ message MsgChannelOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string desired_channel_id = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""]; - string counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""]; - Channel channel = 4 [(gogoproto.nullable) = false]; - string counterparty_version = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_init = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 7 + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + string previous_channel_id = 2 [(gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 8; + string signer = 7; } // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. @@ -147,9 +147,9 @@ message MsgRecvPacket { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 4; } @@ -162,9 +162,9 @@ message MsgTimeout { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 5; @@ -178,10 +178,10 @@ message MsgTimeoutOnClose { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; - ibc.core.client.v1.Height proof_height = 4 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 6; @@ -197,7 +197,7 @@ message MsgAcknowledgement { Packet packet = 1 [(gogoproto.nullable) = false]; bytes acknowledgement = 2; - bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; + bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 5; diff --git a/proto/ibc/core/connection/v1/genesis.proto b/proto/ibc/core/connection/v1/genesis.proto index 4cc2ab7a5e..11df4ba180 100644 --- a/proto/ibc/core/connection/v1/genesis.proto +++ b/proto/ibc/core/connection/v1/genesis.proto @@ -11,4 +11,6 @@ message GenesisState { repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; } diff --git a/proto/ibc/core/connection/v1/tx.proto b/proto/ibc/core/connection/v1/tx.proto index 02a12b0e31..21c283545d 100644 --- a/proto/ibc/core/connection/v1/tx.proto +++ b/proto/ibc/core/connection/v1/tx.proto @@ -29,11 +29,10 @@ message MsgConnectionOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - Version version = 4; - string signer = 5; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + string signer = 4; } // MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type. @@ -45,24 +44,25 @@ message MsgConnectionOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string desired_connection_id = 2 [(gogoproto.moretags) = "yaml:\"desired_connection_id\""]; - string counterparty_chosen_connection_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_connection_id\""]; - google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; - Counterparty counterparty = 5 [(gogoproto.nullable) = false]; - repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; - ibc.core.client.v1.Height proof_height = 7 + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""]; + google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + repeated Version counterparty_versions = 5 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + bytes proof_init = 7 [(gogoproto.moretags) = "yaml:\"proof_init\""]; // proof of client state included in message - bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + bytes proof_client = 8 [(gogoproto.moretags) = "yaml:\"proof_client\""]; // proof of client consensus state - bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 11 + bytes proof_consensus = 9 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 10 [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 12; + string signer = 11; } // MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. diff --git a/proto/ibc/lightclients/solomachine/v1/solomachine.proto b/proto/ibc/lightclients/solomachine/v1/solomachine.proto index 738217fa6c..89686f3b7f 100644 --- a/proto/ibc/lightclients/solomachine/v1/solomachine.proto +++ b/proto/ibc/lightclients/solomachine/v1/solomachine.proto @@ -48,11 +48,11 @@ message Header { // Misbehaviour defines misbehaviour for a solo machine which consists // of a sequence and two signatures over different messages at that sequence. message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; } // SignatureAndData contains a signature and the data signed over to create that diff --git a/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/proto/ibc/lightclients/tendermint/v1/tendermint.proto index 840bd97739..a6882bf432 100644 --- a/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -75,7 +75,7 @@ message ConsensusState { // Misbehaviour is a wrapper over two conflicting Headers // that implements Misbehaviour interface expected by ICS-02 message Misbehaviour { - option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_getters) = false; string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index b03b615b6a..889067d852 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -307,8 +307,8 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { val := s.network.Validators[0] args := []string{ - "121", // dummy port-id - "21212121212", // dummy channel-id + "121", // dummy port-id + "channel-0", // dummy channel-id fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), diff --git a/x/ibc/applications/transfer/keeper/relay_test.go b/x/ibc/applications/transfer/keeper/relay_test.go index 7878c59357..9f30317517 100644 --- a/x/ibc/applications/transfer/keeper/relay_test.go +++ b/x/ibc/applications/transfer/keeper/relay_test.go @@ -51,8 +51,8 @@ func (suite *KeeperTestSuite) TestSendTransfer() { {"next seq send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA = connA.NextTestChannel(ibctesting.TransferPort) - channelB = connB.NextTestChannel(ibctesting.TransferPort) + channelA = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB = suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually create channel so next seq send is never set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), diff --git a/x/ibc/applications/transfer/module_test.go b/x/ibc/applications/transfer/module_test.go index b0d0fd10e4..b6ce1077c6 100644 --- a/x/ibc/applications/transfer/module_test.go +++ b/x/ibc/applications/transfer/module_test.go @@ -33,7 +33,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -56,7 +56,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.INIT, @@ -122,7 +122,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -144,7 +144,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.TRYOPEN, @@ -210,7 +210,7 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterpartyVersion = types.Version module, _, err := suite.chainA.App.IBCKeeper.PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort) diff --git a/x/ibc/applications/transfer/types/msgs_test.go b/x/ibc/applications/transfer/types/msgs_test.go index 4c9eb80acd..89bd39524a 100644 --- a/x/ibc/applications/transfer/types/msgs_test.go +++ b/x/ibc/applications/transfer/types/msgs_test.go @@ -19,7 +19,7 @@ const ( validChannel = "testchannel" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" ) diff --git a/x/ibc/core/03-connection/client/cli/tx.go b/x/ibc/core/03-connection/client/cli/tx.go index 9526c5f8c0..bff4c5da94 100644 --- a/x/ibc/core/03-connection/client/cli/tx.go +++ b/x/ibc/core/03-connection/client/cli/tx.go @@ -22,23 +22,22 @@ import ( const ( flagVersionIdentifier = "version-identifier" flagVersionFeatures = "version-features" - flagProvedID = "proved-id" ) // NewConnectionOpenInitCmd defines the command to initialize a connection on // chain A with a given counterparty chain B func NewConnectionOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", + Use: "open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", Short: "Initialize connection on chain A", Long: `Initialize a connection on chain A with a given counterparty chain B. - 'version-identifier' flag can be a single pre-selected version identifier to be used in the handshake. - 'version-features' flag can be a list of features separated by commas to accompany the version identifier.`, Example: fmt.Sprintf( - "%s tx %s %s open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", + "%s tx %s %s open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", version.AppName, host.ModuleName, types.SubModuleName, ), - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -46,12 +45,10 @@ func NewConnectionOpenInitCmd() *cobra.Command { return err } - connectionID := args[0] - clientID := args[1] - counterpartyConnectionID := args[2] - counterpartyClientID := args[3] + clientID := args[0] + counterpartyClientID := args[1] - counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[4]) + counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[2]) if err != nil { return err } @@ -71,7 +68,7 @@ func NewConnectionOpenInitCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + clientID, counterpartyClientID, counterpartyPrefix, version, clientCtx.GetFromAddress(), ) @@ -116,7 +113,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { } connectionID := args[0] - provedID, _ := cmd.Flags().GetString(flagProvedID) clientID := args[1] counterpartyConnectionID := args[2] counterpartyClientID := args[3] @@ -179,7 +175,7 @@ func NewConnectionOpenTryCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenTry( - connectionID, provedID, clientID, counterpartyConnectionID, counterpartyClientID, + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, counterpartyClient, counterpartyPrefix, counterpartyVersions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, clientCtx.GetFromAddress(), @@ -193,7 +189,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { }, } - cmd.Flags().String(flagProvedID, "", "identifier set by the counterparty chain") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/x/ibc/core/03-connection/genesis.go b/x/ibc/core/03-connection/genesis.go index da8ffcd50d..4f97ed37ba 100644 --- a/x/ibc/core/03-connection/genesis.go +++ b/x/ibc/core/03-connection/genesis.go @@ -16,6 +16,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, connPaths := range gs.ClientConnectionPaths { k.SetClientConnectionPaths(ctx, connPaths.ClientId, connPaths.Paths) } + k.SetNextConnectionSequence(ctx, gs.NextConnectionSequence) } // ExportGenesis returns the ibc connection submodule's exported genesis. diff --git a/x/ibc/core/03-connection/keeper/grpc_query_test.go b/x/ibc/core/03-connection/keeper/grpc_query_test.go index 7e27b5af10..e710b0d547 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query_test.go +++ b/x/ibc/core/03-connection/keeper/grpc_query_test.go @@ -112,18 +112,18 @@ func (suite *KeeperTestSuite) TestQueryConnections() { "success", func() { clientA, clientB, connA0, connB0 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - connA1, connB1, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) + clientA1, clientB1, connA1, connB1 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) + connA2, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - clientA1, clientB1, connA2, connB2 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - counterparty1 := types.NewCounterparty(clientB, connB0.ID, suite.chainB.GetPrefix()) - counterparty2 := types.NewCounterparty(clientB, connB1.ID, suite.chainB.GetPrefix()) - counterparty3 := types.NewCounterparty(clientB1, connB2.ID, suite.chainB.GetPrefix()) + counterparty2 := types.NewCounterparty(clientB1, connB1.ID, suite.chainB.GetPrefix()) + // counterparty connection id is blank after open init + counterparty3 := types.NewCounterparty(clientB, "", suite.chainB.GetPrefix()) conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterparty1, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn2 := types.NewConnectionEnd(types.INIT, clientA, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn3 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn2 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn3 := types.NewConnectionEnd(types.INIT, clientA, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1) iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2) diff --git a/x/ibc/core/03-connection/keeper/handshake.go b/x/ibc/core/03-connection/keeper/handshake.go index 0fce7d9006..7a7d700570 100644 --- a/x/ibc/core/03-connection/keeper/handshake.go +++ b/x/ibc/core/03-connection/keeper/handshake.go @@ -14,36 +14,33 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ) -// ConnOpenInit initialises a connection attempt on chain A. +// ConnOpenInit initialises a connection attempt on chain A. The generated connection identifier +// is returned. // -// NOTE: Identifiers are checked on msg validation. +// NOTE: Msg validation verifies the supplied identifiers and ensures that the counterparty +// connection identifier is empty. func (k Keeper) ConnOpenInit( ctx sdk.Context, - connectionID, // identifier clientID string, - counterparty types.Counterparty, // desiredCounterpartyConnectionIdentifier, counterpartyPrefix, counterpartyClientIdentifier + counterparty types.Counterparty, // counterpartyPrefix, counterpartyClientIdentifier version *types.Version, -) error { - _, found := k.GetConnection(ctx, connectionID) - if found { - return sdkerrors.Wrap(types.ErrConnectionExists, connectionID) - } - +) (string, error) { versions := types.GetCompatibleVersions() if version != nil { if !types.IsSupportedVersion(version) { - return sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") + return "", sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") } versions = []exported.Version{version} } // connection defines chain A's ConnectionEnd + connectionID := k.GenerateConnectionIdentifier(ctx) connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions)) k.SetConnection(ctx, connectionID, connection) if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { - return err + return "", err } k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "NONE", "new-state", "INIT") @@ -52,7 +49,7 @@ func (k Keeper) ConnOpenInit( telemetry.IncrCounter(1, "ibc", "connection", "open-init") }() - return nil + return connectionID, nil } // ConnOpenTry relays notice of a connection attempt on chain A to chain B (this @@ -63,8 +60,7 @@ func (k Keeper) ConnOpenInit( // - Identifiers are checked on msg validation func (k Keeper) ConnOpenTry( ctx sdk.Context, - desiredConnectionID, // desiredIdentifier - counterpartyChosenConnectionID string, // counterparty used this identifier in proof + previousConnectionID string, // previousIdentifier counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier clientID string, // clientID of chainA clientState exported.ClientState, // clientState that chainA has for chainB @@ -74,10 +70,47 @@ func (k Keeper) ConnOpenTry( proofConsensus []byte, // proof that chainA stored chainB's consensus state at consensus height proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client -) error { +) (string, error) { + var ( + connectionID string + previousConnection types.ConnectionEnd + found bool + ) + + // empty connection identifier indicates continuing a previous connection handshake + if previousConnectionID != "" { + // ensure that the previous connection exists + previousConnection, found = k.GetConnection(ctx, previousConnectionID) + if !found { + return "", sdkerrors.Wrapf(types.ErrConnectionNotFound, "previous connection does not exist for supplied previous connectionID %s", previousConnectionID) + } + + // ensure that the existing connection's + // counterparty is chainA and connection is on INIT stage. + // Check that existing connection versions for initialized connection is equal to compatible + // versions for this chain. + if !(previousConnection.Counterparty.ConnectionId == "" && + bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && + previousConnection.ClientId == clientID && + previousConnection.Counterparty.ClientId == counterparty.ClientId) { + return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields") + } + + if !(previousConnection.State == types.INIT) { + return "", sdkerrors.Wrapf(types.ErrInvalidConnectionState, "previous connection state is in state %s, expected INIT", previousConnection.State) + } + + // continue with previous connection + connectionID = previousConnectionID + + } else { + // generate a new connection + connectionID = k.GenerateConnectionIdentifier(ctx) + } + selfHeight := clienttypes.GetSelfHeight(ctx) if consensusHeight.GTE(selfHeight) { - return sdkerrors.Wrapf( + return "", sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, "consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight, ) @@ -85,43 +118,20 @@ func (k Keeper) ConnOpenTry( // validate client parameters of a chainB client stored on chainA if err := k.clientKeeper.ValidateSelfClient(ctx, clientState); err != nil { - return err + return "", err } expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { - return sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) - } - - // If the connection id chosen for this connection end by the counterparty is empty then - // flexible connection identifier selection is allowed by using the desired connection id. - // Otherwise the desiredConnectionID must match the counterpartyChosenConnectionID. - if counterpartyChosenConnectionID != "" && counterpartyChosenConnectionID != desiredConnectionID { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty chosen connection ID (%s) must be empty or equal to the desired connection ID (%s)", counterpartyChosenConnectionID, desiredConnectionID, - ) + return "", sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) } // expectedConnection defines Chain A's ConnectionEnd // NOTE: chain A's counterparty is chain B (i.e where this code is executed) prefix := k.GetCommitmentPrefix() - expectedCounterparty := types.NewCounterparty(clientID, counterpartyChosenConnectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes())) + expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions)) - // If connection already exists for desiredConnectionID, ensure that the existing connection's - // counterparty is chainA and connection is on INIT stage. - // Check that existing connection versions for initialized connection is equal to compatible - // versions for this chain. - previousConnection, found := k.GetConnection(ctx, desiredConnectionID) - if found && !(previousConnection.State == types.INIT && - previousConnection.Counterparty.ConnectionId == counterparty.ConnectionId && - bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && - previousConnection.ClientId == clientID && - previousConnection.Counterparty.ClientId == counterparty.ClientId) { - return sdkerrors.Wrap(types.ErrInvalidConnection, "cannot relay connection attempt") - } - supportedVersions := types.GetCompatibleVersions() if len(previousConnection.Versions) != 0 { supportedVersions = previousConnection.GetVersions() @@ -132,7 +142,7 @@ func (k Keeper) ConnOpenTry( // of the supported versions and the counterparty versions. version, err := types.PickVersion(supportedVersions, counterpartyVersions) if err != nil { - return err + return "", err } // connection defines chain B's ConnectionEnd @@ -143,34 +153,34 @@ func (k Keeper) ConnOpenTry( ctx, connection, proofHeight, proofInit, counterparty.ConnectionId, expectedConnection, ); err != nil { - return err + return "", err } // Check that ChainA stored the clientState provided in the msg if err := k.VerifyClientState(ctx, connection, proofHeight, proofClient, clientState); err != nil { - return err + return "", err } // Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight if err := k.VerifyClientConsensusState( ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { - return err + return "", err } // store connection in chainB state - if err := k.addConnectionToClient(ctx, clientID, desiredConnectionID); err != nil { - return sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", desiredConnectionID, clientID) + if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { + return "", sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID) } - k.SetConnection(ctx, desiredConnectionID, connection) - k.Logger(ctx).Info("connection state updated", "connection-id", desiredConnectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "connection", "open-try") }() - return nil + return connectionID, nil } // ConnOpenAck relays acceptance of a connection open attempt from chain B back @@ -204,16 +214,6 @@ func (k Keeper) ConnOpenAck( return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) } - // If the previously set connection end allowed for the counterparty to select its own - // connection identifier then we use the counterpartyConnectionID. Otherwise the - // counterpartyConnectionID must match the previously set counterparty connection ID. - if connection.Counterparty.ConnectionId != "" && counterpartyConnectionID != connection.Counterparty.ConnectionId { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty connection identifier (%s) must be equal to stored connection ID for counterparty (%s)", counterpartyConnectionID, connection.Counterparty.ConnectionId, - ) - } - // Verify the provided version against the previously set connection state switch { // connection on ChainA must be in INIT or TRYOPEN diff --git a/x/ibc/core/03-connection/keeper/handshake_test.go b/x/ibc/core/03-connection/keeper/handshake_test.go index 2ece130ebb..eb9ca5c401 100644 --- a/x/ibc/core/03-connection/keeper/handshake_test.go +++ b/x/ibc/core/03-connection/keeper/handshake_test.go @@ -36,9 +36,6 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] }, true}, - {"connection already exists", func() { - clientA, clientB, _, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - }, false}, {"invalid version", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = &types.Version{} @@ -58,19 +55,20 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { tc.malleate() - connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) if emptyConnBID { connB.ID = "" } counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix()) - err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), connA.ID, clientA, counterparty, version) + connectionID, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), clientA, counterparty, version) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -80,11 +78,12 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { // connection on chainA is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { var ( - clientA string - clientB string - versions []exported.Version - consensusHeight exported.Height - counterpartyClient exported.ClientState + clientA string + clientB string + previousConnectionID string + versions []exported.Version + consensusHeight exported.Height + counterpartyClient exported.ClientState ) testCases := []struct { @@ -100,50 +99,16 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) }, true}, - {"success with empty counterpartyChosenConnectionID", func() { + {"success with crossing hellos", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) + _, connB, err := suite.coordinator.ConnOpenInitOnBothChains(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, true}, - {"counterpartyChosenConnectionID does not match desiredConnectionID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to invalid identifier - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "badidentifier" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainA to pass as counterpartyClient - counterpartyClient = suite.chainA.GetClientState(clientA) - }, false}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) _, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -255,6 +220,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, {"invalid previous connection has invalid versions", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -281,6 +248,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, } @@ -291,20 +260,13 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.SetupTest() // reset consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate versions = types.GetCompatibleVersions() // must be explicitly changed in malleate + previousConnectionID = "" tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) - connB := suite.chainB.GetFirstTestConnection(clientB, clientA) counterparty := types.NewCounterparty(clientA, connA.ID, suite.chainA.GetPrefix()) - // get counterpartyChosenConnectionID - var counterpartyChosenConnectionID string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - if found { - counterpartyChosenConnectionID = connection.Counterparty.ConnectionId - } - connectionKey := host.ConnectionKey(connA.ID) proofInit, proofHeight := suite.chainA.QueryProof(connectionKey) @@ -319,16 +281,18 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { clientKey := host.FullClientStateKey(clientA) proofClient, _ := suite.chainA.QueryProof(clientKey) - err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.chainB.GetContext(), connB.ID, counterpartyChosenConnectionID, counterparty, clientB, counterpartyClient, + connectionID, err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.chainB.GetContext(), previousConnectionID, counterparty, clientB, counterpartyClient, versions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, ) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -338,12 +302,11 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // the initialization (TRYINIT) of the connection on Chain B (ID #2). func (suite *KeeperTestSuite) TestConnOpenAck() { var ( - clientA string - clientB string - counterpartyConnectionID string - consensusHeight exported.Height - version *types.Version - counterpartyClient exported.ClientState + clientA string + clientB string + consensusHeight exported.Height + version *types.Version + counterpartyClient exported.ClientState ) testCases := []struct { @@ -362,33 +325,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success with empty stored counterparty connection ID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainB, suite.chainA, connB, connA) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - // use some other identifier - counterpartyConnectionID = connB.ID - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"success from tryopen", func() { // chainA is in TRYOPEN, chainB is in TRYOPEN clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -401,6 +337,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // set chainB to TRYOPEN connection := suite.chainB.GetConnection(connB) connection.State = types.TRYOPEN + connection.Counterparty.ConnectionId = connA.ID suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) // update clientB so state change is committed suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) @@ -410,37 +347,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success from tryopen with empty stored connection id", func() { - // chainA is in TRYOPEN, chainB is in TRYOPEN - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainA, suite.chainB, connA, connB) - suite.Require().NoError(err) - - // set chainB to TRYOPEN - connection := suite.chainB.GetConnection(connB) - connection.State = types.TRYOPEN - - suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) - - // set connA to use empty string - connection = suite.chainA.GetConnection(connA) - - // set counterparty connection identifier to empty string - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - // update clientB so state change is committed - suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - - suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -663,17 +569,12 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.SetupTest() // reset version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] // must be explicitly changed in malleate consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate - counterpartyConnectionID = "" // must be explicitly changed in malleate tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) - if counterpartyConnectionID == "" { - counterpartyConnectionID = connB.ID - } - connectionKey := host.ConnectionKey(connB.ID) proofTry, proofHeight := suite.chainB.QueryProof(connectionKey) @@ -690,7 +591,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { proofClient, _ := suite.chainB.QueryProof(clientKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.chainA.GetContext(), connA.ID, counterpartyClient, version, counterpartyConnectionID, + suite.chainA.GetContext(), connA.ID, counterpartyClient, version, connB.ID, proofTry, proofClient, proofConsensus, proofHeight, consensusHeight, ) diff --git a/x/ibc/core/03-connection/keeper/keeper.go b/x/ibc/core/03-connection/keeper/keeper.go index dda5295877..05d110fec8 100644 --- a/x/ibc/core/03-connection/keeper/keeper.go +++ b/x/ibc/core/03-connection/keeper/keeper.go @@ -45,6 +45,16 @@ func (k Keeper) GetCommitmentPrefix() exported.Prefix { return commitmenttypes.NewMerklePrefix([]byte(k.storeKey.Name())) } +// GenerateConnectionIdentifier returns the next connection identifier. +func (k Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string { + nextConnSeq := k.GetNextConnectionSequence(ctx) + connectionID := types.FormatConnectionIdentifier(nextConnSeq) + + nextConnSeq++ + k.SetNextConnectionSequence(ctx, nextConnSeq) + return connectionID +} + // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { store := ctx.KVStore(k.storeKey) @@ -105,6 +115,24 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths store.Set(host.ClientConnectionsKey(clientID), bz) } +// GetNextConnectionSequence gets the next connection sequence from the store. +func (k Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextConnectionSequence)) + if bz == nil { + panic("next connection sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextConnectionSequence sets the next connection sequence to the store. +func (k Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextConnectionSequence), bz) +} + // GetAllClientConnectionPaths returns all stored clients connection id paths. It // will ignore the clients that haven't initialized a connection handshake since // no paths are stored. diff --git a/x/ibc/core/03-connection/types/connection_test.go b/x/ibc/core/03-connection/types/connection_test.go index 93891cbea1..133bb1e5c6 100644 --- a/x/ibc/core/03-connection/types/connection_test.go +++ b/x/ibc/core/03-connection/types/connection_test.go @@ -13,7 +13,7 @@ import ( var ( chainID = "gaiamainnet" - connectionID = "connectionidone" + connectionID = "connection-0" clientID = "clientidone" connectionID2 = "connectionidtwo" clientID2 = "clientidtwo" diff --git a/x/ibc/core/03-connection/types/genesis.go b/x/ibc/core/03-connection/types/genesis.go index 58b21678c2..f5af9b8486 100644 --- a/x/ibc/core/03-connection/types/genesis.go +++ b/x/ibc/core/03-connection/types/genesis.go @@ -17,18 +17,21 @@ func NewConnectionPaths(id string, paths []string) ConnectionPaths { // NewGenesisState creates a GenesisState instance. func NewGenesisState( connections []IdentifiedConnection, connPaths []ConnectionPaths, + nextConnectionSequence uint64, ) GenesisState { return GenesisState{ - Connections: connections, - ClientConnectionPaths: connPaths, + Connections: connections, + ClientConnectionPaths: connPaths, + NextConnectionSequence: nextConnectionSequence, } } // DefaultGenesisState returns the ibc connection submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Connections: []IdentifiedConnection{}, - ClientConnectionPaths: []ConnectionPaths{}, + Connections: []IdentifiedConnection{}, + ClientConnectionPaths: []ConnectionPaths{}, + NextConnectionSequence: 0, } } diff --git a/x/ibc/core/03-connection/types/genesis.pb.go b/x/ibc/core/03-connection/types/genesis.pb.go index ba8b3bcd5b..19c4e6aeb8 100644 --- a/x/ibc/core/03-connection/types/genesis.pb.go +++ b/x/ibc/core/03-connection/types/genesis.pb.go @@ -27,6 +27,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { Connections []IdentifiedConnection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections"` ClientConnectionPaths []ConnectionPaths `protobuf:"bytes,2,rep,name=client_connection_paths,json=clientConnectionPaths,proto3" json:"client_connection_paths" yaml:"client_connection_paths"` + // the sequence for the next generated connection identifier + NextConnectionSequence uint64 `protobuf:"varint,3,opt,name=next_connection_sequence,json=nextConnectionSequence,proto3" json:"next_connection_sequence,omitempty" yaml:"next_connection_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -76,6 +78,13 @@ func (m *GenesisState) GetClientConnectionPaths() []ConnectionPaths { return nil } +func (m *GenesisState) GetNextConnectionSequence() uint64 { + if m != nil { + return m.NextConnectionSequence + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "ibc.core.connection.v1.GenesisState") } @@ -85,25 +94,28 @@ func init() { } var fileDescriptor_1879d34bc6ac3cd7 = []byte{ - // 281 bytes of a gzipped FileDescriptorProto + // 326 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc9, 0x4c, 0x4a, 0xd6, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcb, 0x4b, 0x4d, 0x2e, 0xc9, 0xcc, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xcb, 0x4c, 0x4a, 0xd6, 0x03, 0xa9, 0xd2, 0x43, 0xa8, 0xd2, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0xd4, 0x71, 0x98, 0x89, - 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x1d, 0x23, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, + 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x2c, 0x13, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0xa1, 0x10, 0x2e, 0x6e, 0x84, 0xa2, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x1d, 0x3d, 0xec, 0xb6, 0xeb, 0x79, 0xa6, 0xa4, 0xe6, 0x95, 0x64, 0xa6, 0x65, 0xa6, 0xa6, 0x38, 0xc3, 0xc5, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x42, 0x36, 0x46, 0xa8, 0x9d, 0x91, 0x4b, 0x3c, 0x39, 0x27, 0x33, 0x35, 0xaf, 0x24, 0x1e, 0x21, 0x1c, 0x5f, 0x90, 0x58, 0x92, 0x51, 0x2c, 0xc1, 0x04, 0xb6, 0x42, 0x1d, 0x97, 0x15, 0x08, 0x83, 0x03, 0x40, 0xca, 0x9d, 0xd4, 0x40, 0xa6, 0x7f, 0xba, 0x27, 0x2f, 0x57, 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x84, 0xc3, 0x54, 0xa5, 0x20, 0x51, 0x88, - 0x0c, 0xba, 0xf6, 0xd0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, - 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4e, - 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, - 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, 0xfa, 0x15, 0xfa, 0xf0, 0x20, 0x35, 0x30, 0xd6, 0x45, 0x0a, - 0xd5, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0x70, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, - 0xff, 0xae, 0x12, 0xc8, 0x83, 0xcd, 0x01, 0x00, 0x00, + 0x0c, 0x9a, 0x76, 0xa1, 0x58, 0x2e, 0x89, 0xbc, 0xd4, 0x0a, 0x14, 0x0d, 0xc5, 0xa9, 0x85, 0xa5, + 0xa9, 0x79, 0xc9, 0xa9, 0x12, 0xcc, 0x0a, 0x8c, 0x1a, 0x2c, 0x4e, 0xca, 0x9f, 0xee, 0xc9, 0xcb, + 0x43, 0x0c, 0xc7, 0xa5, 0x52, 0x29, 0x48, 0x0c, 0x24, 0x85, 0x30, 0x3b, 0x18, 0x2a, 0xe1, 0x14, + 0x7a, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, + 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xd6, 0xe9, 0x99, 0x25, 0x19, + 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0x50, 0x4a, 0xb7, + 0x38, 0x25, 0x5b, 0xbf, 0x42, 0x1f, 0x1e, 0x63, 0x06, 0xc6, 0xba, 0x48, 0x91, 0x56, 0x52, 0x59, + 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x2d, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xad, + 0x14, 0x09, 0x2c, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -126,6 +138,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextConnectionSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextConnectionSequence)) + i-- + dAtA[i] = 0x18 + } if len(m.ClientConnectionPaths) > 0 { for iNdEx := len(m.ClientConnectionPaths) - 1; iNdEx >= 0; iNdEx-- { { @@ -186,6 +203,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextConnectionSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextConnectionSequence)) + } return n } @@ -292,6 +312,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextConnectionSequence", wireType) + } + m.NextConnectionSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextConnectionSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/03-connection/types/genesis_test.go b/x/ibc/core/03-connection/types/genesis_test.go index 6290a98a9f..343d69b08e 100644 --- a/x/ibc/core/03-connection/types/genesis_test.go +++ b/x/ibc/core/03-connection/types/genesis_test.go @@ -31,6 +31,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: true, }, @@ -43,6 +44,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -55,6 +57,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {"(CLIENTIDONE)", []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -67,6 +70,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{invalidConnectionID}}, }, + 0, ), expPass: false, }, diff --git a/x/ibc/core/03-connection/types/keys.go b/x/ibc/core/03-connection/types/keys.go index 23478ec759..c44602203e 100644 --- a/x/ibc/core/03-connection/types/keys.go +++ b/x/ibc/core/03-connection/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC connection name SubModuleName = "connection" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC connections QuerierRoute = SubModuleName + + // KeyNextConnectionSequence is the key used to store the next connection sequence in + // the keeper. + KeyNextConnectionSequence = "nextConnectionSequence" + + // ConnectionPrefix is the prefix used when creating a connection identifier + ConnectionPrefix = "connection-" ) + +// FormatConnectionIdentifier returns the connection identifier with the sequence appended. +func FormatConnectionIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ConnectionPrefix, sequence) +} + +// IsValidConnectionID return true if the connection identifier is valid. +func IsValidConnectionID(connectionID string) bool { + _, err := ParseConnectionSequence(connectionID) + return err == nil +} + +// ParseConnectionSequence parses the connection sequence from the connection identifier. +func ParseConnectionSequence(connectionID string) (uint64, error) { + if !strings.HasPrefix(connectionID, ConnectionPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidConnectionIdentifier, "doesn't contain prefix `%s`", ConnectionPrefix) + } + + splitStr := strings.Split(connectionID, ConnectionPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "connection identifier must be in format: `connection-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse connection identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/03-connection/types/keys_test.go b/x/ibc/core/03-connection/types/keys_test.go new file mode 100644 index 0000000000..261bd2895f --- /dev/null +++ b/x/ibc/core/03-connection/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" + "github.com/stretchr/testify/require" +) + +// tests ParseConnectionSequence and IsValidConnectionID +func TestParseConnectionSequence(t *testing.T) { + testCases := []struct { + name string + connectionID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "connection-0", 0, true}, + {"valid 1", "connection-1", 1, true}, + {"valid large sequence", "connection-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "connection-2345682193567182931243", 0, false}, + {"capital prefix", "Connection-0", 0, false}, + {"missing dash", "connection0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "connection--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseConnectionSequence(tc.connectionID) + valid := types.IsValidConnectionID(tc.connectionID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/03-connection/types/msgs.go b/x/ibc/core/03-connection/types/msgs.go index a162fb589b..a734f98608 100644 --- a/x/ibc/core/03-connection/types/msgs.go +++ b/x/ibc/core/03-connection/types/msgs.go @@ -12,16 +12,16 @@ import ( var _ sdk.Msg = &MsgConnectionOpenInit{} -// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance +// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance. It sets the +// counterparty connection identifier to be empty. //nolint:interfacer func NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyPrefix commitmenttypes.MerklePrefix, + clientID, counterpartyClientID string, + counterpartyPrefix commitmenttypes.MerklePrefix, version *Version, signer sdk.AccAddress, ) *MsgConnectionOpenInit { - counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + counterparty := NewCounterparty(counterpartyClientID, "", counterpartyPrefix) return &MsgConnectionOpenInit{ - ConnectionId: connectionID, ClientId: clientID, Counterparty: counterparty, Version: version, @@ -41,12 +41,13 @@ func (msg MsgConnectionOpenInit) Type() string { // ValidateBasic implements sdk.Msg. func (msg MsgConnectionOpenInit) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") - } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + if msg.Counterparty.ConnectionId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty connection identifier must be empty") + } + // NOTE: Version can be nil on MsgConnectionOpenInit if msg.Version != nil { if err := ValidateVersion(msg.Version); err != nil { @@ -80,7 +81,7 @@ var _ sdk.Msg = &MsgConnectionOpenTry{} // NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance //nolint:interfacer func NewMsgConnectionOpenTry( - desiredConnectionID, counterpartyChosenConnectionID, clientID, counterpartyConnectionID, + previousConnectionID, clientID, counterpartyConnectionID, counterpartyClientID string, counterpartyClient exported.ClientState, counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyVersions []*Version, proofInit, proofClient, proofConsensus []byte, @@ -89,18 +90,17 @@ func NewMsgConnectionOpenTry( counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) csAny, _ := clienttypes.PackClientState(counterpartyClient) return &MsgConnectionOpenTry{ - DesiredConnectionId: desiredConnectionID, - CounterpartyChosenConnectionId: counterpartyChosenConnectionID, - ClientId: clientID, - ClientState: csAny, - Counterparty: counterparty, - CounterpartyVersions: counterpartyVersions, - ProofInit: proofInit, - ProofClient: proofClient, - ProofConsensus: proofConsensus, - ProofHeight: proofHeight, - ConsensusHeight: consensusHeight, - Signer: signer.String(), + PreviousConnectionId: previousConnectionID, + ClientId: clientID, + ClientState: csAny, + Counterparty: counterparty, + CounterpartyVersions: counterpartyVersions, + ProofInit: proofInit, + ProofClient: proofClient, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer.String(), } } @@ -116,15 +116,19 @@ func (msg MsgConnectionOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.DesiredConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid desired connection ID") - } - if msg.CounterpartyChosenConnectionId != "" && msg.CounterpartyChosenConnectionId != msg.DesiredConnectionId { - return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "counterparty chosen connection identifier must be empty or equal to desired connection identifier") + // an empty connection identifier indicates that a connection identifier should be generated + if msg.PreviousConnectionId != "" { + if !IsValidConnectionID(msg.PreviousConnectionId) { + return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "invalid previous connection ID") + } } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + // counterparty validate basic allows empty counterparty connection identifiers + if err := host.ConnectionIdentifierValidator(msg.Counterparty.ConnectionId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty connection ID") + } if msg.ClientState == nil { return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") } @@ -234,8 +238,8 @@ func (msg MsgConnectionOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenAck) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if err := host.ConnectionIdentifierValidator(msg.CounterpartyConnectionId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty connection ID") @@ -318,8 +322,8 @@ func (msg MsgConnectionOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenConfirm) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") diff --git a/x/ibc/core/03-connection/types/msgs_test.go b/x/ibc/core/03-connection/types/msgs_test.go index 675de99347..9c09ec1f7b 100644 --- a/x/ibc/core/03-connection/types/msgs_test.go +++ b/x/ibc/core/03-connection/types/msgs_test.go @@ -87,14 +87,13 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { msg *types.MsgConnectionOpenInit expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenInit("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenInit("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "test/conn1", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "test/conn1", prefix, version, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", emptyPrefix, version, signer), false}, - {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, &types.Version{}, signer), false}, - {"empty singer", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, nil), false}, - {"success", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, signer), true}, + {"invalid client ID", types.NewMsgConnectionOpenInit("test/iris", "clienttotest", prefix, version, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("clienttotest", "(clienttotest)", prefix, version, signer), false}, + {"invalid counterparty connection ID", &types.MsgConnectionOpenInit{connectionID, types.NewCounterparty("clienttotest", "connectiontotest", prefix), version, signer.String()}, false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", emptyPrefix, version, signer), false}, + {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, &types.Version{}, signer), false}, + {"empty singer", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, nil), false}, + {"success", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, signer), true}, } for _, tc := range testCases { @@ -112,7 +111,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -124,33 +123,32 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - provedID := "" var testCases = []struct { name string msg *types.MsgConnectionOpenTry expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid connection ID", types.NewMsgConnectionOpenTry("ibcconntest", "test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid nil counterparty client", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client unpacking", &types.MsgConnectionOpenTry{"ibcconntest", provedID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, - {"counterparty failed Validate", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterpartyVersions", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofInit", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofClient", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofConsensus", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, - {"invalid proofHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, - {"invalid consensusHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, - {"empty singer", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, - {"success", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, - {"invalid version", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, + {"counterparty failed Validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, + {"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, + {"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, + {"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, + {"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, + {"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, } for _, tc := range testCases { @@ -166,7 +164,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -177,9 +175,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - connectionID := "ibcconntest" + connectionID := "connection-0" var testCases = []struct { name string @@ -216,10 +214,10 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { testMsgs := []*types.MsgConnectionOpenConfirm{ types.NewMsgConnectionOpenConfirm("test/conn1", suite.proof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", emptyProof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clienttypes.ZeroHeight(), signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, nil), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, emptyProof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clienttypes.ZeroHeight(), signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, nil), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, signer), } var testCases = []struct { diff --git a/x/ibc/core/03-connection/types/tx.pb.go b/x/ibc/core/03-connection/types/tx.pb.go index be78639db0..05e60cf3e1 100644 --- a/x/ibc/core/03-connection/types/tx.pb.go +++ b/x/ibc/core/03-connection/types/tx.pb.go @@ -34,10 +34,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // initialize a connection with Chain B. type MsgConnectionOpenInit struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - Counterparty Counterparty `protobuf:"bytes,3,opt,name=counterparty,proto3" json:"counterparty"` - Version *Version `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"` + Version *Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenInit) Reset() { *m = MsgConnectionOpenInit{} } @@ -113,22 +112,23 @@ var xxx_messageInfo_MsgConnectionOpenInitResponse proto.InternalMessageInfo // MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a // connection on Chain B. type MsgConnectionOpenTry struct { - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - DesiredConnectionId string `protobuf:"bytes,2,opt,name=desired_connection_id,json=desiredConnectionId,proto3" json:"desired_connection_id,omitempty" yaml:"desired_connection_id"` - CounterpartyChosenConnectionId string `protobuf:"bytes,3,opt,name=counterparty_chosen_connection_id,json=counterpartyChosenConnectionId,proto3" json:"counterparty_chosen_connection_id,omitempty" yaml:"counterparty_chosen_connection_id"` - ClientState *types.Any `protobuf:"bytes,4,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` - Counterparty Counterparty `protobuf:"bytes,5,opt,name=counterparty,proto3" json:"counterparty"` - CounterpartyVersions []*Version `protobuf:"bytes,6,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` - ProofHeight types1.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + PreviousConnectionId string `protobuf:"bytes,2,opt,name=previous_connection_id,json=previousConnectionId,proto3" json:"previous_connection_id,omitempty" yaml:"previous_connection_id"` + ClientState *types.Any `protobuf:"bytes,3,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` + Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"` + CounterpartyVersions []*Version `protobuf:"bytes,5,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` + ProofHeight types1.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - ProofInit []byte `protobuf:"bytes,8,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofInit []byte `protobuf:"bytes,7,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` // proof of client state included in message - ProofClient []byte `protobuf:"bytes,9,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` + ProofClient []byte `protobuf:"bytes,8,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` // proof of client consensus state - ProofConsensus []byte `protobuf:"bytes,10,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` - ConsensusHeight types1.Height `protobuf:"bytes,11,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` - Signer string `protobuf:"bytes,12,opt,name=signer,proto3" json:"signer,omitempty"` + ProofConsensus []byte `protobuf:"bytes,9,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` + ConsensusHeight types1.Height `protobuf:"bytes,10,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` + Signer string `protobuf:"bytes,11,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} } @@ -384,65 +384,62 @@ func init() { func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) } var fileDescriptor_5d00fde5fc97399e = []byte{ - // 917 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x3f, 0x93, 0xdb, 0x44, - 0x14, 0xb7, 0xce, 0xf7, 0xc7, 0xde, 0x33, 0x24, 0x51, 0xec, 0x3b, 0x21, 0x82, 0xe4, 0xec, 0xc0, - 0x70, 0x45, 0x4e, 0x8a, 0x93, 0x30, 0x03, 0xc7, 0x50, 0xd8, 0x6e, 0xb8, 0x22, 0xc0, 0x88, 0x83, - 0x22, 0x8d, 0xc7, 0x96, 0xd7, 0xb2, 0xc6, 0xe7, 0x5d, 0x8f, 0x56, 0x76, 0x22, 0x5a, 0x1a, 0x86, - 0x8a, 0x8f, 0x90, 0x4f, 0xc1, 0x67, 0x48, 0x47, 0x4a, 0x2a, 0x0d, 0xdc, 0x35, 0xd4, 0xea, 0xe8, - 0x18, 0xad, 0xfe, 0x78, 0x65, 0xcb, 0x73, 0x36, 0xe7, 0x54, 0xd2, 0xdb, 0xf7, 0x7b, 0xef, 0xed, - 0xfe, 0xf6, 0xfd, 0xde, 0x2c, 0x50, 0xed, 0x9e, 0xa9, 0x9b, 0xc4, 0x41, 0xba, 0x49, 0x30, 0x46, - 0xa6, 0x6b, 0x13, 0xac, 0xcf, 0x1a, 0xba, 0xfb, 0x4a, 0x9b, 0x38, 0xc4, 0x25, 0xe2, 0x91, 0xdd, - 0x33, 0xb5, 0x10, 0xa0, 0xcd, 0x01, 0xda, 0xac, 0x21, 0x57, 0x2d, 0x62, 0x11, 0x06, 0xd1, 0xc3, - 0xbf, 0x08, 0x2d, 0x7f, 0x60, 0x11, 0x62, 0x5d, 0x22, 0x9d, 0x59, 0xbd, 0xe9, 0x40, 0xef, 0x62, - 0x2f, 0x76, 0x71, 0x95, 0x2e, 0x6d, 0x84, 0xdd, 0xb0, 0x4a, 0xf4, 0x17, 0x03, 0x3e, 0x5d, 0xb1, - 0x15, 0xae, 0x2e, 0x03, 0xc2, 0xdf, 0x77, 0x40, 0xed, 0x39, 0xb5, 0xda, 0xe9, 0xfa, 0xb7, 0x13, - 0x84, 0xcf, 0xb1, 0xed, 0x8a, 0x0d, 0x50, 0x8e, 0x52, 0x76, 0xec, 0xbe, 0x24, 0xd4, 0x85, 0x93, - 0x72, 0xab, 0x1a, 0xf8, 0xea, 0x5d, 0xaf, 0x3b, 0xbe, 0x3c, 0x83, 0xa9, 0x0b, 0x1a, 0xa5, 0xe8, - 0xff, 0xbc, 0x2f, 0x7e, 0x05, 0xde, 0x9b, 0x17, 0x08, 0xc3, 0x76, 0x58, 0x98, 0x14, 0xf8, 0x6a, - 0x35, 0x0e, 0xe3, 0xdd, 0xd0, 0xa8, 0xcc, 0xed, 0xf3, 0xbe, 0xf8, 0x0d, 0xa8, 0x98, 0x64, 0x8a, - 0x5d, 0xe4, 0x4c, 0xba, 0x8e, 0xeb, 0x49, 0xc5, 0xba, 0x70, 0x72, 0xf8, 0xe4, 0x63, 0x2d, 0x9f, - 0x35, 0xad, 0xcd, 0x61, 0x5b, 0xbb, 0x6f, 0x7c, 0xb5, 0x60, 0x64, 0xe2, 0xc5, 0x2f, 0xc0, 0xc1, - 0x0c, 0x39, 0xd4, 0x26, 0x58, 0xda, 0x65, 0xa9, 0xd4, 0x55, 0xa9, 0x7e, 0x8c, 0x60, 0x46, 0x82, - 0x17, 0x8f, 0xc0, 0x3e, 0xb5, 0x2d, 0x8c, 0x1c, 0x69, 0x2f, 0x3c, 0x82, 0x11, 0x5b, 0x67, 0xa5, - 0x5f, 0x5e, 0xab, 0x85, 0x7f, 0x5e, 0xab, 0x05, 0xa8, 0x82, 0x8f, 0x72, 0x79, 0x33, 0x10, 0x9d, - 0x10, 0x4c, 0x11, 0xfc, 0xe3, 0x00, 0x54, 0x97, 0x10, 0x17, 0x8e, 0xf7, 0x7f, 0x88, 0xbd, 0x00, - 0xb5, 0x3e, 0xa2, 0xb6, 0x83, 0xfa, 0x9d, 0x3c, 0x82, 0xeb, 0x81, 0xaf, 0x3e, 0x88, 0xc2, 0x73, - 0x61, 0xd0, 0xb8, 0x1f, 0xaf, 0xb7, 0x79, 0xbe, 0x5f, 0x82, 0x87, 0x3c, 0x5f, 0x1d, 0x73, 0x48, - 0x28, 0xc2, 0x0b, 0x15, 0x8a, 0xac, 0xc2, 0xa3, 0xc0, 0x57, 0x4f, 0x92, 0x2b, 0xbc, 0x21, 0x04, - 0x1a, 0x0a, 0x8f, 0x69, 0x33, 0x48, 0xa6, 0xf0, 0x77, 0xa0, 0x12, 0x1f, 0x93, 0xba, 0x5d, 0x17, - 0xc5, 0xb7, 0x53, 0xd5, 0xa2, 0x86, 0xd7, 0x92, 0x86, 0xd7, 0x9a, 0xd8, 0x6b, 0x1d, 0x07, 0xbe, - 0x7a, 0x3f, 0x43, 0x0d, 0x8b, 0x81, 0xc6, 0x61, 0x64, 0x7e, 0x1f, 0x5a, 0x4b, 0xad, 0xb3, 0x77, - 0xcb, 0xd6, 0x99, 0x81, 0x5a, 0xe6, 0x9c, 0x71, 0x5f, 0x50, 0x69, 0xbf, 0x5e, 0x5c, 0xa3, 0x91, - 0xf8, 0x1b, 0xc9, 0xcd, 0x03, 0x8d, 0x2a, 0xbf, 0x1e, 0x87, 0x51, 0xf1, 0x05, 0xa8, 0x4c, 0x1c, - 0x42, 0x06, 0x9d, 0x21, 0xb2, 0xad, 0xa1, 0x2b, 0x1d, 0xb0, 0x73, 0xc8, 0x5c, 0xb9, 0x48, 0xe5, - 0xb3, 0x86, 0xf6, 0x35, 0x43, 0xb4, 0x3e, 0x0c, 0x77, 0x3f, 0xe7, 0x88, 0x8f, 0x86, 0xc6, 0x21, - 0x33, 0x23, 0xa4, 0xf8, 0x0c, 0x80, 0xc8, 0x6b, 0x63, 0xdb, 0x95, 0x4a, 0x75, 0xe1, 0xa4, 0xd2, - 0xaa, 0x05, 0xbe, 0x7a, 0x8f, 0x8f, 0x0c, 0x7d, 0xd0, 0x28, 0x33, 0x83, 0x8d, 0x81, 0xb3, 0x64, - 0x47, 0x51, 0x65, 0xa9, 0xcc, 0xe2, 0x8e, 0x17, 0x2b, 0x46, 0xde, 0xa4, 0x62, 0x9b, 0x59, 0x62, - 0x1b, 0xdc, 0x89, 0xbd, 0xa1, 0x22, 0x30, 0x9d, 0x52, 0x09, 0xb0, 0x70, 0x39, 0xf0, 0xd5, 0xa3, - 0x4c, 0x78, 0x02, 0x80, 0xc6, 0xfb, 0x51, 0x86, 0x64, 0x41, 0x1c, 0x80, 0xbb, 0xa9, 0x37, 0xa1, - 0xe5, 0xf0, 0x46, 0x5a, 0xd4, 0x98, 0x96, 0xe3, 0x74, 0xee, 0x64, 0x32, 0x40, 0xe3, 0x4e, 0xba, - 0x14, 0xd3, 0x33, 0x97, 0x7c, 0x65, 0x85, 0xe4, 0x15, 0xf0, 0x20, 0x4f, 0xd0, 0xa9, 0xe2, 0xff, - 0xde, 0xcb, 0x51, 0x7c, 0xd3, 0x1c, 0x2d, 0xcf, 0x45, 0x61, 0xa3, 0xb9, 0x68, 0x02, 0x39, 0x2b, - 0xba, 0x9c, 0x11, 0xf0, 0x49, 0xe0, 0xab, 0x0f, 0xf3, 0x04, 0x9a, 0x4d, 0x2c, 0x65, 0x94, 0xc9, - 0x17, 0xe1, 0x86, 0x65, 0x71, 0xc3, 0x61, 0xb9, 0x7d, 0x39, 0x2f, 0xca, 0x60, 0x6f, 0x8b, 0x32, - 0x68, 0x80, 0xa8, 0xbb, 0x3b, 0xae, 0xe3, 0x49, 0xfb, 0xac, 0x1d, 0xb9, 0xf1, 0x9b, 0xba, 0xa0, - 0x51, 0x62, 0xff, 0xe1, 0xc4, 0x5e, 0xd4, 0xc0, 0xc1, 0xed, 0x34, 0x50, 0xda, 0x8a, 0x06, 0xca, - 0xef, 0x54, 0x03, 0x60, 0x03, 0x0d, 0x34, 0xcd, 0x51, 0xaa, 0x81, 0x5f, 0x77, 0x80, 0xb4, 0x04, - 0x68, 0x13, 0x3c, 0xb0, 0x9d, 0xf1, 0x6d, 0x75, 0x90, 0xde, 0x5c, 0xd7, 0x1c, 0xb1, 0xb6, 0xcf, - 0xb9, 0xb9, 0xae, 0x39, 0x4a, 0x6e, 0x2e, 0x54, 0xde, 0x62, 0x23, 0x15, 0xb7, 0xd8, 0x48, 0x73, - 0xb2, 0x76, 0x57, 0x90, 0x05, 0x41, 0x7d, 0x15, 0x17, 0x09, 0x61, 0x4f, 0xfe, 0x2d, 0x82, 0xe2, - 0x73, 0x6a, 0x89, 0x3f, 0x01, 0x31, 0xe7, 0x11, 0x76, 0xba, 0x4a, 0x84, 0xb9, 0x6f, 0x0f, 0xf9, - 0xb3, 0x8d, 0xe0, 0xc9, 0x1e, 0xc4, 0x97, 0xe0, 0xde, 0xf2, 0x33, 0xe5, 0xd1, 0xda, 0xb9, 0x2e, - 0x1c, 0x4f, 0x7e, 0xb6, 0x09, 0x7a, 0x75, 0xe1, 0xf0, 0xce, 0xd6, 0x2f, 0xdc, 0x34, 0x47, 0x1b, - 0x14, 0xe6, 0xda, 0x54, 0xfc, 0x59, 0x00, 0xb5, 0xfc, 0x1e, 0x7d, 0xbc, 0x76, 0xbe, 0x38, 0x42, - 0xfe, 0x7c, 0xd3, 0x88, 0x64, 0x17, 0xad, 0x1f, 0xde, 0x5c, 0x29, 0xc2, 0xdb, 0x2b, 0x45, 0xf8, - 0xeb, 0x4a, 0x11, 0x7e, 0xbb, 0x56, 0x0a, 0x6f, 0xaf, 0x95, 0xc2, 0x9f, 0xd7, 0x4a, 0xe1, 0xc5, - 0x97, 0x96, 0xed, 0x0e, 0xa7, 0x3d, 0xcd, 0x24, 0x63, 0xdd, 0x24, 0x74, 0x4c, 0x68, 0xfc, 0x39, - 0xa5, 0xfd, 0x91, 0xfe, 0x4a, 0x4f, 0x9f, 0xf7, 0x8f, 0x9f, 0x9e, 0x72, 0x2f, 0x7c, 0xd7, 0x9b, - 0x20, 0xda, 0xdb, 0x67, 0x13, 0xf7, 0xe9, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x86, 0xcf, 0x23, - 0x2c, 0x90, 0x0c, 0x00, 0x00, + // 880 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x73, 0xda, 0x58, + 0x10, 0x46, 0x06, 0x63, 0x78, 0x70, 0x67, 0x5b, 0x07, 0x58, 0xa7, 0xb3, 0x11, 0xd6, 0xdc, 0xcd, + 0xb9, 0x38, 0x4b, 0xc6, 0xf6, 0xcd, 0xdc, 0xf9, 0xe6, 0x0a, 0xa0, 0x39, 0x17, 0xbe, 0x64, 0x14, + 0x27, 0x99, 0x71, 0xc3, 0x80, 0x10, 0xb2, 0x06, 0xa3, 0xc7, 0xe8, 0x09, 0x62, 0xa5, 0x4d, 0x93, + 0x49, 0x95, 0x9f, 0xe0, 0x9f, 0xe3, 0xd2, 0x65, 0xd2, 0x68, 0x12, 0xbb, 0x49, 0xad, 0x26, 0x93, + 0x2e, 0xa3, 0xf7, 0x24, 0x21, 0x40, 0x8c, 0x21, 0x38, 0x15, 0x5a, 0xed, 0xf7, 0xed, 0xae, 0x76, + 0xf7, 0x7b, 0x3c, 0xc0, 0x69, 0x4d, 0x59, 0x94, 0xa1, 0xa1, 0x88, 0x32, 0xd4, 0x75, 0x45, 0x36, + 0x35, 0xa8, 0x8b, 0x83, 0xb2, 0x68, 0x5e, 0x0a, 0x3d, 0x03, 0x9a, 0x90, 0x2e, 0x68, 0x4d, 0x59, + 0x70, 0x01, 0xc2, 0x10, 0x20, 0x0c, 0xca, 0x6c, 0x4e, 0x85, 0x2a, 0xc4, 0x10, 0xd1, 0x7d, 0x22, + 0x68, 0xf6, 0x67, 0x15, 0x42, 0xf5, 0x42, 0x11, 0xb1, 0xd5, 0xec, 0xb7, 0xc5, 0x86, 0x6e, 0x79, + 0xae, 0x50, 0xa6, 0x0b, 0x4d, 0xd1, 0x4d, 0x37, 0x0b, 0x79, 0xf2, 0x00, 0xbf, 0x4f, 0x29, 0x25, + 0x94, 0x17, 0x03, 0xf9, 0xcf, 0x14, 0xc8, 0x9f, 0x20, 0xb5, 0x16, 0xbc, 0x7f, 0xd4, 0x53, 0xf4, + 0x63, 0x5d, 0x33, 0xe9, 0x32, 0x48, 0x93, 0x90, 0x75, 0xad, 0xc5, 0x50, 0x25, 0x6a, 0x27, 0x5d, + 0xcd, 0x39, 0x36, 0xb7, 0x66, 0x35, 0xba, 0x17, 0x47, 0x7c, 0xe0, 0xe2, 0xa5, 0x14, 0x79, 0x3e, + 0x6e, 0xd1, 0xff, 0x83, 0xac, 0x0c, 0xfb, 0xba, 0xa9, 0x18, 0xbd, 0x86, 0x61, 0x5a, 0xcc, 0x52, + 0x89, 0xda, 0xc9, 0xec, 0xff, 0x2a, 0x44, 0x7f, 0xb6, 0x50, 0x0b, 0x61, 0xab, 0x89, 0x6b, 0x9b, + 0x8b, 0x49, 0x23, 0x7c, 0xfa, 0x6f, 0xb0, 0x32, 0x50, 0x0c, 0xa4, 0x41, 0x9d, 0x89, 0xe3, 0x50, + 0xdc, 0xb4, 0x50, 0xcf, 0x08, 0x4c, 0xf2, 0xf1, 0x74, 0x01, 0x24, 0x91, 0xa6, 0xea, 0x8a, 0xc1, + 0x24, 0xdc, 0xd2, 0x25, 0xcf, 0x3a, 0x4a, 0xbd, 0xbe, 0xe2, 0x62, 0x9f, 0xae, 0xb8, 0x18, 0xcf, + 0x81, 0xad, 0xc8, 0x0f, 0x97, 0x14, 0xd4, 0x83, 0x3a, 0x52, 0xf8, 0xf7, 0x49, 0x90, 0x9b, 0x40, + 0x9c, 0x1a, 0xd6, 0xb7, 0x74, 0xe6, 0x39, 0x28, 0xf4, 0x0c, 0x65, 0xa0, 0xc1, 0x3e, 0xaa, 0x0f, + 0x2b, 0x77, 0xf9, 0x4b, 0x98, 0xbf, 0xed, 0xd8, 0xdc, 0x16, 0xe1, 0x47, 0xe3, 0x78, 0x29, 0xe7, + 0x3b, 0x86, 0x05, 0x1d, 0xb7, 0xe8, 0xc7, 0x20, 0xeb, 0x25, 0x44, 0x66, 0xc3, 0x54, 0xbc, 0x3e, + 0xe5, 0x04, 0xb2, 0x3b, 0x82, 0xbf, 0x3b, 0x42, 0x45, 0xb7, 0xaa, 0x1b, 0x8e, 0xcd, 0xfd, 0x34, + 0x52, 0x24, 0xe6, 0xf0, 0x52, 0x86, 0x98, 0x4f, 0x5c, 0x6b, 0x62, 0x88, 0x89, 0x05, 0x87, 0x38, + 0x00, 0xf9, 0xb0, 0x5d, 0xf7, 0x26, 0x84, 0x98, 0xe5, 0x52, 0x7c, 0x86, 0x91, 0x56, 0x4b, 0x8e, + 0xcd, 0x6d, 0x7a, 0x55, 0x47, 0xc5, 0xe1, 0xa5, 0x5c, 0xf8, 0xbd, 0x47, 0x43, 0xf4, 0x19, 0xc8, + 0xf6, 0x0c, 0x08, 0xdb, 0xf5, 0x73, 0x45, 0x53, 0xcf, 0x4d, 0x26, 0x89, 0xbf, 0x83, 0x0d, 0xa5, + 0x23, 0x82, 0x19, 0x94, 0x85, 0xff, 0x30, 0xa2, 0xfa, 0x8b, 0x5b, 0xfd, 0xb0, 0x47, 0x61, 0x36, + 0x2f, 0x65, 0xb0, 0x49, 0x90, 0xf4, 0x21, 0x00, 0xc4, 0xab, 0xe9, 0x9a, 0xc9, 0xac, 0x94, 0xa8, + 0x9d, 0x6c, 0x35, 0xef, 0xd8, 0xdc, 0x7a, 0x98, 0xe9, 0xfa, 0x78, 0x29, 0x8d, 0x0d, 0xac, 0xa8, + 0x23, 0xbf, 0x22, 0x92, 0x99, 0x49, 0x61, 0xde, 0xc6, 0x78, 0x46, 0xe2, 0xf5, 0x33, 0xd6, 0xb0, + 0x45, 0xd7, 0xc0, 0xaa, 0xe7, 0x75, 0x77, 0x53, 0x47, 0x7d, 0xc4, 0xa4, 0x31, 0x9d, 0x75, 0x6c, + 0xae, 0x30, 0x42, 0xf7, 0x01, 0xbc, 0xf4, 0x23, 0x89, 0xe0, 0xbf, 0xa0, 0xdb, 0x60, 0x2d, 0xf0, + 0xfa, 0x6d, 0x01, 0xf7, 0xb6, 0x85, 0xf3, 0xda, 0xb2, 0xe1, 0x0f, 0x61, 0x34, 0x02, 0x2f, 0xad, + 0x06, 0xaf, 0xbc, 0xf6, 0x0c, 0xc5, 0x97, 0x99, 0x22, 0xbe, 0x22, 0xd8, 0x8c, 0x92, 0x56, 0xa0, + 0xbd, 0x8f, 0xcb, 0x11, 0xda, 0xab, 0xc8, 0x1d, 0xfa, 0x5f, 0xf0, 0xc3, 0xa8, 0x7e, 0x88, 0xfe, + 0x18, 0xc7, 0xe6, 0x72, 0x41, 0x7d, 0x61, 0xd9, 0x64, 0xe5, 0xb0, 0x5c, 0x64, 0xc0, 0x8e, 0x2c, + 0x51, 0x94, 0x16, 0x7f, 0x73, 0x6c, 0x6e, 0x3b, 0x62, 0xe1, 0xc6, 0x02, 0x33, 0x61, 0xe7, 0x88, + 0x26, 0x17, 0x38, 0xb6, 0xc6, 0xe5, 0x9c, 0x58, 0x58, 0xce, 0xe3, 0x32, 0x58, 0x7e, 0x40, 0x19, + 0x94, 0x01, 0xd9, 0xee, 0xba, 0x69, 0x58, 0x58, 0x5f, 0xd9, 0xf0, 0x41, 0x18, 0xb8, 0x78, 0x29, + 0x85, 0x9f, 0xdd, 0xb3, 0x73, 0x5c, 0x03, 0x2b, 0x8b, 0x69, 0x20, 0xf5, 0x20, 0x1a, 0x48, 0x7f, + 0x57, 0x0d, 0x80, 0x39, 0x34, 0x50, 0x91, 0x3b, 0x81, 0x06, 0xde, 0x2c, 0x01, 0x66, 0x02, 0x50, + 0x83, 0x7a, 0x5b, 0x33, 0xba, 0x8b, 0xea, 0x20, 0x98, 0x5c, 0x43, 0xee, 0xe0, 0xb5, 0x8f, 0x98, + 0x5c, 0x43, 0xee, 0xf8, 0x93, 0x73, 0x95, 0x37, 0xbe, 0x48, 0xf1, 0x07, 0x5c, 0xa4, 0xfb, 0xff, + 0xad, 0x79, 0x50, 0x9a, 0xd6, 0x0b, 0xbf, 0x61, 0xfb, 0x5f, 0xe2, 0x20, 0x7e, 0x82, 0x54, 0xfa, + 0x25, 0xa0, 0x23, 0xee, 0x33, 0xbb, 0xd3, 0x44, 0x18, 0x79, 0x0b, 0x60, 0xff, 0x9c, 0x0b, 0xee, + 0xd7, 0x40, 0xbf, 0x00, 0xeb, 0x93, 0x17, 0x86, 0x3f, 0x66, 0x8e, 0x75, 0x6a, 0x58, 0xec, 0xe1, + 0x3c, 0xe8, 0xe9, 0x89, 0xdd, 0x99, 0xcd, 0x9e, 0xb8, 0x22, 0x77, 0xe6, 0x48, 0x1c, 0x5a, 0x53, + 0xfa, 0x15, 0x05, 0xf2, 0xd1, 0x3b, 0xba, 0x37, 0x73, 0x3c, 0x8f, 0xc1, 0xfe, 0x35, 0x2f, 0xc3, + 0xaf, 0xa2, 0xfa, 0xf4, 0xfa, 0xb6, 0x48, 0xdd, 0xdc, 0x16, 0xa9, 0x0f, 0xb7, 0x45, 0xea, 0xed, + 0x5d, 0x31, 0x76, 0x73, 0x57, 0x8c, 0xbd, 0xbb, 0x2b, 0xc6, 0xce, 0xfe, 0x51, 0x35, 0xf3, 0xbc, + 0xdf, 0x14, 0x64, 0xd8, 0x15, 0x65, 0x88, 0xba, 0x10, 0x79, 0x3f, 0xbb, 0xa8, 0xd5, 0x11, 0x2f, + 0xc5, 0xe0, 0xa6, 0xbc, 0x77, 0xb0, 0x1b, 0xba, 0x2c, 0x9b, 0x56, 0x4f, 0x41, 0xcd, 0x24, 0x3e, + 0x71, 0x0f, 0xbe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x4a, 0xeb, 0x3e, 0xdb, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -666,7 +663,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } if m.Version != nil { { @@ -678,7 +675,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) @@ -689,14 +686,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x12 - } + dAtA[i] = 0x12 if len(m.ClientId) > 0 { i -= len(m.ClientId) copy(dAtA[i:], m.ClientId) @@ -755,7 +745,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x5a } { size, err := m.ConsensusHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -766,27 +756,27 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x52 if len(m.ProofConsensus) > 0 { i -= len(m.ProofConsensus) copy(dAtA[i:], m.ProofConsensus) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofConsensus))) i-- - dAtA[i] = 0x52 + dAtA[i] = 0x4a } if len(m.ProofClient) > 0 { i -= len(m.ProofClient) copy(dAtA[i:], m.ProofClient) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClient))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0x42 } if len(m.ProofInit) > 0 { i -= len(m.ProofInit) copy(dAtA[i:], m.ProofInit) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -797,7 +787,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 if len(m.CounterpartyVersions) > 0 { for iNdEx := len(m.CounterpartyVersions) - 1; iNdEx >= 0; iNdEx-- { { @@ -809,7 +799,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } } { @@ -821,7 +811,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 if m.ClientState != nil { { size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) @@ -832,19 +822,12 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - } - if len(m.CounterpartyChosenConnectionId) > 0 { - i -= len(m.CounterpartyChosenConnectionId) - copy(dAtA[i:], m.CounterpartyChosenConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenConnectionId))) - i-- dAtA[i] = 0x1a } - if len(m.DesiredConnectionId) > 0 { - i -= len(m.DesiredConnectionId) - copy(dAtA[i:], m.DesiredConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredConnectionId))) + if len(m.PreviousConnectionId) > 0 { + i -= len(m.PreviousConnectionId) + copy(dAtA[i:], m.PreviousConnectionId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousConnectionId))) i-- dAtA[i] = 0x12 } @@ -1111,10 +1094,6 @@ func (m *MsgConnectionOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Counterparty.Size() n += 1 + l + sovTx(uint64(l)) if m.Version != nil { @@ -1147,11 +1126,7 @@ func (m *MsgConnectionOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenConnectionId) + l = len(m.PreviousConnectionId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1353,38 +1328,6 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1417,7 +1360,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } @@ -1453,7 +1396,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -1625,7 +1568,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredConnectionId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousConnectionId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1653,41 +1596,9 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredConnectionId = string(dAtA[iNdEx:postIndex]) + m.PreviousConnectionId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenConnectionId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CounterpartyChosenConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) } @@ -1723,7 +1634,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1756,7 +1667,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersions", wireType) } @@ -1790,7 +1701,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -1823,7 +1734,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -1857,7 +1768,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 9: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofClient", wireType) } @@ -1891,7 +1802,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofClient = []byte{} } iNdEx = postIndex - case 10: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofConsensus", wireType) } @@ -1925,7 +1836,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofConsensus = []byte{} } iNdEx = postIndex - case 11: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsensusHeight", wireType) } @@ -1958,7 +1869,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/04-channel/client/cli/tx.go b/x/ibc/core/04-channel/client/cli/tx.go index f4f4176383..d3150f2c91 100644 --- a/x/ibc/core/04-channel/client/cli/tx.go +++ b/x/ibc/core/04-channel/client/cli/tx.go @@ -24,9 +24,9 @@ const ( // NewChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction func NewChannelOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops]", + Use: "open-init [port-id] [counterparty-port-id] [connection-hops]", Short: "Creates and sends a ChannelOpenInit message", - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -35,16 +35,14 @@ func NewChannelOpenInitCmd() *cobra.Command { } portID := args[0] - channelID := args[1] - counterpartyPortID := args[2] - counterpartyChannelID := args[3] - hops := strings.Split(args[4], "/") + counterpartyPortID := args[1] + hops := strings.Split(args[2], "/") order := channelOrder(cmd.Flags()) version, _ := cmd.Flags().GetString(FlagIBCVersion) msg := types.NewMsgChannelOpenInit( - portID, channelID, version, order, hops, - counterpartyPortID, counterpartyChannelID, clientCtx.GetFromAddress(), + portID, version, order, hops, + counterpartyPortID, clientCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -64,9 +62,9 @@ func NewChannelOpenInitCmd() *cobra.Command { // NewChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction func NewChannelOpenTryCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-try [port-id] [channel-id] [proved-channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelOpenTry message", - Args: cobra.ExactArgs(8), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -76,27 +74,26 @@ func NewChannelOpenTryCmd() *cobra.Command { portID := args[0] channelID := args[1] - provedChannelID := args[2] - counterpartyPortID := args[3] - counterpartyChannelID := args[4] - hops := strings.Split(args[5], "/") + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") order := channelOrder(cmd.Flags()) // TODO: Differentiate between channel and counterparty versions. version, _ := cmd.Flags().GetString(FlagIBCVersion) - proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[6]) + proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[5]) if err != nil { return err } - proofHeight, err := clienttypes.ParseHeight(args[7]) + proofHeight, err := clienttypes.ParseHeight(args[6]) if err != nil { return err } msg := types.NewMsgChannelOpenTry( - portID, channelID, provedChannelID, version, order, hops, + portID, channelID, version, order, hops, counterpartyPortID, counterpartyChannelID, version, proofInit, proofHeight, clientCtx.GetFromAddress(), ) diff --git a/x/ibc/core/04-channel/genesis.go b/x/ibc/core/04-channel/genesis.go index bd557bc5bf..07fad47d77 100644 --- a/x/ibc/core/04-channel/genesis.go +++ b/x/ibc/core/04-channel/genesis.go @@ -31,6 +31,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, as := range gs.AckSequences { k.SetNextSequenceAck(ctx, as.PortId, as.ChannelId, as.Sequence) } + k.SetNextChannelSequence(ctx, gs.NextChannelSequence) } // ExportGenesis returns the ibc channel submodule's exported genesis. diff --git a/x/ibc/core/04-channel/handler.go b/x/ibc/core/04-channel/handler.go index 2bf542cfdf..375c35263e 100644 --- a/x/ibc/core/04-channel/handler.go +++ b/x/ibc/core/04-channel/handler.go @@ -9,20 +9,20 @@ import ( ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenInit( - ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenInit( + ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open init failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenInit, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -35,23 +35,23 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabil return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, msg.CounterpartyChosenChannelId, +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.PreviousChannelId, portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open try failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenTry, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.DesiredChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -64,7 +64,7 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabili return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck diff --git a/x/ibc/core/04-channel/keeper/handshake.go b/x/ibc/core/04-channel/keeper/handshake.go index 75b0c1bd3d..2286deafec 100644 --- a/x/ibc/core/04-channel/keeper/handshake.go +++ b/x/ibc/core/04-channel/keeper/handshake.go @@ -34,30 +34,25 @@ func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, b } // ChanOpenInit is called by a module to initiate a channel opening handshake with -// a module on another chain. +// a module on another chain. The counterparty channel identifier is validated to be +// empty in msg validation. func (k Keeper) ChanOpenInit( ctx sdk.Context, order types.Order, connectionHops []string, - portID, - channelID string, + portID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version string, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - _, found := k.GetChannel(ctx, portID, channelID) - if found { - return nil, sdkerrors.Wrapf(types.ErrChannelExists, "port ID (%s) channel ID (%s)", portID, channelID) - } - +) (string, *capabilitytypes.Capability, error) { + // connection hop length checked on msg.ValidateBasic() connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -65,7 +60,7 @@ func (k Keeper) ChanOpenInit( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), @@ -73,15 +68,16 @@ func (k Keeper) ChanOpenInit( } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } + channelID := k.GenerateChannelIdentifier(ctx) channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) capKey, err := k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } k.SetNextSequenceSend(ctx, portID, channelID, 1) @@ -94,7 +90,7 @@ func (k Keeper) ChanOpenInit( telemetry.IncrCounter(1, "ibc", "channel", "open-init") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -104,44 +100,65 @@ func (k Keeper) ChanOpenTry( order types.Order, connectionHops []string, portID, - desiredChannelID, - counterpartyChosenChannelID string, + previousChannelID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version, counterpartyVersion string, proofInit []byte, proofHeight exported.Height, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - previousChannel, found := k.GetChannel(ctx, portID, desiredChannelID) - if found && !(previousChannel.State == types.INIT && - previousChannel.Ordering == order && - previousChannel.Counterparty.PortId == counterparty.PortId && - previousChannel.Counterparty.ChannelId == counterparty.ChannelId && - previousChannel.ConnectionHops[0] == connectionHops[0] && - previousChannel.Version == version) { - return nil, sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") +) (string, *capabilitytypes.Capability, error) { + var ( + previousChannel types.Channel + previousChannelFound bool + ) + + channelID := previousChannelID + + // empty channel identifier indicates continuing a previous channel handshake + if previousChannelID != "" { + // channel identifier and connection hop length checked on msg.ValidateBasic() + // ensure that the previous channel exists + previousChannel, previousChannelFound = k.GetChannel(ctx, portID, previousChannelID) + if !previousChannelFound { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannel, "previous channel does not exist for supplied previous channelID %s", previousChannelID) + } + // previous channel must use the same fields + if !(previousChannel.Ordering == order && + previousChannel.Counterparty.PortId == counterparty.PortId && + previousChannel.Counterparty.ChannelId == "" && + previousChannel.ConnectionHops[0] == connectionHops[0] && + previousChannel.Version == version) { + return "", nil, sdkerrors.Wrap(types.ErrInvalidChannel, "channel fields mismatch previous channel fields") + } + + if previousChannel.State != types.INIT { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannelState, "previous channel state is in %s, expected INIT", previousChannel.State) + } + + } else { + // generate a new channel + channelID = k.GenerateChannelIdentifier(ctx) } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -149,23 +166,13 @@ func (k Keeper) ChanOpenTry( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), ) } - // If the channel id chosen for this channel end by the counterparty is empty then - // flexible channel identifier selection is allowed by using the desired channel id. - // Otherwise the desiredChannelID must match the counterpartyChosenChannelID. - if counterpartyChosenChannelID != "" && counterpartyChosenChannelID != desiredChannelID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty chosen channel ID (%s) must be empty or equal to the desired channel ID (%s)", counterpartyChosenChannelID, desiredChannelID, - ) - } - // NOTE: this step has been switched with the one below to reverse the connection // hops channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) @@ -178,7 +185,7 @@ func (k Keeper) ChanOpenTry( // expectedCounterpaty is the counterparty of the counterparty's channel end // (i.e self) - expectedCounterparty := types.NewCounterparty(portID, counterpartyChosenChannelID) + expectedCounterparty := types.NewCounterparty(portID, "") expectedChannel := types.NewChannel( types.INIT, channel.Ordering, expectedCounterparty, counterpartyHops, counterpartyVersion, @@ -188,7 +195,7 @@ func (k Keeper) ChanOpenTry( ctx, connectionEnd, proofHeight, proofInit, counterparty.PortId, counterparty.ChannelId, expectedChannel, ); err != nil { - return nil, err + return "", nil, err } var ( @@ -196,36 +203,34 @@ func (k Keeper) ChanOpenTry( err error ) - // Only create a capability and set the sequences if the previous channel does not exist - _, found = k.GetChannel(ctx, portID, desiredChannelID) - if !found { - capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + if !previousChannelFound { + capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, desiredChannelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } - k.SetNextSequenceSend(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceRecv(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceAck(ctx, portID, desiredChannelID, 1) + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + k.SetNextSequenceAck(ctx, portID, channelID, 1) } else { // capability initialized in ChanOpenInit - capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if !found { - return nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, - "capability not found for existing channel, portID (%s) channelID (%s)", portID, desiredChannelID, + return "", nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, + "capability not found for existing channel, portID (%s) channelID (%s)", portID, channelID, ) } } - k.SetChannel(ctx, portID, desiredChannelID, channel) + k.SetChannel(ctx, portID, channelID, channel) - k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", desiredChannelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "channel", "open-try") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -256,16 +261,6 @@ func (k Keeper) ChanOpenAck( return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } - // If the previously set channel end allowed for the counterparty to select its own - // channel identifier then we use the counterpartyChannelID. Otherwise the - // counterpartyChannelID must match the previously set counterparty channel ID. - if channel.Counterparty.ChannelId != "" && counterpartyChannelID != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty channel identifier (%s) must be equal to stored channel ID for counterparty (%s)", counterpartyChannelID, channel.Counterparty.ChannelId, - ) - } - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) diff --git a/x/ibc/core/04-channel/keeper/handshake_test.go b/x/ibc/core/04-channel/keeper/handshake_test.go index 857bba57d4..7aae08130c 100644 --- a/x/ibc/core/04-channel/keeper/handshake_test.go +++ b/x/ibc/core/04-channel/keeper/handshake_test.go @@ -34,8 +34,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { {"success", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, {"channel already exists", func() { _, _, connA, connB, _, _ = suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) @@ -64,8 +64,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { connA.ID, conn, ) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -82,8 +82,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { ) // NOTE: Opening UNORDERED channels is still expected to pass but ORDERED channels should fail features = []string{"ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, } @@ -98,9 +98,9 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { counterparty := types.NewCounterparty(connB.FirstOrNextTestChannel(ibctesting.MockPort).PortID, connB.FirstOrNextTestChannel(ibctesting.MockPort).ID) channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) - cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( + channelID, cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( suite.chainA.GetContext(), order, []string{connA.ID}, - channelA.PortID, channelA.ID, portCap, counterparty, channelA.Version, + channelA.PortID, portCap, counterparty, channelA.Version, ) // check if order is supported by channel to determine expected behaviour @@ -116,6 +116,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { if tc.expPass && orderSupported { suite.Require().NoError(err) suite.Require().NotNil(cap) + suite.Require().Equal(types.FormatChannelIdentifier(0), channelID) chanCap, ok := suite.chainA.App.ScopedIBCKeeper.GetCapability( suite.chainA.GetContext(), @@ -125,6 +126,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") } else { suite.Require().Error(err) + suite.Require().Nil(cap) + suite.Require().Equal("", channelID) } } }) @@ -137,10 +140,11 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { // ChanOpenTry can succeed. func (suite *KeeperTestSuite) TestChanOpenTry() { var ( - connA *ibctesting.TestConnection - connB *ibctesting.TestConnection - portCap *capabilitytypes.Capability - heightDiff uint64 + connA *ibctesting.TestConnection + connB *ibctesting.TestConnection + previousChannelID string + portCap *capabilitytypes.Capability + heightDiff uint64 ) testCases := []testCase{ @@ -148,34 +152,16 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"success with crossing hello", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, true}, - {"success with empty counterparty chosen channel id", func() { - var clientA, clientB string - clientA, clientB, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) + _, channelB, err := suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) suite.Require().NoError(err) - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + previousChannelID = channelB.ID + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"previous channel with invalid state", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -206,28 +192,15 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) heightDiff = 3 // consensus state doesn't exist at this height }, false}, - {"counterparty chosen channel id does not match desired channel id", func() { - _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.Require().NoError(err) - - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "otherchannel" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, false}, {"channel verification failed", func() { // not creating a channel on chainA will result in an invalid proof of existence _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"port capability not found", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -249,8 +222,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainB.GetContext(), connB.ID, conn, ) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -266,8 +239,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainA.GetContext(), connA.ID, conn, ) - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, } @@ -276,25 +249,19 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset heightDiff = 0 // must be explicitly changed in malleate + previousChannelID = "" tc.malleate() channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) channelB := connB.FirstOrNextTestChannel(ibctesting.MockPort) counterparty := types.NewCounterparty(channelA.PortID, channelA.ID) - // get counterpartyChosenChannelID - var counterpartyChosenChannelID string - channel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - if found { - counterpartyChosenChannelID = channel.Counterparty.ChannelId - } - channelKey := host.ChannelKey(counterparty.PortId, counterparty.ChannelId) proof, proofHeight := suite.chainA.QueryProof(channelKey) - cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + channelID, cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainB.GetContext(), types.ORDERED, []string{connB.ID}, - channelB.PortID, channelB.ID, counterpartyChosenChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, + channelB.PortID, previousChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, proof, malleateHeight(proofHeight, heightDiff), ) @@ -304,7 +271,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { chanCap, ok := suite.chainB.App.ScopedIBCKeeper.GetCapability( suite.chainB.GetContext(), - host.ChannelCapabilityPath(channelB.PortID, channelB.ID), + host.ChannelCapabilityPath(channelB.PortID, channelID), ) suite.Require().True(ok, "could not retrieve channel capapbility after successful ChanOpenTry") suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") diff --git a/x/ibc/core/04-channel/keeper/keeper.go b/x/ibc/core/04-channel/keeper/keeper.go index 99aee2c6da..2390fb41cf 100644 --- a/x/ibc/core/04-channel/keeper/keeper.go +++ b/x/ibc/core/04-channel/keeper/keeper.go @@ -55,6 +55,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", host.ModuleName, types.SubModuleName)) } +// GenerateChannelIdentifier returns the next channel identifier. +func (k Keeper) GenerateChannelIdentifier(ctx sdk.Context) string { + nextChannelSeq := k.GetNextChannelSequence(ctx) + channelID := types.FormatChannelIdentifier(nextChannelSeq) + + nextChannelSeq++ + k.SetNextChannelSequence(ctx, nextChannelSeq) + return channelID +} + // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { store := ctx.KVStore(k.storeKey) @@ -75,6 +85,24 @@ func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel ty store.Set(host.ChannelKey(portID, channelID), bz) } +// GetNextChannelSequence gets the next channel sequence from the store. +func (k Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextChannelSequence)) + if bz == nil { + panic("next channel sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextChannelSequence sets the next channel sequence to the store. +func (k Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextChannelSequence), bz) +} + // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) diff --git a/x/ibc/core/04-channel/keeper/keeper_test.go b/x/ibc/core/04-channel/keeper/keeper_test.go index d1ea3de5da..fa24a66b9c 100644 --- a/x/ibc/core/04-channel/keeper/keeper_test.go +++ b/x/ibc/core/04-channel/keeper/keeper_test.go @@ -42,8 +42,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { // create client and connections on both chains _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - // check for channel to be created on chainB - channelA := connA.NextTestChannel(ibctesting.MockPort) + // check for channel to be created on chainA + channelA := suite.chainA.NextTestChannel(connA, ibctesting.MockPort) _, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) suite.False(found) @@ -52,7 +52,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.NoError(err) storedChannel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - expectedCounterparty := types.NewCounterparty(channelB.PortID, channelB.ID) + // counterparty channel id is empty after open init + expectedCounterparty := types.NewCounterparty(channelB.PortID, "") suite.True(found) suite.Equal(types.INIT, storedChannel.State) @@ -83,9 +84,10 @@ func (suite KeeperTestSuite) TestGetAllChannels() { testchannel2, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA1, connB1, ibctesting.MockPort, ibctesting.MockPort, types.UNORDERED) suite.Require().NoError(err) + // counterparty channel id is empty after open init counterparty2 := types.Counterparty{ PortId: connB1.Channels[0].PortID, - ChannelId: connB1.Channels[0].ID, + ChannelId: "", } channel0 := types.NewChannel( diff --git a/x/ibc/core/04-channel/keeper/packet_test.go b/x/ibc/core/04-channel/keeper/packet_test.go index f53ed79475..62c8336212 100644 --- a/x/ibc/core/04-channel/keeper/packet_test.go +++ b/x/ibc/core/04-channel/keeper/packet_test.go @@ -148,8 +148,8 @@ func (suite *KeeperTestSuite) TestSendPacket() { }, false}, {"next sequence send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -298,8 +298,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainB.GetContext(), @@ -322,8 +322,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { }, false}, {"next receive sequence is not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually creating channel prevents next recv sequence from being set suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -570,8 +570,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), @@ -599,8 +599,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { }, false}, {"next ack sequence not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence acknowledgement from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( diff --git a/x/ibc/core/04-channel/types/genesis.go b/x/ibc/core/04-channel/types/genesis.go index 51de681271..28ab32f21a 100644 --- a/x/ibc/core/04-channel/types/genesis.go +++ b/x/ibc/core/04-channel/types/genesis.go @@ -44,28 +44,30 @@ func (ps PacketSequence) Validate() error { // NewGenesisState creates a GenesisState instance. func NewGenesisState( channels []IdentifiedChannel, acks, receipts, commitments []PacketState, - sendSeqs, recvSeqs, ackSeqs []PacketSequence, + sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, ) GenesisState { return GenesisState{ - Channels: channels, - Acknowledgements: acks, - Commitments: commitments, - SendSequences: sendSeqs, - RecvSequences: recvSeqs, - AckSequences: ackSeqs, + Channels: channels, + Acknowledgements: acks, + Commitments: commitments, + SendSequences: sendSeqs, + RecvSequences: recvSeqs, + AckSequences: ackSeqs, + NextChannelSequence: nextChannelSequence, } } // DefaultGenesisState returns the ibc channel submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Channels: []IdentifiedChannel{}, - Acknowledgements: []PacketState{}, - Receipts: []PacketState{}, - Commitments: []PacketState{}, - SendSequences: []PacketSequence{}, - RecvSequences: []PacketSequence{}, - AckSequences: []PacketSequence{}, + Channels: []IdentifiedChannel{}, + Acknowledgements: []PacketState{}, + Receipts: []PacketState{}, + Commitments: []PacketState{}, + SendSequences: []PacketSequence{}, + RecvSequences: []PacketSequence{}, + AckSequences: []PacketSequence{}, + NextChannelSequence: 0, } } diff --git a/x/ibc/core/04-channel/types/genesis.pb.go b/x/ibc/core/04-channel/types/genesis.pb.go index ca26a9bb5d..51ff4e5077 100644 --- a/x/ibc/core/04-channel/types/genesis.pb.go +++ b/x/ibc/core/04-channel/types/genesis.pb.go @@ -32,6 +32,8 @@ type GenesisState struct { SendSequences []PacketSequence `protobuf:"bytes,5,rep,name=send_sequences,json=sendSequences,proto3" json:"send_sequences" yaml:"send_sequences"` RecvSequences []PacketSequence `protobuf:"bytes,6,rep,name=recv_sequences,json=recvSequences,proto3" json:"recv_sequences" yaml:"recv_sequences"` AckSequences []PacketSequence `protobuf:"bytes,7,rep,name=ack_sequences,json=ackSequences,proto3" json:"ack_sequences" yaml:"ack_sequences"` + // the sequence for the next generated channel identifier + NextChannelSequence uint64 `protobuf:"varint,8,opt,name=next_channel_sequence,json=nextChannelSequence,proto3" json:"next_channel_sequence,omitempty" yaml:"next_channel_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -116,6 +118,13 @@ func (m *GenesisState) GetAckSequences() []PacketSequence { return nil } +func (m *GenesisState) GetNextChannelSequence() uint64 { + if m != nil { + return m.NextChannelSequence + } + return 0 +} + // PacketSequence defines the genesis type necessary to retrieve and store // next send and receive sequences. type PacketSequence struct { @@ -186,37 +195,39 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/genesis.proto", fileDescriptor_cb06ec201f452595) } var fileDescriptor_cb06ec201f452595 = []byte{ - // 471 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0xe3, 0x26, 0x4d, 0xd3, 0x6b, 0x13, 0xd1, 0xa3, 0x95, 0x4c, 0x04, 0x76, 0x30, 0x12, - 0x8a, 0x84, 0x6a, 0x53, 0xe8, 0x80, 0x18, 0xcd, 0x00, 0xd9, 0xd0, 0xb1, 0x21, 0xa1, 0xca, 0x39, - 0xbf, 0xba, 0x27, 0xc7, 0xbe, 0xe0, 0xbb, 0x06, 0xfa, 0x21, 0x10, 0x7c, 0xac, 0x8e, 0x1d, 0x99, - 0x2c, 0x94, 0x7c, 0x83, 0x8c, 0x4c, 0xc8, 0xe7, 0x8b, 0x9b, 0xa8, 0x11, 0x22, 0x4c, 0xf6, 0xbd, - 0xf7, 0x7f, 0xbf, 0xdf, 0x5b, 0x1e, 0x7a, 0xcc, 0x86, 0xd4, 0xa3, 0x3c, 0x03, 0x8f, 0x5e, 0x04, - 0x69, 0x0a, 0x23, 0x6f, 0x72, 0xe2, 0x45, 0x90, 0x82, 0x60, 0xc2, 0x1d, 0x67, 0x5c, 0x72, 0x7c, - 0x9f, 0x0d, 0xa9, 0x5b, 0x44, 0x5c, 0x1d, 0x71, 0x27, 0x27, 0xdd, 0xc3, 0x88, 0x47, 0x5c, 0xf5, - 0xbd, 0xe2, 0xaf, 0x8c, 0x76, 0xd7, 0xd2, 0x16, 0x53, 0x2a, 0xe2, 0x7c, 0xdb, 0x46, 0xfb, 0x6f, - 0x4b, 0xfe, 0x07, 0x19, 0x48, 0xc0, 0x9f, 0x50, 0x4b, 0x27, 0x84, 0x69, 0xf4, 0xea, 0xfd, 0xbd, - 0x17, 0x4f, 0xdd, 0x35, 0x46, 0x77, 0x10, 0x42, 0x2a, 0xd9, 0x39, 0x83, 0xf0, 0x4d, 0x59, 0xf4, - 0x1f, 0x5c, 0xe7, 0x76, 0xed, 0x77, 0x6e, 0x1f, 0xdc, 0x69, 0x91, 0x0a, 0x89, 0x09, 0xba, 0x17, - 0xd0, 0x38, 0xe5, 0x5f, 0x46, 0x10, 0x46, 0x90, 0x40, 0x2a, 0x85, 0xb9, 0xa5, 0x34, 0xbd, 0xb5, - 0x9a, 0xf7, 0x01, 0x8d, 0x41, 0xaa, 0xd5, 0xfc, 0x46, 0x21, 0x20, 0x77, 0xe6, 0xf1, 0x3b, 0xb4, - 0x47, 0x79, 0x92, 0x30, 0x59, 0xe2, 0xea, 0x1b, 0xe1, 0x96, 0x47, 0xb1, 0x8f, 0x5a, 0x19, 0x50, - 0x60, 0x63, 0x29, 0xcc, 0xc6, 0x46, 0x98, 0x6a, 0x0e, 0x33, 0xd4, 0x11, 0x90, 0x86, 0x67, 0x02, - 0x3e, 0x5f, 0x42, 0x4a, 0x41, 0x98, 0xdb, 0x8a, 0xf4, 0xe4, 0x6f, 0x24, 0x9d, 0xf5, 0x1f, 0x15, - 0xb0, 0x79, 0x6e, 0x1f, 0x5d, 0x05, 0xc9, 0xe8, 0xb5, 0xb3, 0x0a, 0x72, 0x48, 0xbb, 0x28, 0x2c, - 0xc2, 0x4a, 0x95, 0x01, 0x9d, 0x2c, 0xa9, 0x9a, 0xff, 0xad, 0x5a, 0x05, 0x39, 0xa4, 0x5d, 0x14, - 0x6e, 0x55, 0xe7, 0xa8, 0x1d, 0xd0, 0x78, 0xc9, 0xb4, 0xf3, 0xef, 0xa6, 0x87, 0xda, 0x74, 0x58, - 0x9a, 0x56, 0x38, 0x0e, 0xd9, 0x0f, 0x68, 0x5c, 0x79, 0x9c, 0xef, 0x06, 0xea, 0xac, 0x8e, 0xe3, - 0x67, 0x68, 0x67, 0xcc, 0x33, 0x79, 0xc6, 0x42, 0xd3, 0xe8, 0x19, 0xfd, 0x5d, 0x1f, 0xcf, 0x73, - 0xbb, 0x53, 0xb2, 0x74, 0xc3, 0x21, 0xcd, 0xe2, 0x6f, 0x10, 0xe2, 0x53, 0x84, 0xf4, 0x22, 0x45, - 0x7e, 0x4b, 0xe5, 0x8f, 0xe6, 0xb9, 0x7d, 0x50, 0xe6, 0x6f, 0x7b, 0x0e, 0xd9, 0xd5, 0x8f, 0x41, - 0x88, 0xbb, 0xa8, 0xb5, 0xd8, 0xc8, 0xac, 0xf7, 0x8c, 0x7e, 0x83, 0x54, 0x6f, 0x9f, 0x5c, 0x4f, - 0x2d, 0xe3, 0x66, 0x6a, 0x19, 0xbf, 0xa6, 0x96, 0xf1, 0x63, 0x66, 0xd5, 0x6e, 0x66, 0x56, 0xed, - 0xe7, 0xcc, 0xaa, 0x7d, 0x7c, 0x15, 0x31, 0x79, 0x71, 0x39, 0x74, 0x29, 0x4f, 0x3c, 0xca, 0x45, - 0xc2, 0x85, 0xfe, 0x1c, 0x8b, 0x30, 0xf6, 0xbe, 0x7a, 0xd5, 0xf5, 0x3d, 0x3f, 0x3d, 0x5e, 0x1c, - 0xa0, 0xbc, 0x1a, 0x83, 0x18, 0x36, 0xd5, 0xf1, 0xbd, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0x70, - 0xac, 0x09, 0x09, 0xef, 0x03, 0x00, 0x00, + // 501 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0x87, 0xe3, 0x26, 0x4d, 0xd3, 0x6d, 0x13, 0xd1, 0x6d, 0x23, 0x99, 0xa8, 0xd8, 0xc6, 0x48, + 0x28, 0x12, 0xaa, 0x4d, 0xa1, 0x07, 0xc4, 0xd1, 0x1c, 0x20, 0x37, 0xb4, 0x70, 0x42, 0x42, 0x91, + 0xb3, 0x9e, 0xba, 0x2b, 0xc7, 0xde, 0xe0, 0xdd, 0x86, 0xf6, 0x29, 0xe0, 0xb1, 0x7a, 0xec, 0x91, + 0x93, 0x85, 0x92, 0x37, 0xc8, 0x91, 0x13, 0xf2, 0xdf, 0x24, 0x6a, 0x84, 0x68, 0x4f, 0xde, 0x9d, + 0xf9, 0xcd, 0xf7, 0xcd, 0xc1, 0x8b, 0x9e, 0xb2, 0x11, 0xb5, 0x29, 0x8f, 0xc1, 0xa6, 0x17, 0x6e, + 0x14, 0xc1, 0xd8, 0x9e, 0x9e, 0xda, 0x3e, 0x44, 0x20, 0x98, 0xb0, 0x26, 0x31, 0x97, 0x1c, 0x1f, + 0xb2, 0x11, 0xb5, 0xd2, 0x88, 0x55, 0x44, 0xac, 0xe9, 0x69, 0xef, 0xc8, 0xe7, 0x3e, 0xcf, 0xfa, + 0x76, 0x7a, 0xca, 0xa3, 0xbd, 0x8d, 0xb4, 0x72, 0x2a, 0x8b, 0x98, 0xf3, 0x6d, 0xb4, 0xff, 0x3e, + 0xe7, 0x7f, 0x92, 0xae, 0x04, 0xfc, 0x15, 0xb5, 0x8a, 0x84, 0x50, 0x15, 0xa3, 0xde, 0xdf, 0x7b, + 0xf5, 0xdc, 0xda, 0x60, 0xb4, 0x06, 0x1e, 0x44, 0x92, 0x9d, 0x33, 0xf0, 0xde, 0xe5, 0x45, 0xe7, + 0xf1, 0x4d, 0xa2, 0xd7, 0xfe, 0x24, 0xfa, 0xc1, 0x9d, 0x16, 0xa9, 0x90, 0x98, 0xa0, 0x47, 0x2e, + 0x0d, 0x22, 0xfe, 0x7d, 0x0c, 0x9e, 0x0f, 0x21, 0x44, 0x52, 0xa8, 0x5b, 0x99, 0xc6, 0xd8, 0xa8, + 0xf9, 0xe8, 0xd2, 0x00, 0x64, 0xb6, 0x9a, 0xd3, 0x48, 0x05, 0xe4, 0xce, 0x3c, 0xfe, 0x80, 0xf6, + 0x28, 0x0f, 0x43, 0x26, 0x73, 0x5c, 0xfd, 0x5e, 0xb8, 0xd5, 0x51, 0xec, 0xa0, 0x56, 0x0c, 0x14, + 0xd8, 0x44, 0x0a, 0xb5, 0x71, 0x2f, 0x4c, 0x35, 0x87, 0x19, 0xea, 0x08, 0x88, 0xbc, 0xa1, 0x80, + 0x6f, 0x97, 0x10, 0x51, 0x10, 0xea, 0x76, 0x46, 0x7a, 0xf6, 0x2f, 0x52, 0x91, 0x75, 0x9e, 0xa4, + 0xb0, 0x45, 0xa2, 0x77, 0xaf, 0xdd, 0x70, 0xfc, 0xd6, 0x5c, 0x07, 0x99, 0xa4, 0x9d, 0x16, 0xca, + 0x70, 0xa6, 0x8a, 0x81, 0x4e, 0x57, 0x54, 0xcd, 0x07, 0xab, 0xd6, 0x41, 0x26, 0x69, 0xa7, 0x85, + 0xa5, 0xea, 0x1c, 0xb5, 0x5d, 0x1a, 0xac, 0x98, 0x76, 0xfe, 0xdf, 0x74, 0x5c, 0x98, 0x8e, 0x72, + 0xd3, 0x1a, 0xc7, 0x24, 0xfb, 0x2e, 0x0d, 0x96, 0x9e, 0xcf, 0xa8, 0x1b, 0xc1, 0x95, 0x1c, 0x16, + 0xb4, 0x2a, 0xa8, 0xb6, 0x0c, 0xa5, 0xdf, 0x70, 0x8c, 0x45, 0xa2, 0x1f, 0xe7, 0x98, 0x8d, 0x31, + 0x93, 0x1c, 0xa6, 0xf5, 0xe2, 0xbf, 0x2b, 0xb1, 0xe6, 0x0f, 0x05, 0x75, 0xd6, 0x97, 0xc2, 0x2f, + 0xd0, 0xce, 0x84, 0xc7, 0x72, 0xc8, 0x3c, 0x55, 0x31, 0x94, 0xfe, 0xae, 0x83, 0x17, 0x89, 0xde, + 0xc9, 0xd1, 0x45, 0xc3, 0x24, 0xcd, 0xf4, 0x34, 0xf0, 0xf0, 0x19, 0x42, 0xa5, 0x89, 0x79, 0xea, + 0x56, 0x96, 0xef, 0x2e, 0x12, 0xfd, 0x20, 0xcf, 0x2f, 0x7b, 0x26, 0xd9, 0x2d, 0x2e, 0x03, 0x0f, + 0xf7, 0x50, 0xab, 0x5a, 0xbf, 0x9e, 0xae, 0x4f, 0xaa, 0xbb, 0x43, 0x6e, 0x66, 0x9a, 0x72, 0x3b, + 0xd3, 0x94, 0xdf, 0x33, 0x4d, 0xf9, 0x39, 0xd7, 0x6a, 0xb7, 0x73, 0xad, 0xf6, 0x6b, 0xae, 0xd5, + 0xbe, 0xbc, 0xf1, 0x99, 0xbc, 0xb8, 0x1c, 0x59, 0x94, 0x87, 0x36, 0xe5, 0x22, 0xe4, 0xa2, 0xf8, + 0x9c, 0x08, 0x2f, 0xb0, 0xaf, 0xec, 0xea, 0x4d, 0xbf, 0x3c, 0x3b, 0x29, 0x9f, 0xb5, 0xbc, 0x9e, + 0x80, 0x18, 0x35, 0xb3, 0x27, 0xfd, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x42, 0xc2, + 0x18, 0x45, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -239,6 +250,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextChannelSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextChannelSequence)) + i-- + dAtA[i] = 0x40 + } if len(m.AckSequences) > 0 { for iNdEx := len(m.AckSequences) - 1; iNdEx >= 0; iNdEx-- { { @@ -441,6 +457,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextChannelSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextChannelSequence)) + } return n } @@ -737,6 +756,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextChannelSequence", wireType) + } + m.NextChannelSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextChannelSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/04-channel/types/genesis_test.go b/x/ibc/core/04-channel/types/genesis_test.go index c1dbfd76e0..05e154296e 100644 --- a/x/ibc/core/04-channel/types/genesis_test.go +++ b/x/ibc/core/04-channel/types/genesis_test.go @@ -66,6 +66,7 @@ func TestValidateGenesis(t *testing.T) { []types.PacketSequence{ types.NewPacketSequence(testPort2, testChannel2, 1), }, + 0, ), expPass: true, }, diff --git a/x/ibc/core/04-channel/types/keys.go b/x/ibc/core/04-channel/types/keys.go index 60f24d5e74..b6c5745dda 100644 --- a/x/ibc/core/04-channel/types/keys.go +++ b/x/ibc/core/04-channel/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC channels name SubModuleName = "channel" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC channels QuerierRoute = SubModuleName + + // KeyNextChannelSequence is the key used to store the next channel sequence in + // the keeper. + KeyNextChannelSequence = "nextChannelSequence" + + // ChannelPrefix is the prefix used when creating a channel identifier + ChannelPrefix = "channel-" ) + +// FormatChannelIdentifier returns the channel identifier with the sequence appended. +func FormatChannelIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ChannelPrefix, sequence) +} + +// IsValidChannelID return true if the channel identifier is valid. +func IsValidChannelID(channelID string) bool { + _, err := ParseChannelSequence(channelID) + return err == nil +} + +// ParseChannelSequence parses the channel sequence from the channel identifier. +func ParseChannelSequence(channelID string) (uint64, error) { + if !strings.HasPrefix(channelID, ChannelPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidChannelIdentifier, "doesn't contain prefix `%s`", ChannelPrefix) + } + + splitStr := strings.Split(channelID, ChannelPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidChannelIdentifier, "channel identifier must be in format: `channel-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse channel identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/04-channel/types/keys_test.go b/x/ibc/core/04-channel/types/keys_test.go new file mode 100644 index 0000000000..418174cb04 --- /dev/null +++ b/x/ibc/core/04-channel/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" + "github.com/stretchr/testify/require" +) + +// tests ParseChannelSequence and IsValidChannelID +func TestParseChannelSequence(t *testing.T) { + testCases := []struct { + name string + channelID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "channel-0", 0, true}, + {"valid 1", "channel-1", 1, true}, + {"valid large sequence", "channel-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "channel-2345682193567182931243", 0, false}, + {"capital prefix", "Channel-0", 0, false}, + {"missing dash", "channel0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "channel--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseChannelSequence(tc.channelID) + valid := types.IsValidChannelID(tc.channelID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/04-channel/types/msgs.go b/x/ibc/core/04-channel/types/msgs.go index 772a1204ef..da14a31030 100644 --- a/x/ibc/core/04-channel/types/msgs.go +++ b/x/ibc/core/04-channel/types/msgs.go @@ -12,19 +12,19 @@ import ( var _ sdk.Msg = &MsgChannelOpenInit{} -// NewMsgChannelOpenInit creates a new MsgChannelOpenInit +// NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel +// identifier to be empty. // nolint:interfacer func NewMsgChannelOpenInit( - portID, channelID string, version string, channelOrder Order, connectionHops []string, - counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, + portID, version string, channelOrder Order, connectionHops []string, + counterpartyPortID string, signer sdk.AccAddress, ) *MsgChannelOpenInit { - counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + counterparty := NewCounterparty(counterpartyPortID, "") channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenInit{ - PortId: portID, - ChannelId: channelID, - Channel: channel, - Signer: signer.String(), + PortId: portID, + Channel: channel, + Signer: signer.String(), } } @@ -43,15 +43,15 @@ func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") - } if msg.Channel.State != INIT { return sdkerrors.Wrapf(ErrInvalidChannelState, "channel state must be INIT in MsgChannelOpenInit. expected: %s, got: %s", INIT, msg.Channel.State, ) } + if msg.Channel.Counterparty.ChannelId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty channel identifier must be empty") + } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -79,21 +79,20 @@ var _ sdk.Msg = &MsgChannelOpenTry{} // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance // nolint:interfacer func NewMsgChannelOpenTry( - portID, desiredChannelID, counterpartyChosenChannelID, version string, channelOrder Order, connectionHops []string, + portID, previousChannelID, version string, channelOrder Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, proofInit []byte, proofHeight clienttypes.Height, signer sdk.AccAddress, ) *MsgChannelOpenTry { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) channel := NewChannel(TRYOPEN, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenTry{ - PortId: portID, - DesiredChannelId: desiredChannelID, - CounterpartyChosenChannelId: counterpartyChosenChannelID, - Channel: channel, - CounterpartyVersion: counterpartyVersion, - ProofInit: proofInit, - ProofHeight: proofHeight, - Signer: signer.String(), + PortId: portID, + PreviousChannelId: previousChannelID, + Channel: channel, + CounterpartyVersion: counterpartyVersion, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer.String(), } } @@ -112,11 +111,10 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.DesiredChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid desired channel ID") - } - if msg.CounterpartyChosenChannelId != "" && msg.CounterpartyChosenChannelId != msg.DesiredChannelId { - return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "counterparty chosen channel ID must be empty or equal to desired channel ID") + if msg.PreviousChannelId != "" { + if !IsValidChannelID(msg.PreviousChannelId) { + return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "invalid previous channel ID") + } } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") @@ -130,6 +128,11 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { TRYOPEN, msg.Channel.State, ) } + // counterparty validate basic allows empty counterparty channel identifiers + if err := host.ChannelIdentifierValidator(msg.Channel.Counterparty.ChannelId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty channel ID") + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -186,8 +189,8 @@ func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if err := host.ChannelIdentifierValidator(msg.CounterpartyChannelId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty channel ID") @@ -252,8 +255,8 @@ func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") @@ -312,8 +315,8 @@ func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -369,8 +372,8 @@ func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") diff --git a/x/ibc/core/04-channel/types/msgs_test.go b/x/ibc/core/04-channel/types/msgs_test.go index 3a666b31be..9c27fd69ef 100644 --- a/x/ibc/core/04-channel/types/msgs_test.go +++ b/x/ibc/core/04-channel/types/msgs_test.go @@ -23,7 +23,7 @@ import ( const ( // valid constatns used for testing portid = "testportid" - chanid = "testchannel" + chanid = "channel-0" cpportid = "testcpport" cpchanid = "testcpchannel" @@ -35,7 +35,7 @@ const ( invalidLongPort = "invalidlongportinvalidlongportinvalidlongportidinvalidlongportidinvalid" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" invalidConnection = "(invalidconnection1)" @@ -114,22 +114,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenInitValidateBasic() { msg *types.MsgChannelOpenInit expPass bool }{ - {"", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), true}, - {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too short channel id", types.NewMsgChannelOpenInit(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long channel id", types.NewMsgChannelOpenInit(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenInit(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"invalid channel order", types.NewMsgChannelOpenInit(portid, chanid, version, types.Order(3), connHops, cpportid, cpchanid, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, invalidConnHops, cpportid, cpchanid, addr), false}, - {"too short connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, addr), false}, - {"too long connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, addr), false}, - {"", types.NewMsgChannelOpenInit(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, addr), false}, - {"channel not in INIT state", &types.MsgChannelOpenInit{portid, chanid, tryOpenChannel, addr.String()}, false}, + {"", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, connHops, cpportid, addr), true}, + {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"invalid channel order", types.NewMsgChannelOpenInit(portid, version, types.Order(3), connHops, cpportid, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, invalidConnHops, cpportid, addr), false}, + {"too short connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidShortConnHops, cpportid, addr), false}, + {"too long connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidLongConnHops, cpportid, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, []string{invalidConnection}, cpportid, addr), false}, + {"", types.NewMsgChannelOpenInit(portid, "", types.UNORDERED, connHops, cpportid, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, connHops, invalidPort, addr), false}, + {"channel not in INIT state", &types.MsgChannelOpenInit{portid, tryOpenChannel, addr.String()}, false}, } for _, tc := range testCases { @@ -155,27 +151,25 @@ func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { msg *types.MsgChannelOpenTry expPass bool }{ - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, - {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, - {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, - {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, - {"valid empty proved channel id", types.NewMsgChannelOpenTry(portid, chanid, "", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid proved channel id, doesn't match channel id", types.NewMsgChannelOpenTry(portid, chanid, "differentchannel", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, + {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, + {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, + {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, + {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, + {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, } for _, tc := range testCases { diff --git a/x/ibc/core/04-channel/types/tx.pb.go b/x/ibc/core/04-channel/types/tx.pb.go index 608f573a77..9d2f3e221e 100644 --- a/x/ibc/core/04-channel/types/tx.pb.go +++ b/x/ibc/core/04-channel/types/tx.pb.go @@ -32,10 +32,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. type MsgChannelOpenInit struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` - Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` - Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + Channel Channel `protobuf:"bytes,2,opt,name=channel,proto3" json:"channel"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenInit) Reset() { *m = MsgChannelOpenInit{} } @@ -111,14 +110,15 @@ var xxx_messageInfo_MsgChannelOpenInitResponse proto.InternalMessageInfo // MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel // on Chain B. type MsgChannelOpenTry struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - DesiredChannelId string `protobuf:"bytes,2,opt,name=desired_channel_id,json=desiredChannelId,proto3" json:"desired_channel_id,omitempty" yaml:"desired_channel_id"` - CounterpartyChosenChannelId string `protobuf:"bytes,3,opt,name=counterparty_chosen_channel_id,json=counterpartyChosenChannelId,proto3" json:"counterparty_chosen_channel_id,omitempty" yaml:"counterparty_chosen_channel_id"` - Channel Channel `protobuf:"bytes,4,opt,name=channel,proto3" json:"channel"` - CounterpartyVersion string `protobuf:"bytes,5,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` - ProofInit []byte `protobuf:"bytes,6,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` - ProofHeight types.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` - Signer string `protobuf:"bytes,8,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + PreviousChannelId string `protobuf:"bytes,2,opt,name=previous_channel_id,json=previousChannelId,proto3" json:"previous_channel_id,omitempty" yaml:"previous_channel_id"` + Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` + CounterpartyVersion string `protobuf:"bytes,4,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` + ProofInit []byte `protobuf:"bytes,5,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofHeight types.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + Signer string `protobuf:"bytes,7,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenTry) Reset() { *m = MsgChannelOpenTry{} } @@ -853,80 +853,77 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1158 bytes of a gzipped FileDescriptorProto + // 1120 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0xd6, 0x9f, 0x65, 0x7b, 0xec, 0xc6, 0x0e, 0xfd, 0xa7, 0x50, 0xb6, 0xe8, 0x12, 0x68, 0xe2, - 0xa6, 0x88, 0x14, 0x3b, 0x01, 0xda, 0x06, 0xbd, 0x58, 0x02, 0x8a, 0x1a, 0x81, 0x91, 0x82, 0x71, - 0x7b, 0x30, 0x0a, 0x08, 0xf2, 0x6a, 0x43, 0x11, 0xb2, 0x76, 0x55, 0x92, 0x56, 0xac, 0x37, 0xe8, - 0x31, 0xe7, 0x9e, 0x72, 0xef, 0x21, 0x7d, 0x87, 0x5e, 0x72, 0xcc, 0x2d, 0x45, 0x0f, 0x44, 0x61, - 0x5f, 0x7a, 0xe6, 0x13, 0x14, 0x5c, 0x2e, 0x7f, 0x44, 0x91, 0x31, 0x5d, 0x57, 0x6a, 0x4f, 0x22, - 0x67, 0xbe, 0x9d, 0x9d, 0xfd, 0xe6, 0xdb, 0xd9, 0xa5, 0x60, 0x53, 0x3b, 0x41, 0x35, 0x44, 0x75, - 0x5c, 0x43, 0x9d, 0x16, 0x21, 0xf8, 0xb4, 0x36, 0xd8, 0xad, 0x99, 0xe7, 0xd5, 0xbe, 0x4e, 0x4d, - 0x2a, 0xac, 0x68, 0x27, 0xa8, 0xea, 0x78, 0xab, 0xdc, 0x5b, 0x1d, 0xec, 0x8a, 0xab, 0x2a, 0x55, - 0x29, 0xf3, 0xd7, 0x9c, 0x27, 0x17, 0x2a, 0x4a, 0x41, 0xa0, 0x53, 0x0d, 0x13, 0xd3, 0x89, 0xe3, - 0x3e, 0x71, 0xc0, 0xc7, 0x71, 0x33, 0x79, 0x61, 0x19, 0x44, 0x7e, 0x9f, 0x05, 0xe1, 0xd0, 0x50, - 0x1b, 0xae, 0xf1, 0x59, 0x1f, 0x93, 0x03, 0xa2, 0x99, 0xc2, 0x67, 0x30, 0xdb, 0xa7, 0xba, 0xd9, - 0xd4, 0xda, 0xa5, 0xec, 0x76, 0x76, 0x67, 0xbe, 0x2e, 0xd8, 0x96, 0x74, 0x6b, 0xd8, 0xea, 0x9d, - 0x3e, 0x91, 0xb9, 0x43, 0x56, 0x8a, 0xce, 0xd3, 0x41, 0x5b, 0x78, 0x0c, 0xc0, 0x83, 0x3a, 0xf8, - 0x1c, 0xc3, 0xaf, 0xd9, 0x96, 0x74, 0xdb, 0xc5, 0x07, 0x3e, 0x59, 0x99, 0xe7, 0x2f, 0x07, 0x6d, - 0xe1, 0x2b, 0x98, 0xe5, 0x2f, 0xa5, 0xfc, 0x76, 0x76, 0x67, 0x61, 0x6f, 0xb3, 0x1a, 0xb3, 0xf4, - 0x2a, 0xcf, 0xac, 0x5e, 0x78, 0x6b, 0x49, 0x19, 0xc5, 0x1b, 0x22, 0xac, 0x43, 0xd1, 0xd0, 0x54, - 0x82, 0xf5, 0x52, 0xc1, 0x99, 0x4f, 0xe1, 0x6f, 0x4f, 0xe6, 0x7e, 0x7a, 0x2d, 0x65, 0xfe, 0x7a, - 0x2d, 0x65, 0xe4, 0x4d, 0x10, 0xc7, 0x17, 0xa6, 0x60, 0xa3, 0x4f, 0x89, 0x81, 0xe5, 0xdf, 0x0a, - 0x70, 0x7b, 0xd4, 0x7d, 0xa4, 0x0f, 0xaf, 0xb7, 0xec, 0xa7, 0x20, 0xb4, 0xb1, 0xa1, 0xe9, 0xb8, - 0xdd, 0x1c, 0x5b, 0xfe, 0x96, 0x6d, 0x49, 0x77, 0xdc, 0x71, 0xe3, 0x18, 0x59, 0x59, 0xe6, 0xc6, - 0x86, 0xcf, 0x06, 0x81, 0x0a, 0xa2, 0x67, 0xc4, 0xc4, 0x7a, 0xbf, 0xa5, 0x9b, 0xc3, 0x26, 0xea, - 0x50, 0x03, 0x93, 0x70, 0xe0, 0x3c, 0x0b, 0xfc, 0xa9, 0x6d, 0x49, 0x9f, 0x70, 0x5e, 0x3f, 0x88, - 0x97, 0x95, 0x72, 0x18, 0xd0, 0x60, 0xfe, 0x46, 0x1c, 0xfb, 0x85, 0xeb, 0xb3, 0xaf, 0xc0, 0xea, - 0xc8, 0xec, 0x03, 0xac, 0x1b, 0x1a, 0x25, 0xa5, 0x19, 0x96, 0xa3, 0x64, 0x5b, 0x52, 0x39, 0x26, - 0x47, 0x8e, 0x92, 0x95, 0x95, 0xb0, 0xf9, 0x7b, 0xd7, 0xea, 0xa8, 0xa8, 0xaf, 0x53, 0xfa, 0xa2, - 0xa9, 0x11, 0xcd, 0x2c, 0x15, 0xb7, 0xb3, 0x3b, 0x8b, 0x61, 0x15, 0x05, 0x3e, 0x59, 0x99, 0x67, - 0x2f, 0x4c, 0xa8, 0xc7, 0xb0, 0xe8, 0x7a, 0x3a, 0x58, 0x53, 0x3b, 0x66, 0x69, 0x96, 0x2d, 0x46, - 0x0c, 0x2d, 0xc6, 0xdd, 0x10, 0x83, 0xdd, 0xea, 0x37, 0x0c, 0x51, 0x2f, 0x3b, 0x4b, 0xb1, 0x2d, - 0x69, 0x25, 0x1c, 0xd7, 0x1d, 0x2d, 0x2b, 0x0b, 0xec, 0xd5, 0x45, 0x86, 0x34, 0x36, 0x97, 0xa0, - 0xb1, 0x32, 0xdc, 0x19, 0x13, 0x91, 0x2f, 0xb1, 0xf7, 0xf9, 0xa8, 0xc4, 0xf6, 0x51, 0x77, 0x1a, - 0x3b, 0xeb, 0x18, 0x36, 0x22, 0xda, 0x88, 0x88, 0x48, 0xb6, 0x2d, 0xa9, 0x12, 0x2b, 0xa2, 0x20, - 0xde, 0xda, 0xa8, 0x7a, 0xbc, 0xd8, 0x49, 0x95, 0x2f, 0xdc, 0xa0, 0xf2, 0xbb, 0xe0, 0x16, 0xb4, - 0x69, 0xea, 0x43, 0x26, 0xa1, 0xc5, 0xfa, 0xaa, 0x6d, 0x49, 0xcb, 0xe1, 0x02, 0x99, 0xfa, 0x50, - 0x56, 0xe6, 0xd8, 0xb3, 0xb3, 0x51, 0xa3, 0x65, 0x2f, 0x4e, 0xa4, 0xec, 0xb3, 0x69, 0xcb, 0xbe, - 0x8f, 0xba, 0x7e, 0xd9, 0x7f, 0xc9, 0xc1, 0xda, 0xa8, 0xb7, 0x41, 0xc9, 0x0b, 0x4d, 0xef, 0x4d, - 0xa3, 0xf4, 0x3e, 0x95, 0x2d, 0xd4, 0x65, 0xc5, 0x8e, 0xa1, 0xb2, 0x85, 0xba, 0x1e, 0x95, 0x8e, - 0x20, 0xa3, 0x54, 0x16, 0x26, 0x42, 0xe5, 0x4c, 0x02, 0x95, 0x12, 0x6c, 0xc5, 0x92, 0xe5, 0xd3, - 0xf9, 0x73, 0x16, 0x56, 0x02, 0x44, 0xe3, 0x94, 0x1a, 0x78, 0x5a, 0x27, 0x54, 0x90, 0x7d, 0x3e, - 0x21, 0xfb, 0x2d, 0x28, 0xc7, 0xe4, 0xe6, 0xe7, 0xfe, 0x26, 0x07, 0xeb, 0x11, 0xff, 0x14, 0xb5, - 0x30, 0xda, 0x50, 0xf3, 0xff, 0xb0, 0xa1, 0x4e, 0x57, 0x0e, 0xdb, 0x50, 0x89, 0x27, 0xcc, 0xe7, - 0xf4, 0x55, 0x0e, 0x3e, 0x3a, 0x34, 0x54, 0x05, 0xa3, 0xc1, 0xb7, 0x2d, 0xd4, 0xc5, 0xa6, 0xf0, - 0x25, 0x14, 0xfb, 0xec, 0x89, 0x31, 0xb9, 0xb0, 0x57, 0x8e, 0x3d, 0xc9, 0x5c, 0x30, 0x3f, 0xc8, - 0xf8, 0x00, 0xe1, 0x6b, 0x58, 0x76, 0xd3, 0x45, 0xb4, 0xd7, 0xd3, 0xcc, 0x1e, 0x26, 0x26, 0xa3, - 0x77, 0xb1, 0x5e, 0xb6, 0x2d, 0x69, 0x23, 0xbc, 0xa0, 0x00, 0x21, 0x2b, 0x4b, 0xcc, 0xd4, 0xf0, - 0x2d, 0x63, 0xa4, 0xe5, 0x27, 0x42, 0x5a, 0xd2, 0x4d, 0x67, 0x83, 0x35, 0x9c, 0x80, 0x11, 0x9f, - 0xab, 0x3f, 0x72, 0x00, 0x87, 0x86, 0x7a, 0xa4, 0xf5, 0x30, 0x3d, 0xfb, 0x77, 0x88, 0x3a, 0x23, - 0x3a, 0x46, 0x58, 0x1b, 0xe0, 0x76, 0x12, 0x51, 0x01, 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x51, - 0xa2, 0x9e, 0x82, 0x40, 0xf0, 0xb9, 0xd9, 0x34, 0xf0, 0x8f, 0x67, 0x98, 0x20, 0xdc, 0xd4, 0x31, - 0x1a, 0x30, 0xd2, 0x0a, 0xe1, 0xfb, 0xd8, 0x38, 0x46, 0x56, 0x96, 0x1d, 0xe3, 0x73, 0x6e, 0x73, - 0x88, 0x4c, 0x21, 0xd5, 0x55, 0x76, 0x71, 0xe6, 0xdc, 0x06, 0xed, 0xca, 0x3d, 0xf4, 0xb9, 0xf9, - 0x19, 0x61, 0x1a, 0xfe, 0x3f, 0x30, 0xff, 0x39, 0x2c, 0x70, 0x21, 0x3b, 0x19, 0xf1, 0x76, 0xb0, - 0x6e, 0x5b, 0x92, 0x30, 0xa2, 0x72, 0xc7, 0x29, 0x2b, 0x6e, 0xe3, 0x70, 0x73, 0x9f, 0x64, 0x43, - 0x88, 0x2f, 0xd9, 0xcc, 0x4d, 0x4b, 0x56, 0xfc, 0xe0, 0xb9, 0x3d, 0x5a, 0x1b, 0xbf, 0x72, 0xbf, - 0xe6, 0x58, 0x41, 0xf7, 0x51, 0x97, 0xd0, 0x97, 0xa7, 0xb8, 0xad, 0x62, 0xb6, 0xb5, 0x6f, 0x50, - 0xba, 0x1d, 0x58, 0x6a, 0x8d, 0x46, 0x73, 0x2b, 0xa7, 0x44, 0xcd, 0x41, 0x71, 0x9c, 0x81, 0xed, - 0xa4, 0xe2, 0x30, 0xa7, 0x57, 0x9c, 0x7d, 0xe7, 0xe5, 0x3f, 0xee, 0xd6, 0xee, 0x27, 0x56, 0x84, - 0x31, 0x8f, 0xd0, 0xbd, 0x37, 0x73, 0x90, 0x3f, 0x34, 0x54, 0xa1, 0x0b, 0x4b, 0xd1, 0xcf, 0xcb, - 0x7b, 0xb1, 0x24, 0x8e, 0x7f, 0xae, 0x89, 0xb5, 0x94, 0x40, 0x6f, 0x52, 0xa1, 0x03, 0xb7, 0x22, - 0xdf, 0x74, 0x77, 0x53, 0x84, 0x38, 0xd2, 0x87, 0x62, 0x35, 0x1d, 0x2e, 0x61, 0x26, 0xe7, 0x26, - 0x95, 0x66, 0xa6, 0x7d, 0xd4, 0x4d, 0x35, 0x53, 0xe8, 0x46, 0x29, 0x98, 0x20, 0xc4, 0xdc, 0x26, - 0xef, 0xa7, 0x88, 0xc2, 0xb1, 0xe2, 0x5e, 0x7a, 0xac, 0x3f, 0x2b, 0x81, 0xe5, 0xb1, 0x4b, 0xd7, - 0xce, 0x15, 0x71, 0x7c, 0xa4, 0xf8, 0x30, 0x2d, 0xd2, 0x9f, 0xef, 0x25, 0xac, 0xc4, 0x5e, 0x94, - 0xd2, 0x04, 0xf2, 0xd6, 0xf9, 0xe8, 0x1a, 0x60, 0x7f, 0xe2, 0x1f, 0x00, 0x42, 0xb7, 0x09, 0x39, - 0x29, 0x44, 0x80, 0x11, 0xef, 0x5f, 0x8d, 0xf1, 0xa3, 0x3f, 0x87, 0x59, 0xef, 0xfc, 0x95, 0x92, - 0x86, 0x71, 0x80, 0x78, 0xef, 0x0a, 0x40, 0x58, 0x7b, 0x91, 0x13, 0xe6, 0xee, 0x15, 0x43, 0x39, - 0x2e, 0x59, 0x7b, 0xf1, 0x5d, 0xd1, 0xd9, 0xbc, 0xd1, 0x8e, 0x98, 0x98, 0x65, 0x04, 0x98, 0xbc, - 0x79, 0x13, 0x3a, 0x46, 0x5d, 0x79, 0x7b, 0x51, 0xc9, 0xbe, 0xbb, 0xa8, 0x64, 0xff, 0xbc, 0xa8, - 0x64, 0x5f, 0x5d, 0x56, 0x32, 0xef, 0x2e, 0x2b, 0x99, 0xdf, 0x2f, 0x2b, 0x99, 0xe3, 0x2f, 0x54, - 0xcd, 0xec, 0x9c, 0x9d, 0x54, 0x11, 0xed, 0xd5, 0x10, 0x35, 0x7a, 0xd4, 0xe0, 0x3f, 0x0f, 0x8c, - 0x76, 0xb7, 0x76, 0x5e, 0xf3, 0xff, 0xe8, 0x7a, 0xf8, 0xf8, 0x81, 0xf7, 0x5f, 0x97, 0x39, 0xec, - 0x63, 0xe3, 0xa4, 0xc8, 0xfe, 0xe7, 0x7a, 0xf4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x07, - 0x48, 0xeb, 0x76, 0x13, 0x00, 0x00, + 0x10, 0xd6, 0x8f, 0x2d, 0xdb, 0x63, 0x37, 0xb6, 0x29, 0xff, 0x28, 0x94, 0x2d, 0xba, 0x3c, 0x24, + 0x42, 0x8a, 0x48, 0xb1, 0x63, 0xa0, 0x6d, 0xd0, 0x8b, 0x64, 0xa0, 0x68, 0x50, 0xb8, 0x29, 0x18, + 0xb7, 0x07, 0xa3, 0x80, 0x20, 0xaf, 0x36, 0x14, 0x21, 0x89, 0xab, 0x92, 0x94, 0x62, 0xbd, 0x41, + 0x8f, 0x39, 0xf7, 0x94, 0x9e, 0x7b, 0x48, 0x1f, 0x23, 0xc7, 0x9c, 0xda, 0xa2, 0x07, 0xa2, 0xb0, + 0x2f, 0x3d, 0xf3, 0x09, 0x0a, 0xee, 0x2e, 0x29, 0x4a, 0x22, 0x2b, 0x2a, 0xa9, 0x9c, 0x9c, 0xb4, + 0x9c, 0xf9, 0x76, 0x76, 0xf6, 0xfb, 0x86, 0xb3, 0x4b, 0xc1, 0x9e, 0x76, 0x81, 0xca, 0x88, 0x18, + 0xb8, 0x8c, 0x9a, 0x75, 0x5d, 0xc7, 0xed, 0x72, 0xff, 0xb0, 0x6c, 0x5d, 0x96, 0xba, 0x06, 0xb1, + 0x88, 0x90, 0xd5, 0x2e, 0x50, 0xc9, 0xf5, 0x96, 0xb8, 0xb7, 0xd4, 0x3f, 0x14, 0xb7, 0x54, 0xa2, + 0x12, 0xea, 0x2f, 0xbb, 0x23, 0x06, 0x15, 0xa5, 0x61, 0xa0, 0xb6, 0x86, 0x75, 0xcb, 0x8d, 0xc3, + 0x46, 0x1c, 0xf0, 0x71, 0xd8, 0x4a, 0x5e, 0x58, 0x0a, 0x91, 0x7f, 0x49, 0x82, 0x70, 0x6a, 0xaa, + 0x27, 0xcc, 0xf8, 0xa4, 0x8b, 0xf5, 0xc7, 0xba, 0x66, 0x09, 0x9f, 0xc0, 0x52, 0x97, 0x18, 0x56, + 0x4d, 0x6b, 0xe4, 0x92, 0x07, 0xc9, 0xe2, 0x4a, 0x55, 0x70, 0x6c, 0xe9, 0xd6, 0xa0, 0xde, 0x69, + 0x3f, 0x92, 0xb9, 0x43, 0x56, 0x32, 0xee, 0xe8, 0x71, 0x43, 0xf8, 0x02, 0x96, 0x78, 0xd0, 0x5c, + 0xea, 0x20, 0x59, 0x5c, 0x3d, 0xda, 0x2b, 0x85, 0x6c, 0xa2, 0xc4, 0xd7, 0xa8, 0x2e, 0xbc, 0xb6, + 0xa5, 0x84, 0xe2, 0x4d, 0x11, 0x76, 0x20, 0x63, 0x6a, 0xaa, 0x8e, 0x8d, 0x5c, 0xda, 0x5d, 0x49, + 0xe1, 0x4f, 0x8f, 0x96, 0x7f, 0x7a, 0x29, 0x25, 0xfe, 0x79, 0x29, 0x25, 0xe4, 0x3d, 0x10, 0x27, + 0x53, 0x54, 0xb0, 0xd9, 0x25, 0xba, 0x89, 0xe5, 0xdf, 0xd3, 0xb0, 0x39, 0xea, 0x3e, 0x33, 0x06, + 0xb3, 0x6d, 0xe0, 0x1b, 0xc8, 0x76, 0x0d, 0xdc, 0xd7, 0x48, 0xcf, 0xac, 0xf1, 0xb4, 0xdc, 0x89, + 0x29, 0x3a, 0xb1, 0xe0, 0xd8, 0x92, 0xc8, 0x27, 0x4e, 0x82, 0x64, 0x65, 0xd3, 0xb3, 0xf2, 0x0c, + 0x46, 0x09, 0x49, 0xcf, 0x4e, 0x88, 0x02, 0x5b, 0x88, 0xf4, 0x74, 0x0b, 0x1b, 0xdd, 0xba, 0x61, + 0x0d, 0x6a, 0x7d, 0x6c, 0x98, 0x1a, 0xd1, 0x73, 0x0b, 0x34, 0x1d, 0xc9, 0xb1, 0xa5, 0x3c, 0x4b, + 0x27, 0x0c, 0x25, 0x2b, 0xd9, 0xa0, 0xf9, 0x7b, 0x66, 0x15, 0x8e, 0x01, 0xba, 0x06, 0x21, 0xcf, + 0x6a, 0x9a, 0xae, 0x59, 0xb9, 0xc5, 0x83, 0x64, 0x71, 0xad, 0xba, 0xed, 0xd8, 0xd2, 0xa6, 0xb7, + 0x31, 0xcf, 0x27, 0x2b, 0x2b, 0xf4, 0x81, 0x56, 0xc1, 0x39, 0xac, 0x31, 0x4f, 0x13, 0x6b, 0x6a, + 0xd3, 0xca, 0x65, 0xe8, 0x66, 0xc4, 0xc0, 0x66, 0x58, 0xb5, 0xf5, 0x0f, 0x4b, 0x5f, 0x51, 0x44, + 0x35, 0xef, 0x6e, 0xc5, 0xb1, 0xa5, 0x6c, 0x30, 0x2e, 0x9b, 0x2d, 0x2b, 0xab, 0xf4, 0x91, 0x21, + 0x03, 0xb2, 0x2f, 0x45, 0xc8, 0x9e, 0x87, 0xdb, 0x13, 0xba, 0xfa, 0xaa, 0xff, 0x31, 0xa1, 0x7a, + 0x05, 0xb5, 0x66, 0x53, 0xfd, 0x18, 0x60, 0x42, 0xec, 0x00, 0x27, 0x41, 0x8d, 0x57, 0x90, 0xaf, + 0xed, 0x39, 0xec, 0x8e, 0xf0, 0x1e, 0x08, 0x41, 0xeb, 0xb7, 0x2a, 0x3b, 0xb6, 0x54, 0x08, 0x11, + 0x28, 0x18, 0x6f, 0x3b, 0xe8, 0x19, 0xd6, 0xcd, 0x3c, 0x94, 0x3f, 0x04, 0x26, 0x68, 0xcd, 0x32, + 0x06, 0x5c, 0xf8, 0x2d, 0xc7, 0x96, 0x36, 0x82, 0x02, 0x59, 0xc6, 0x40, 0x56, 0x96, 0xe9, 0xd8, + 0x7d, 0x77, 0x3e, 0x30, 0xd9, 0x2b, 0xa8, 0xe5, 0xcb, 0xfe, 0x6b, 0x0a, 0xb6, 0x47, 0xbd, 0x27, + 0x44, 0x7f, 0xa6, 0x19, 0x9d, 0x9b, 0x90, 0xde, 0xa7, 0xb2, 0x8e, 0x5a, 0x54, 0xec, 0x10, 0x2a, + 0xeb, 0xa8, 0xe5, 0x51, 0xe9, 0x16, 0xe4, 0x38, 0x95, 0x0b, 0x73, 0xa1, 0x72, 0x31, 0x82, 0x4a, + 0x09, 0xf6, 0x43, 0xc9, 0xf2, 0xe9, 0xfc, 0x39, 0x09, 0xd9, 0x21, 0xe2, 0xa4, 0x4d, 0x4c, 0x3c, + 0x7b, 0xfb, 0x7f, 0x3b, 0x32, 0xa7, 0xb7, 0xfd, 0x7d, 0xc8, 0x87, 0xe4, 0xe6, 0xe7, 0xfe, 0x2a, + 0x05, 0x3b, 0x63, 0xfe, 0x1b, 0xac, 0x85, 0xd1, 0x86, 0x9a, 0x7e, 0xcb, 0x86, 0x7a, 0xb3, 0xe5, + 0x70, 0x00, 0x85, 0x70, 0xc2, 0x7c, 0x4e, 0x5f, 0xa4, 0xe0, 0xa3, 0x53, 0x53, 0x55, 0x30, 0xea, + 0x7f, 0x5b, 0x47, 0x2d, 0x6c, 0x09, 0x9f, 0x43, 0xa6, 0x4b, 0x47, 0x94, 0xc9, 0xd5, 0xa3, 0x7c, + 0xe8, 0x49, 0xc6, 0xc0, 0xfc, 0x20, 0xe3, 0x13, 0x84, 0x2f, 0x61, 0x83, 0xa5, 0x8b, 0x48, 0xa7, + 0xa3, 0x59, 0x1d, 0xac, 0x5b, 0x94, 0xde, 0xb5, 0x6a, 0xde, 0xb1, 0xa5, 0xdd, 0xe0, 0x86, 0x86, + 0x08, 0x59, 0x59, 0xa7, 0xa6, 0x13, 0xdf, 0x32, 0x41, 0x5a, 0x7a, 0x2e, 0xa4, 0x2d, 0x44, 0x90, + 0xb6, 0x4b, 0x1b, 0xce, 0x90, 0x11, 0x9f, 0xab, 0xbf, 0x52, 0x00, 0xa7, 0xa6, 0x7a, 0xa6, 0x75, + 0x30, 0xe9, 0xfd, 0x3f, 0x44, 0xf5, 0x74, 0x03, 0x23, 0xac, 0xf5, 0x71, 0x23, 0x8a, 0xa8, 0x21, + 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x57, 0xa2, 0xbe, 0x06, 0x41, 0xc7, 0x97, 0x56, 0xcd, 0xc4, + 0x3f, 0xf6, 0xb0, 0x8e, 0x70, 0xcd, 0xc0, 0xa8, 0x4f, 0x49, 0x5b, 0xa8, 0xee, 0x3b, 0xb6, 0x74, + 0x9b, 0x45, 0x98, 0xc4, 0xc8, 0xca, 0x86, 0x6b, 0x7c, 0xca, 0x6d, 0x2e, 0x91, 0x31, 0x4a, 0x75, + 0x8b, 0xde, 0x4a, 0x39, 0xb7, 0xc3, 0x76, 0xc5, 0x0e, 0x7d, 0x6e, 0x7e, 0xa2, 0xd3, 0x1a, 0xfe, + 0x10, 0x98, 0xff, 0x14, 0x56, 0x79, 0x21, 0xbb, 0x19, 0xf1, 0x76, 0xb0, 0xe3, 0xd8, 0x92, 0x30, + 0x52, 0xe5, 0xae, 0x53, 0x56, 0x58, 0xe3, 0x60, 0xb9, 0xcf, 0xb3, 0x21, 0x84, 0x4b, 0xb6, 0xf8, + 0xae, 0x92, 0x65, 0xfe, 0xf3, 0xdc, 0x1e, 0xd5, 0xc6, 0x57, 0xee, 0xb7, 0x14, 0x15, 0xb4, 0x82, + 0x5a, 0x3a, 0x79, 0xde, 0xc6, 0x0d, 0x15, 0xd3, 0x57, 0xfb, 0x1d, 0xa4, 0x2b, 0xc2, 0x7a, 0x7d, + 0x34, 0x1a, 0x53, 0x4e, 0x19, 0x37, 0x0f, 0xc5, 0x71, 0x27, 0x36, 0xa2, 0xc4, 0xa1, 0x4e, 0x4f, + 0x9c, 0x8a, 0xfb, 0xf0, 0x9e, 0xbb, 0x35, 0xfb, 0xea, 0x19, 0x63, 0xcc, 0x23, 0xf4, 0xe8, 0xd5, + 0x32, 0xa4, 0x4f, 0x4d, 0x55, 0x68, 0xc1, 0xfa, 0xf8, 0xb7, 0xdb, 0xdd, 0x50, 0x12, 0x27, 0xbf, + 0xa0, 0xc4, 0x72, 0x4c, 0xa0, 0xb7, 0xa8, 0xd0, 0x84, 0x5b, 0x63, 0x9f, 0x59, 0x77, 0x62, 0x84, + 0x38, 0x33, 0x06, 0x62, 0x29, 0x1e, 0x2e, 0x62, 0x25, 0xf7, 0x26, 0x15, 0x67, 0xa5, 0x0a, 0x6a, + 0xc5, 0x5a, 0x29, 0x70, 0xa3, 0x14, 0x2c, 0x10, 0x42, 0x6e, 0x93, 0xf7, 0x62, 0x44, 0xe1, 0x58, + 0xf1, 0x28, 0x3e, 0xd6, 0x5f, 0x55, 0x87, 0x8d, 0x89, 0x4b, 0x57, 0x71, 0x4a, 0x1c, 0x1f, 0x29, + 0x3e, 0x88, 0x8b, 0xf4, 0xd7, 0x7b, 0x0e, 0xd9, 0xd0, 0x8b, 0x52, 0x9c, 0x40, 0xde, 0x3e, 0x1f, + 0xce, 0x00, 0xf6, 0x17, 0xfe, 0x01, 0x20, 0x70, 0x9b, 0x90, 0xa3, 0x42, 0x0c, 0x31, 0xe2, 0xbd, + 0xe9, 0x18, 0x3f, 0xfa, 0x53, 0x58, 0xf2, 0xce, 0x5f, 0x29, 0x6a, 0x1a, 0x07, 0x88, 0x77, 0xa7, + 0x00, 0x82, 0xb5, 0x37, 0x76, 0xc2, 0xdc, 0x99, 0x32, 0x95, 0xe3, 0xa2, 0x6b, 0x2f, 0xbc, 0x2b, + 0xba, 0x2f, 0xef, 0x78, 0x47, 0x8c, 0xcc, 0x72, 0x0c, 0x18, 0xfd, 0xf2, 0x46, 0x74, 0x8c, 0xaa, + 0xf2, 0xfa, 0xaa, 0x90, 0x7c, 0x73, 0x55, 0x48, 0xfe, 0x7d, 0x55, 0x48, 0xbe, 0xb8, 0x2e, 0x24, + 0xde, 0x5c, 0x17, 0x12, 0x7f, 0x5e, 0x17, 0x12, 0xe7, 0x9f, 0xa9, 0x9a, 0xd5, 0xec, 0x5d, 0x94, + 0x10, 0xe9, 0x94, 0x11, 0x31, 0x3b, 0xc4, 0xe4, 0x3f, 0xf7, 0xcd, 0x46, 0xab, 0x7c, 0x59, 0xf6, + 0xff, 0x45, 0x7a, 0x70, 0x7c, 0xdf, 0xfb, 0x23, 0xc9, 0x1a, 0x74, 0xb1, 0x79, 0x91, 0xa1, 0x7f, + 0x22, 0x3d, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xe9, 0x16, 0xfa, 0xd3, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1378,7 +1375,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1389,14 +1386,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - if len(m.ChannelId) > 0 { - i -= len(m.ChannelId) - copy(dAtA[i:], m.ChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) - i-- - dAtA[i] = 0x12 - } + dAtA[i] = 0x12 if len(m.PortId) > 0 { i -= len(m.PortId) copy(dAtA[i:], m.PortId) @@ -1455,7 +1445,7 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -1466,20 +1456,20 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 if len(m.ProofInit) > 0 { i -= len(m.ProofInit) copy(dAtA[i:], m.ProofInit) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } if len(m.CounterpartyVersion) > 0 { i -= len(m.CounterpartyVersion) copy(dAtA[i:], m.CounterpartyVersion) i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1490,18 +1480,11 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - if len(m.CounterpartyChosenChannelId) > 0 { - i -= len(m.CounterpartyChosenChannelId) - copy(dAtA[i:], m.CounterpartyChosenChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenChannelId))) - i-- - dAtA[i] = 0x1a - } - if len(m.DesiredChannelId) > 0 { - i -= len(m.DesiredChannelId) - copy(dAtA[i:], m.DesiredChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredChannelId))) + dAtA[i] = 0x1a + if len(m.PreviousChannelId) > 0 { + i -= len(m.PreviousChannelId) + copy(dAtA[i:], m.PreviousChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousChannelId))) i-- dAtA[i] = 0x12 } @@ -2236,10 +2219,6 @@ func (m *MsgChannelOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Channel.Size() n += 1 + l + sovTx(uint64(l)) l = len(m.Signer) @@ -2268,11 +2247,7 @@ func (m *MsgChannelOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenChannelId) + l = len(m.PreviousChannelId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -2652,38 +2627,6 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) } @@ -2716,7 +2659,7 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -2888,7 +2831,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousChannelId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2916,41 +2859,9 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredChannelId = string(dAtA[iNdEx:postIndex]) + m.PreviousChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenChannelId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CounterpartyChosenChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) } @@ -2983,7 +2894,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", wireType) } @@ -3015,7 +2926,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } m.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -3049,7 +2960,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -3082,7 +2993,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/24-host/validate.go b/x/ibc/core/24-host/validate.go index d589223f58..10458e8d3a 100644 --- a/x/ibc/core/24-host/validate.go +++ b/x/ibc/core/24-host/validate.go @@ -70,10 +70,10 @@ func ConnectionIdentifierValidator(id string) error { } // ChannelIdentifierValidator is the default validator function for Channel identifiers. -// A valid Identifier must be between 10-64 characters and only contain alphanumeric and some allowed +// A valid Identifier must be between 8-64 characters and only contain alphanumeric and some allowed // special characters (see IsValidID). func ChannelIdentifierValidator(id string) error { - return defaultIdentifierValidator(id, 10, DefaultMaxCharacterLength) + return defaultIdentifierValidator(id, 8, DefaultMaxCharacterLength) } // PortIdentifierValidator is the default validator function for Port identifiers. diff --git a/x/ibc/core/genesis_test.go b/x/ibc/core/genesis_test.go index d435cf8566..29a26aad74 100644 --- a/x/ibc/core/genesis_test.go +++ b/x/ibc/core/genesis_test.go @@ -105,6 +105,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -133,6 +134,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, expPass: true, @@ -168,6 +170,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), }, expPass: false, @@ -244,6 +247,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -272,6 +276,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, }, diff --git a/x/ibc/core/keeper/msg_server.go b/x/ibc/core/keeper/msg_server.go index 9ca0697e1f..2b655ff9a2 100644 --- a/x/ibc/core/keeper/msg_server.go +++ b/x/ibc/core/keeper/msg_server.go @@ -132,16 +132,15 @@ func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSu func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.ConnectionKeeper.ConnOpenInit( - ctx, msg.ConnectionId, msg.ClientId, msg.Counterparty, msg.Version, - ); err != nil { + connectionID, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenInit, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -164,18 +163,19 @@ func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.Ms return nil, sdkerrors.Wrapf(err, "client in msg is not exported.ClientState. invalid client: %v.", targetClient) } - if err := k.ConnectionKeeper.ConnOpenTry( - ctx, msg.DesiredConnectionId, msg.CounterpartyChosenConnectionId, msg.Counterparty, msg.ClientId, targetClient, + connectionID, err := k.ConnectionKeeper.ConnOpenTry( + ctx, msg.PreviousConnectionId, msg.Counterparty, msg.ClientId, targetClient, connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, - ); err != nil { + ) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenTry, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.DesiredConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -263,7 +263,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -274,7 +274,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { + if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { return nil, sdkerrors.Wrap(err, "channel open init callback failed") } @@ -290,7 +290,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -301,7 +301,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { + if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { return nil, sdkerrors.Wrap(err, "channel open try callback failed") } diff --git a/x/ibc/core/spec/01_concepts.md b/x/ibc/core/spec/01_concepts.md index 079e6fa702..4b002458eb 100644 --- a/x/ibc/core/spec/01_concepts.md +++ b/x/ibc/core/spec/01_concepts.md @@ -131,16 +131,18 @@ The IBC interfaces expect an `ibcexported.Height` interface, however all clients The connection handshake occurs in 4 steps as defined in [ICS 03](https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics). `ConnOpenInit` is the first attempt to initialize a connection on the executing chain. -The handshake is expected to succeed if the connection identifier selected is not used and the -version selected is supported. The connection identifier for the counterparty connection may -be left empty indicating that the counterparty may select its own identifier. The connection -is set and stored in the INIT state upon success. +The handshake is expected to succeed if the version selected is supported. The connection +identifier for the counterparty connection must be left empty indicating that the counterparty +must select its own identifier. The connection identifier is auto derived in the format: +`connection{N}` where N is the next sequence to be used. The counter begins at 0 and increments +by 1. The connection is set and stored in the INIT state upon success. `ConnOpenTry` is a response to a chain executing `ConnOpenInit`. The executing chain will validate -the chain level parameters the counterparty has stored such as its chainID and consensus parameters. -The executing chain will also verify that if a previous connection exists for the specified -connection identifier that all the parameters match and its previous state was in INIT. This -may occur when both chains execute `ConnOpenInit` simultaneously. The executing chain will verify +the chain level parameters the counterparty has stored such as its chainID. The executing chain +will also verify that if a previous connection exists for the specified connection identifier +that all the parameters match and its previous state was in INIT. This may occur when both +chains execute `ConnOpenInit` simultaneously. If the connection does not exist then a connection +identifier is generated in the same format done in `ConnOpenInit`. The executing chain will verify that the counterparty created a connection in INIT state. The executing chain will also verify The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The executing chain will select a version from the intersection of its supported versions and the @@ -208,23 +210,25 @@ versions should have a unique version identifier. The channel handshake occurs in 4 steps as defined in [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics). `ChanOpenInit` is the first attempt to initialize a channel on top of an existing connection. -The handshake is expected to succeed if the channel identifier selected is not used and the -version selected for the existing connection is a supported IBC version. The portID must correspond -to a port already binded upon `InitChain`. The channel identifier for the counterparty channel -may be left empty indicating that the counterparty may select its own identifier. The channel is -set and stored in the INIT state upon success. The channel parameters `NextSequenceSend`, -`NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and a channel capability is created -for the given portID and channelID path. +The handshake is expected to succeed if the version selected for the existing connection is a +supported IBC version. The portID must correspond to a port already binded upon `InitChain`. +The channel identifier for the counterparty channel must be left empty indicating that the +counterparty must select its own identifier. The channel identifier is auto derived in the +format: `channel{N}` where N is the next sequence to be used. The channel is set and stored +in the INIT state upon success. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, +and `NextSequenceAck` are all set to 1 and a channel capability is created for the given +portID and channelID path. `ChanOpenTry` is a response to a chain executing `ChanOpenInit`. If the executing chain is calling `ChanOpenTry` after previously executing `ChanOpenInit` then the provided channel parameters must -match the previously selected parameters. The connection the channel is created on top of must be -an OPEN state and its IBC version must support the desired channel type being created (ORDERED, -UNORDERED, etc). The executing chain will verify that the channel state of the counterparty is -in INIT. The executing chain will set and store the channel state in TRYOPEN. The channel -parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and -a channel capability is created for the given portID and channelID path only if the channel -did not previously exist. +match the previously selected parameters. If the previous channel does not exist then a channel +identifier is generated in the same format as done in `ChanOpenInit`. The connection the channel +is created on top of must be an OPEN state and its IBC version must support the desired channel +type being created (ORDERED, UNORDERED, etc). The executing chain will verify that the channel +state of the counterparty is in INIT. The executing chain will set and store the channel state +in TRYOPEN. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` +are all set to 1 and a channel capability is created for the given portID and channelID path only +if the channel did not previously exist. `ChanOpenAck` may be called on a chain when the counterparty channel has entered TRYOPEN. A previous channel on the executing chain must exist be in either INIT or TRYOPEN state. If the diff --git a/x/ibc/core/spec/06_events.md b/x/ibc/core/spec/06_events.md index 9f96b089b3..528a30cffa 100644 --- a/x/ibc/core/spec/06_events.md +++ b/x/ibc/core/spec/06_events.md @@ -66,7 +66,6 @@ callbacks to IBC applications. | connection_open_init | connection_id | {connectionId} | | connection_open_init | client_id | {clientId} | | connection_open_init | counterparty_client_id | {counterparty.clientId} | -| connection_open_init | counterparty_connection_id | {counterparty.connectionId} | | message | action | connection_open_init | | message | module | ibc_connection | @@ -112,7 +111,6 @@ callbacks to IBC applications. | channel_open_init | port_id | {portId} | | channel_open_init | channel_id | {channelId} | | channel_open_init | counterparty_port_id | {channel.counterparty.portId} | -| channel_open_init | counterparty_channel_id | {channel.counterparty.channelId} | | channel_open_init | connection_id | {channel.connectionHops} | | message | action | channel_open_init | | message | module | ibc_channel | diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index 0c285a275c..0ac3c51579 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -388,7 +388,7 @@ func (chain *TestChain) AddTestConnection(clientID, counterpartyClientID string) // created given a clientID and counterparty clientID. The connection id // format: -conn func (chain *TestChain) ConstructNextTestConnection(clientID, counterpartyClientID string) *TestConnection { - connectionID := fmt.Sprintf("%s-%s%d", chain.ChainID, ConnectionIDPrefix, len(chain.Connections)) + connectionID := connectiontypes.FormatConnectionIdentifier(uint64(len(chain.Connections))) return &TestConnection{ ID: connectionID, ClientID: clientID, @@ -407,6 +407,34 @@ func (chain *TestChain) GetFirstTestConnection(clientID, counterpartyClientID st return chain.ConstructNextTestConnection(clientID, counterpartyClientID) } +// AddTestChannel appends a new TestChannel which contains references to the port and channel ID +// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. +func (chain *TestChain) AddTestChannel(conn *TestConnection, portID string) TestChannel { + channel := chain.NextTestChannel(conn, portID) + conn.Channels = append(conn.Channels, channel) + return channel +} + +// NextTestChannel returns the next test channel to be created on this connection, but does not +// add it to the list of created channels. This function is expected to be used when the caller +// has not created the associated channel in app state, but would still like to refer to the +// non-existent channel usually to test for its non-existence. +// +// channel ID format: -chan +// +// The port is passed in by the caller. +func (chain *TestChain) NextTestChannel(conn *TestConnection, portID string) TestChannel { + nextChanSeq := chain.App.IBCKeeper.ChannelKeeper.GetNextChannelSequence(chain.GetContext()) + channelID := channeltypes.FormatChannelIdentifier(nextChanSeq) + return TestChannel{ + PortID: portID, + ID: channelID, + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } +} + // ConstructMsgCreateClient constructs a message to create a new client state (tendermint or solomachine). // NOTE: a solo machine client will be created with an empty diversifier. func (chain *TestChain) ConstructMsgCreateClient(counterparty *TestChain, clientID string, clientType string) *clienttypes.MsgCreateClient { @@ -613,8 +641,8 @@ func (chain *TestChain) ConnectionOpenInit( connection, counterpartyConnection *TestConnection, ) error { msg := connectiontypes.NewMsgConnectionOpenInit( - connection.ID, connection.ClientID, - counterpartyConnection.ID, connection.CounterpartyClientID, + connection.ClientID, + connection.CounterpartyClientID, counterparty.GetPrefix(), DefaultOpenInitVersion, chain.SenderAccount.GetAddress(), ) @@ -634,7 +662,7 @@ func (chain *TestChain) ConnectionOpenTry( proofConsensus, consensusHeight := counterparty.QueryConsensusStateProof(counterpartyConnection.ClientID) msg := connectiontypes.NewMsgConnectionOpenTry( - connection.ID, connection.ID, connection.ClientID, // testing doesn't use flexible selection + "", connection.ClientID, // does not support handshake continuation counterpartyConnection.ID, counterpartyConnection.ClientID, counterpartyClient, counterparty.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, proofInit, proofClient, proofConsensus, @@ -756,9 +784,9 @@ func (chain *TestChain) ChanOpenInit( connectionID string, ) error { msg := channeltypes.NewMsgChannelOpenInit( - ch.PortID, ch.ID, + ch.PortID, ch.Version, order, []string{connectionID}, - counterparty.PortID, counterparty.ID, + counterparty.PortID, chain.SenderAccount.GetAddress(), ) return chain.sendMsgs(msg) @@ -774,10 +802,9 @@ func (chain *TestChain) ChanOpenTry( proof, height := counterparty.QueryProof(host.ChannelKey(counterpartyCh.PortID, counterpartyCh.ID)) msg := channeltypes.NewMsgChannelOpenTry( - ch.PortID, ch.ID, ch.ID, // testing doesn't use flexible selection + ch.PortID, "", // does not support handshake continuation ch.Version, order, []string{connectionID}, - counterpartyCh.PortID, counterpartyCh.ID, - counterpartyCh.Version, + counterpartyCh.PortID, counterpartyCh.ID, counterpartyCh.Version, proof, height, chain.SenderAccount.GetAddress(), ) diff --git a/x/ibc/testing/coordinator.go b/x/ibc/testing/coordinator.go index b1c6e99d3f..aecdcd4b70 100644 --- a/x/ibc/testing/coordinator.go +++ b/x/ibc/testing/coordinator.go @@ -394,6 +394,46 @@ func (coord *Coordinator) ConnOpenInit( return sourceConnection, counterpartyConnection, nil } +// ConnOpenInitOnBothChains initializes a connection on the source chain with the state INIT +// using the OpenInit handshake call. +func (coord *Coordinator) ConnOpenInitOnBothChains( + source, counterparty *TestChain, + clientID, counterpartyClientID string, +) (*TestConnection, *TestConnection, error) { + sourceConnection := source.AddTestConnection(clientID, counterpartyClientID) + counterpartyConnection := counterparty.AddTestConnection(counterpartyClientID, clientID) + + // initialize connection on source + if err := source.ConnectionOpenInit(counterparty, sourceConnection, counterpartyConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // initialize connection on counterparty + if err := counterparty.ConnectionOpenInit(source, counterpartyConnection, sourceConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // update counterparty client on source connection + if err := coord.UpdateClient( + source, counterparty, + clientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + // update source client on counterparty connection + if err := coord.UpdateClient( + counterparty, source, + counterpartyClientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + return sourceConnection, counterpartyConnection, nil +} + // ConnOpenTry initializes a connection on the source chain with the state TRYOPEN // using the OpenTry handshake call. func (coord *Coordinator) ConnOpenTry( @@ -461,8 +501,8 @@ func (coord *Coordinator) ChanOpenInit( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. @@ -494,8 +534,8 @@ func (coord *Coordinator) ChanOpenInitOnBothChains( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. diff --git a/x/ibc/testing/types.go b/x/ibc/testing/types.go index c71b0ebd97..16cda6216b 100644 --- a/x/ibc/testing/types.go +++ b/x/ibc/testing/types.go @@ -1,7 +1,7 @@ package ibctesting import ( - "fmt" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" ) // TestConnection is a testing helper struct to keep track of the connectionID, source clientID, @@ -15,33 +15,6 @@ type TestConnection struct { Channels []TestChannel } -// AddTestChannel appends a new TestChannel which contains references to the port and channel ID -// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. -func (conn *TestConnection) AddTestChannel(portID string) TestChannel { - channel := conn.NextTestChannel(portID) - conn.Channels = append(conn.Channels, channel) - return channel -} - -// NextTestChannel returns the next test channel to be created on this connection, but does not -// add it to the list of created channels. This function is expected to be used when the caller -// has not created the associated channel in app state, but would still like to refer to the -// non-existent channel usually to test for its non-existence. -// -// channel ID format: -chan -// -// The port is passed in by the caller. -func (conn *TestConnection) NextTestChannel(portID string) TestChannel { - channelID := fmt.Sprintf("%s-%s%d", conn.ID, ChannelIDPrefix, len(conn.Channels)) - return TestChannel{ - PortID: portID, - ID: channelID, - ClientID: conn.ClientID, - CounterpartyClientID: conn.CounterpartyClientID, - Version: conn.NextChannelVersion, - } -} - // FirstOrNextTestChannel returns the first test channel if it exists, otherwise it // returns the next test channel to be created. This function is expected to be used // when the caller does not know if the channel has or has not been created in app @@ -50,7 +23,13 @@ func (conn *TestConnection) FirstOrNextTestChannel(portID string) TestChannel { if len(conn.Channels) > 0 { return conn.Channels[0] } - return conn.NextTestChannel(portID) + return TestChannel{ + PortID: portID, + ID: channeltypes.FormatChannelIdentifier(0), + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } } // TestChannel is a testing helper struct to keep track of the portID and channelID From c15884a204d5980186c5d72ddee9a9f1ac9fd7e0 Mon Sep 17 00:00:00 2001 From: Aditya Date: Tue, 24 Nov 2020 15:38:24 +0000 Subject: [PATCH 50/57] Rename Version to Revision in IBC Height (#8020) * rename Version to Revision in ibc Height * lint Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- client/docs/swagger-ui/swagger.yaml | 884 +++++++++--------- proto/ibc/core/channel/v1/query.proto | 12 +- proto/ibc/core/client/v1/client.proto | 16 +- proto/ibc/core/client/v1/query.proto | 12 +- proto/ibc/core/connection/v1/query.proto | 8 +- x/ibc/applications/transfer/client/cli/tx.go | 6 +- x/ibc/core/02-client/abci_test.go | 4 +- x/ibc/core/02-client/client/utils/utils.go | 8 +- x/ibc/core/02-client/genesis.go | 4 +- x/ibc/core/02-client/keeper/client_test.go | 76 +- x/ibc/core/02-client/keeper/grpc_query.go | 4 +- .../core/02-client/keeper/grpc_query_test.go | 8 +- x/ibc/core/02-client/keeper/keeper.go | 24 +- x/ibc/core/02-client/keeper/keeper_test.go | 22 +- x/ibc/core/02-client/types/client.pb.go | 117 ++- x/ibc/core/02-client/types/genesis_test.go | 2 +- x/ibc/core/02-client/types/height.go | 106 +-- x/ibc/core/02-client/types/height_test.go | 46 +- x/ibc/core/02-client/types/msgs_test.go | 8 +- x/ibc/core/02-client/types/query.pb.go | 148 +-- x/ibc/core/02-client/types/query.pb.gw.go | 36 +- x/ibc/core/03-connection/client/cli/query.go | 4 +- .../core/03-connection/client/utils/utils.go | 6 +- x/ibc/core/03-connection/keeper/grpc_query.go | 2 +- .../03-connection/keeper/grpc_query_test.go | 16 +- .../core/03-connection/keeper/verify_test.go | 2 +- x/ibc/core/03-connection/types/query.pb.go | 154 +-- x/ibc/core/03-connection/types/query.pb.gw.go | 34 +- x/ibc/core/04-channel/client/cli/query.go | 2 +- x/ibc/core/04-channel/client/utils/utils.go | 8 +- x/ibc/core/04-channel/keeper/grpc_query.go | 2 +- .../core/04-channel/keeper/grpc_query_test.go | 24 +- .../core/04-channel/keeper/handshake_test.go | 2 +- x/ibc/core/04-channel/types/packet.go | 10 +- x/ibc/core/04-channel/types/query.pb.go | 232 ++--- x/ibc/core/04-channel/types/query.pb.gw.go | 34 +- x/ibc/core/client/query.go | 4 +- x/ibc/core/exported/client.go | 10 +- x/ibc/core/keeper/msg_server_test.go | 12 +- x/ibc/core/spec/01_concepts.md | 44 +- .../06-solomachine/types/client_state.go | 14 +- .../06-solomachine/types/header.go | 2 +- .../06-solomachine/types/misbehaviour.go | 2 +- .../06-solomachine/types/misbehaviour_test.go | 4 +- .../types/proposal_handle_test.go | 2 +- .../06-solomachine/types/solomachine_test.go | 2 +- .../07-tendermint/types/client_state.go | 4 +- .../07-tendermint/types/client_state_test.go | 2 +- .../07-tendermint/types/header.go | 4 +- .../07-tendermint/types/misbehaviour.go | 8 +- .../types/misbehaviour_handle.go | 6 +- .../types/misbehaviour_handle_test.go | 88 +- .../07-tendermint/types/misbehaviour_test.go | 40 +- .../07-tendermint/types/tendermint_test.go | 18 +- .../07-tendermint/types/update.go | 28 +- .../07-tendermint/types/update_test.go | 88 +- .../07-tendermint/types/upgrade.go | 12 +- .../07-tendermint/types/upgrade_test.go | 100 +- .../09-localhost/types/client_state.go | 8 +- .../09-localhost/types/client_state_test.go | 4 +- x/ibc/testing/chain.go | 12 +- x/ibc/testing/solomachine.go | 2 +- 62 files changed, 1291 insertions(+), 1312 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 1038e7e698..f251128768 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -16272,28 +16272,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelsResponse is the response type for the Query/Channels @@ -16628,28 +16628,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelResponse is the response type for the Query/Channel @@ -17071,28 +17071,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the @@ -17299,7 +17299,7 @@ paths: type: string tags: - Query - '/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/version/{version_number}/height/{version_height}': + '/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/{revision_number}/height/{revision_height}': get: summary: |- ChannelConsensusState queries for the consensus state for the channel @@ -17494,28 +17494,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the @@ -17720,14 +17720,14 @@ paths: in: path required: true type: string - - name: version_number - description: version number of the consensus state + - name: revision_number + description: revision number of the consensus state in: path required: true type: string format: uint64 - - name: version_height - description: version height of the consensus state + - name: revision_height + description: revision height of the consensus state in: path required: true type: string @@ -17758,28 +17758,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QuerySequenceResponse is the request type for the @@ -18061,28 +18061,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgemetsResponse is the request type for the @@ -18357,28 +18357,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketAcknowledgementResponse defines the client query @@ -18668,28 +18668,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketCommitmentsResponse is the request type for the @@ -18966,28 +18966,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedAcksResponse is the response type for the @@ -19228,28 +19228,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedPacketsResponse is the response type for the @@ -19488,28 +19488,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketCommitmentResponse defines the client query response @@ -19750,28 +19750,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketReceiptResponse defines the client query response for a @@ -20113,28 +20113,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionChannelsResponse is the Response type for the @@ -21260,28 +21260,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryClientStateResponse is the response type for the @@ -21509,28 +21509,28 @@ paths: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height - while keeping version + Normally the RevisionHeight is incremented at each + height while keeping RevisionNumber - number the same However some consensus algorithms may - choose to reset the + the same. However some consensus algorithms may choose + to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight + be monitonically increasing even as the RevisionHeight gets reset consensus_state: title: consensus state @@ -21988,7 +21988,7 @@ paths: type: boolean tags: - Query - '/ibc/core/client/v1beta1/consensus_states/{client_id}/version/{version_number}/height/{version_height}': + '/ibc/core/client/v1beta1/consensus_states/{client_id}/revision/{revision_number}/height/{revision_height}': get: summary: >- ConsensusState queries a consensus state associated with a client state @@ -22184,28 +22184,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryConsensusStateResponse is the response type for the @@ -22407,14 +22407,14 @@ paths: in: path required: true type: string - - name: version_number - description: consensus state version number + - name: revision_number + description: consensus state revision number in: path required: true type: string format: uint64 - - name: version_height - description: consensus state version height + - name: revision_height + description: consensus state revision height in: path required: true type: string @@ -22455,28 +22455,28 @@ paths: title: height at which the proof was generated type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryClientConnectionsResponse is the response type for the @@ -22796,28 +22796,28 @@ paths: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionsResponse is the response type for the @@ -23154,28 +23154,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionResponse is the response type for the @@ -23590,28 +23590,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionClientStateResponse is the response type for the @@ -23813,7 +23813,7 @@ paths: type: string tags: - Query - '/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/version/{version_number}/height/{version_height}': + '/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/revision/{revision_number}/height/{revision_height}': get: summary: |- ConnectionConsensusState queries the consensus state associated with the @@ -24008,28 +24008,28 @@ paths: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height + while keeping RevisionNumber - number the same However some consensus algorithms may choose - to reset the + the same. However some consensus algorithms may choose to + reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionConsensusStateResponse is the response type for the @@ -24229,12 +24229,12 @@ paths: in: path required: true type: string - - name: version_number + - name: revision_number in: path required: true type: string format: uint64 - - name: version_height + - name: revision_height in: path required: true type: string @@ -32360,28 +32360,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method @@ -32559,28 +32558,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryChannelClientStateResponse is the Response type for the Query/QueryChannelClientState RPC method @@ -32664,28 +32662,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelResponse is the response type for the Query/Channel RPC method. @@ -32801,28 +32798,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryChannelsResponse is the response type for the Query/Channels RPC method. @@ -32934,28 +32930,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionChannelsResponse is the Response type for the Query/QueryConnectionChannels RPC method @@ -32974,28 +32969,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QuerySequenceResponse is the request type for the Query/QueryNextSequenceReceiveResponse RPC method @@ -33014,28 +33008,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgementResponse defines the client query response for a packet which also includes a proof and the height from which the @@ -33101,28 +33094,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketAcknowledgemetsResponse is the request type for the Query/QueryPacketAcknowledgements RPC method @@ -33141,28 +33133,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketCommitmentResponse defines the client query response for a packet @@ -33231,28 +33222,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryPacketCommitmentsResponse is the request type for the Query/QueryPacketCommitments RPC method @@ -33270,28 +33260,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryPacketReceiptResponse defines the client query response for a packet receipt @@ -33312,28 +33301,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedAcksResponse is the response type for the Query/UnreceivedAcks RPC method @@ -33350,28 +33338,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryUnreceivedPacketsResponse is the response type for the Query/UnreceivedPacketCommitments RPC method @@ -33398,27 +33385,27 @@ definitions: ibc.core.client.v1.Height: type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while keeping + RevisionNumber - number the same However some consensus algorithms may choose to reset the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height continues + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- Height is a monotonically increasing data type @@ -33602,28 +33589,27 @@ definitions: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset consensus_state: title: consensus state type: object @@ -33982,28 +33968,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryClientStateResponse is the response type for the Query/ClientState RPC @@ -34402,28 +34387,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: >- QueryConsensusStateResponse is the response type for the Query/ConsensusState @@ -34441,28 +34425,29 @@ definitions: title: consensus state height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while - keeping version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to - reset the + the same. However some consensus algorithms may choose to reset + the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets + reset consensus_state: title: consensus state type: object @@ -34858,28 +34843,27 @@ definitions: title: height at which the proof was generated type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryClientConnectionsResponse is the response type for the Query/ClientConnections RPC method @@ -35070,28 +35054,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionClientStateResponse is the response type for the Query/ConnectionClientState RPC method @@ -35269,28 +35252,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset title: |- QueryConnectionConsensusStateResponse is the response type for the Query/ConnectionConsensusState RPC method @@ -35377,28 +35359,27 @@ definitions: title: height at which the proof was retrieved type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionResponse is the response type for the Query/Connection RPC @@ -35511,28 +35492,27 @@ definitions: title: query block height type: object properties: - version_number: + revision_number: type: string format: uint64 - title: the version that the client is currently on - version_height: + title: the revision that the client is currently on + revision_height: type: string format: uint64 - title: the height within the given version + title: the height within the given revision description: >- - Normally the VersionHeight is incremented at each height while keeping - version + Normally the RevisionHeight is incremented at each height while + keeping RevisionNumber - number the same However some consensus algorithms may choose to reset - the + the same. However some consensus algorithms may choose to reset the height in certain conditions e.g. hard forks, state-machine breaking changes - In these cases, the version number is incremented so that height + In these cases, the RevisionNumber is incremented so that height continues to - be monitonically increasing even as the VersionHeight gets reset + be monitonically increasing even as the RevisionHeight gets reset description: >- QueryConnectionsResponse is the response type for the Query/Connections RPC diff --git a/proto/ibc/core/channel/v1/query.proto b/proto/ibc/core/channel/v1/query.proto index 4121096240..d9e3ceb8a6 100644 --- a/proto/ibc/core/channel/v1/query.proto +++ b/proto/ibc/core/channel/v1/query.proto @@ -38,8 +38,8 @@ service Query { // associated with the provided channel identifiers. rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { option (google.api.http).get = - "/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/version/" - "{version_number}/height/{version_height}"; + "/ibc/core/channel/v1beta1/channels/{channel_id}/ports/{port_id}/consensus_state/revision/" + "{revision_number}/height/{revision_height}"; } // PacketCommitment queries a stored packet commitment hash. @@ -176,10 +176,10 @@ message QueryChannelConsensusStateRequest { string port_id = 1; // channel unique identifier string channel_id = 2; - // version number of the consensus state - uint64 version_number = 3; - // version height of the consensus state - uint64 version_height = 4; + // revision number of the consensus state + uint64 revision_number = 3; + // revision height of the consensus state + uint64 revision_height = 4; } // QueryChannelClientStateResponse is the Response type for the diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index a5d2b0f19e..11d2195aaf 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -52,19 +52,19 @@ message ClientUpdateProposal { // that can be compared against another Height for the purposes of updating and // freezing clients // -// Normally the VersionHeight is incremented at each height while keeping version -// number the same However some consensus algorithms may choose to reset the +// Normally the RevisionHeight is incremented at each height while keeping RevisionNumber +// the same. However some consensus algorithms may choose to reset the // height in certain conditions e.g. hard forks, state-machine breaking changes -// In these cases, the version number is incremented so that height continues to -// be monitonically increasing even as the VersionHeight gets reset +// In these cases, the RevisionNumber is incremented so that height continues to +// be monitonically increasing even as the RevisionHeight gets reset message Height { option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; - // the version that the client is currently on - uint64 version_number = 1 [(gogoproto.moretags) = "yaml:\"version_number\""]; - // the height within the given version - uint64 version_height = 2 [(gogoproto.moretags) = "yaml:\"version_height\""]; + // the revision that the client is currently on + uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; + // the height within the given revision + uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; } // Params defines the set of IBC light client parameters. diff --git a/proto/ibc/core/client/v1/query.proto b/proto/ibc/core/client/v1/query.proto index 7a1bf50538..97f3acd627 100644 --- a/proto/ibc/core/client/v1/query.proto +++ b/proto/ibc/core/client/v1/query.proto @@ -24,8 +24,8 @@ service Query { // ConsensusState queries a consensus state associated with a client state at // a given height. rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1beta1/consensus_states/{client_id}/version/{version_number}/" - "height/{version_height}"; + option (google.api.http).get = "/ibc/core/client/v1beta1/consensus_states/{client_id}/revision/{revision_number}/" + "height/{revision_height}"; } // ConsensusStates queries all the consensus state associated with a given @@ -82,10 +82,10 @@ message QueryClientStatesResponse { message QueryConsensusStateRequest { // client identifier string client_id = 1; - // consensus state version number - uint64 version_number = 2; - // consensus state version height - uint64 version_height = 3; + // consensus state revision number + uint64 revision_number = 2; + // consensus state revision height + uint64 revision_height = 3; // latest_height overrrides the height field and queries the latest stored // ConsensusState bool latest_height = 4; diff --git a/proto/ibc/core/connection/v1/query.proto b/proto/ibc/core/connection/v1/query.proto index 9e5b068804..c5085a131f 100644 --- a/proto/ibc/core/connection/v1/query.proto +++ b/proto/ibc/core/connection/v1/query.proto @@ -38,7 +38,7 @@ service Query { // connection. rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { option (google.api.http).get = "/ibc/core/connection/v1beta1/connections/{connection_id}/consensus_state/" - "version/{version_number}/height/{version_height}"; + "revision/{revision_number}/height/{revision_height}"; } } @@ -118,9 +118,9 @@ message QueryConnectionClientStateResponse { // Query/ConnectionConsensusState RPC method message QueryConnectionConsensusStateRequest { // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - uint64 version_number = 2; - uint64 version_height = 3; + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + uint64 revision_number = 2; + uint64 revision_height = 3; } // QueryConnectionConsensusStateResponse is the response type for the diff --git a/x/ibc/applications/transfer/client/cli/tx.go b/x/ibc/applications/transfer/client/cli/tx.go index 7f43c97777..1c4fa4e613 100644 --- a/x/ibc/applications/transfer/client/cli/tx.go +++ b/x/ibc/applications/transfer/client/cli/tx.go @@ -29,7 +29,7 @@ func NewTransferTxCmd() *cobra.Command { Short: "Transfer a fungible token through IBC", Long: strings.TrimSpace(`Transfer a fungible token through IBC. Timeouts can be specified as absolute or relative using the "absolute-timeouts" flag. Timeout height can be set by passing in the height string -in the form {version}-{height} using the "packet-timeout-height" flag. Relative timeouts are added to +in the form {revision}-{height} using the "packet-timeout-height" flag. Relative timeouts are added to the block height and block timestamp queried from the latest consensus state corresponding to the counterparty channel. Any timeout set to 0 is disabled.`), Example: fmt.Sprintf("%s tx ibc-transfer transfer [src-port] [src-channel] [receiver] [amount]", version.AppName), @@ -85,8 +85,8 @@ to the counterparty channel. Any timeout set to 0 is disabled.`), if !timeoutHeight.IsZero() { absoluteHeight := height - absoluteHeight.VersionNumber += timeoutHeight.VersionNumber - absoluteHeight.VersionHeight += timeoutHeight.VersionHeight + absoluteHeight.RevisionNumber += timeoutHeight.RevisionNumber + absoluteHeight.RevisionHeight += timeoutHeight.RevisionHeight timeoutHeight = absoluteHeight } diff --git a/x/ibc/core/02-client/abci_test.go b/x/ibc/core/02-client/abci_test.go index fe9016750f..3a296618b3 100644 --- a/x/ibc/core/02-client/abci_test.go +++ b/x/ibc/core/02-client/abci_test.go @@ -28,9 +28,9 @@ func (suite *ClientTestSuite) SetupTest() { suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1)) // set localhost client - version := types.ParseChainID(suite.chainA.GetContext().ChainID()) + revision := types.ParseChainID(suite.chainA.GetContext().ChainID()) localHostClient := localhosttypes.NewClientState( - suite.chainA.GetContext().ChainID(), types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight())), + suite.chainA.GetContext().ChainID(), types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), ) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) } diff --git a/x/ibc/core/02-client/client/utils/utils.go b/x/ibc/core/02-client/client/utils/utils.go index 200f6423fd..1a7bc003bc 100644 --- a/x/ibc/core/02-client/client/utils/utils.go +++ b/x/ibc/core/02-client/client/utils/utils.go @@ -77,10 +77,10 @@ func QueryConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryConsensusStateRequest{ - ClientId: clientID, - VersionNumber: height.GetVersionNumber(), - VersionHeight: height.GetVersionHeight(), - LatestHeight: latestHeight, + ClientId: clientID, + RevisionNumber: height.GetRevisionNumber(), + RevisionHeight: height.GetRevisionHeight(), + LatestHeight: latestHeight, } return queryClient.ConsensusState(context.Background(), req) diff --git a/x/ibc/core/02-client/genesis.go b/x/ibc/core/02-client/genesis.go index 988e297c18..ef00930f0b 100644 --- a/x/ibc/core/02-client/genesis.go +++ b/x/ibc/core/02-client/genesis.go @@ -50,9 +50,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { } // client id is always "localhost" - version := types.ParseChainID(ctx.ChainID()) + revision := types.ParseChainID(ctx.ChainID()) clientState := localhosttypes.NewClientState( - ctx.ChainID(), types.NewHeight(version, uint64(ctx.BlockHeight())), + ctx.ChainID(), types.NewHeight(revision, uint64(ctx.BlockHeight())), ) if err := clientState.Validate(); err != nil { diff --git a/x/ibc/core/02-client/keeper/client_test.go b/x/ibc/core/02-client/keeper/client_test.go index 8da8ac90b8..736a34d1e4 100644 --- a/x/ibc/core/02-client/keeper/client_test.go +++ b/x/ibc/core/02-client/keeper/client_test.go @@ -56,17 +56,17 @@ func (suite *KeeperTestSuite) TestCreateClient() { func (suite *KeeperTestSuite) TestUpdateClientTendermint() { // Must create header creation functions since suite.header gets recreated on each test case createFutureUpdateFn := func(s *KeeperTestSuite) *ibctmtypes.Header { - heightPlus3 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()+3) + heightPlus3 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()+3) height := suite.header.GetHeight().(clienttypes.Height) - return suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus3.VersionHeight), height, suite.header.Header.Time.Add(time.Hour), + return suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus3.RevisionHeight), height, suite.header.Header.Time.Add(time.Hour), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } createPastUpdateFn := func(s *KeeperTestSuite) *ibctmtypes.Header { - heightMinus2 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()-2) - heightMinus4 := clienttypes.NewHeight(suite.header.GetHeight().GetVersionNumber(), suite.header.GetHeight().GetVersionHeight()-4) + heightMinus2 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()-2) + heightMinus4 := clienttypes.NewHeight(suite.header.GetHeight().GetRevisionNumber(), suite.header.GetHeight().GetRevisionHeight()-4) - return suite.chainA.CreateTMClientHeader(testChainID, int64(heightMinus2.VersionHeight), heightMinus4, suite.header.Header.Time, + return suite.chainA.CreateTMClientHeader(testChainID, int64(heightMinus2.RevisionHeight), heightMinus4, suite.header.Header.Time, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) } var ( @@ -146,7 +146,7 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { }, false}, {"valid past update before client was frozen", func() error { clientState = ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) - clientState.FrozenHeight = types.NewHeight(0, testClientHeight.VersionHeight-1) + clientState.FrozenHeight = types.NewHeight(0, testClientHeight.RevisionHeight-1) err := suite.keeper.CreateClient(suite.ctx, testClientID, clientState, suite.consensusState) suite.Require().NoError(err) @@ -221,8 +221,8 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() { } func (suite *KeeperTestSuite) TestUpdateClientLocalhost() { - version := types.ParseChainID(suite.chainA.ChainID) - var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight()))) + revision := types.ParseChainID(suite.chainA.ChainID) + var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight()))) ctx := suite.chainA.GetContext().WithBlockHeight(suite.chainA.GetContext().BlockHeight() + 1) err := suite.chainA.App.IBCKeeper.ClientKeeper.UpdateClient(ctx, exported.Localhost, nil) @@ -260,8 +260,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -272,8 +272,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: true, }, @@ -290,8 +290,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -302,8 +302,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) clientA = "wrongclientid" }, @@ -322,8 +322,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -334,8 +334,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // set frozen client in store tmClient, ok := cs.(*ibctmtypes.ClientState) @@ -358,8 +358,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = ibctmtypes.NewClientState("wrongchainID", ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, true, true) @@ -371,8 +371,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -435,8 +435,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusting period misbehavior should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -451,8 +451,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ClientId: testClientID, }, func() error { @@ -477,8 +477,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehavior at later height with different trusted heights should pass", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -503,8 +503,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState1 not found", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, valSet, bothSigners), ClientId: testClientID, }, func() error { @@ -519,8 +519,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "trusted ConsensusState2 not found", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.VersionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), testClientHeight, altTime, bothValSet, valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(heightPlus5.RevisionHeight), heightPlus3, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -541,8 +541,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "client already frozen at earlier height", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), bothValSet, bothValSet, bothSigners), ClientId: testClientID, }, func() error { @@ -560,8 +560,8 @@ func (suite *KeeperTestSuite) TestCheckMisbehaviourAndUpdateState() { { "misbehaviour check failed", &ibctmtypes.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, altTime, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeight, suite.ctx.BlockTime(), altValSet, bothValSet, altSigners), ClientId: testClientID, }, func() error { diff --git a/x/ibc/core/02-client/keeper/grpc_query.go b/x/ibc/core/02-client/keeper/grpc_query.go index 9f4bb6c808..f14507d8ce 100644 --- a/x/ibc/core/02-client/keeper/grpc_query.go +++ b/x/ibc/core/02-client/keeper/grpc_query.go @@ -112,11 +112,11 @@ func (q Keeper) ConsensusState(c context.Context, req *types.QueryConsensusState found bool ) - height := types.NewHeight(req.VersionNumber, req.VersionHeight) + height := types.NewHeight(req.RevisionNumber, req.RevisionHeight) if req.LatestHeight { consensusState, found = q.GetLatestClientConsensusState(ctx, req.ClientId) } else { - if req.VersionHeight == 0 { + if req.RevisionHeight == 0 { return nil, status.Error(codes.InvalidArgument, "consensus state height cannot be 0") } diff --git a/x/ibc/core/02-client/keeper/grpc_query_test.go b/x/ibc/core/02-client/keeper/grpc_query_test.go index a252005fc9..d8125198e2 100644 --- a/x/ibc/core/02-client/keeper/grpc_query_test.go +++ b/x/ibc/core/02-client/keeper/grpc_query_test.go @@ -184,8 +184,8 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { func() { req = &types.QueryConsensusStateRequest{ ClientId: testClientID, - VersionNumber: 0, - VersionHeight: 0, + RevisionNumber: 0, + RevisionHeight: 0, LatestHeight: false, } }, @@ -236,8 +236,8 @@ func (suite *KeeperTestSuite) TestQueryConsensusState() { req = &types.QueryConsensusStateRequest{ ClientId: testClientID, - VersionNumber: 0, - VersionHeight: height, + RevisionNumber: 0, + RevisionHeight: height, } }, true, diff --git a/x/ibc/core/02-client/keeper/keeper.go b/x/ibc/core/02-client/keeper/keeper.go index cd39dba941..accf48bb14 100644 --- a/x/ibc/core/02-client/keeper/keeper.go +++ b/x/ibc/core/02-client/keeper/keeper.go @@ -167,18 +167,18 @@ func (k Keeper) GetLatestClientConsensusState(ctx sdk.Context, clientID string) // GetSelfConsensusState introspects the (self) past historical info at a given height // and returns the expected consensus state at that height. -// For now, can only retrieve self consensus states for the current version +// For now, can only retrieve self consensus states for the current revision func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, bool) { selfHeight, ok := height.(types.Height) if !ok { return nil, false } - // check that height version matches chainID version - version := types.ParseChainID(ctx.ChainID()) - if version != height.GetVersionNumber() { + // check that height revision matches chainID revision + revision := types.ParseChainID(ctx.ChainID()) + if revision != height.GetRevisionNumber() { return nil, false } - histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(selfHeight.VersionHeight)) + histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, int64(selfHeight.RevisionHeight)) if !found { return nil, false } @@ -193,7 +193,7 @@ func (k Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) ( // ValidateSelfClient validates the client parameters for a client of the running chain // This function is only used to validate the client state the counterparty stores for this chain -// Client must be in same version as the executing chain +// Client must be in same revision as the executing chain func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error { tmClient, ok := clientState.(*ibctmtypes.ClientState) if !ok { @@ -210,15 +210,15 @@ func (k Keeper) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientS ctx.ChainID(), tmClient.ChainId) } - version := types.ParseChainID(ctx.ChainID()) + revision := types.ParseChainID(ctx.ChainID()) - // client must be in the same version as executing chain - if tmClient.LatestHeight.VersionNumber != version { - return sdkerrors.Wrapf(types.ErrInvalidClient, "client is not in the same version as the chain. expected version: %d, got: %d", - tmClient.LatestHeight.VersionNumber, version) + // client must be in the same revision as executing chain + if tmClient.LatestHeight.RevisionNumber != revision { + return sdkerrors.Wrapf(types.ErrInvalidClient, "client is not in the same revision as the chain. expected revision: %d, got: %d", + tmClient.LatestHeight.RevisionNumber, revision) } - selfHeight := types.NewHeight(version, uint64(ctx.BlockHeight())) + selfHeight := types.NewHeight(revision, uint64(ctx.BlockHeight())) if tmClient.LatestHeight.GTE(selfHeight) { return sdkerrors.Wrapf(types.ErrInvalidClient, "client has LatestHeight %d greater than or equal to chain height %d", tmClient.LatestHeight, selfHeight) diff --git a/x/ibc/core/02-client/keeper/keeper_test.go b/x/ibc/core/02-client/keeper/keeper_test.go index 61396655a3..45ff4f674e 100644 --- a/x/ibc/core/02-client/keeper/keeper_test.go +++ b/x/ibc/core/02-client/keeper/keeper_test.go @@ -27,8 +27,8 @@ import ( ) const ( - testChainID = "gaiahub-0" - testChainIDVersion1 = "gaiahub-1" + testChainID = "gaiahub-0" + testChainIDRevision1 = "gaiahub-1" testClientID = "gaiachain" testClientID2 = "ethbridge" @@ -42,9 +42,9 @@ const ( ) var ( - testClientHeight = types.NewHeight(0, 5) - testClientHeightVersion1 = types.NewHeight(1, 5) - newClientHeight = types.NewHeight(1, 1) + testClientHeight = types.NewHeight(0, 5) + testClientHeightRevision1 = types.NewHeight(1, 5) + newClientHeight = types.NewHeight(1, 1) ) type KeeperTestSuite struct { @@ -94,7 +94,7 @@ func (suite *KeeperTestSuite) SetupTest() { validator := tmtypes.NewValidator(pubKey, 1) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) suite.valSetHash = suite.valSet.Hash() - suite.header = suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.VersionHeight), testClientHeightMinus1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = suite.chainA.CreateTMClientHeader(testChainID, int64(testClientHeight.RevisionHeight), testClientHeightMinus1, now2, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.consensusState = ibctmtypes.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot([]byte("hash")), suite.valSetHash) var validators stakingtypes.Validators @@ -116,9 +116,9 @@ func (suite *KeeperTestSuite) SetupTest() { } // add localhost client - version := types.ParseChainID(suite.chainA.ChainID) + revision := types.ParseChainID(suite.chainA.ChainID) localHostClient := localhosttypes.NewClientState( - suite.chainA.ChainID, types.NewHeight(version, uint64(suite.chainA.GetContext().BlockHeight())), + suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())), ) suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient) @@ -190,8 +190,8 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() { false, }, { - "invalid client version", - ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightVersion1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), + "invalid client revision", + ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightRevision1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), false, }, { @@ -295,7 +295,7 @@ func (suite KeeperTestSuite) TestConsensusStateHelpers() { testClientHeightPlus5 := types.NewHeight(0, height+5) - header := suite.chainA.CreateTMClientHeader(testClientID, int64(testClientHeightPlus5.VersionHeight), testClientHeight, suite.header.Header.Time.Add(time.Minute), + header := suite.chainA.CreateTMClientHeader(testClientID, int64(testClientHeightPlus5.RevisionHeight), testClientHeight, suite.header.Header.Time.Add(time.Minute), suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) // mock update functionality diff --git a/x/ibc/core/02-client/types/client.pb.go b/x/ibc/core/02-client/types/client.pb.go index 95fc58c339..f6233435ca 100644 --- a/x/ibc/core/02-client/types/client.pb.go +++ b/x/ibc/core/02-client/types/client.pb.go @@ -242,16 +242,16 @@ var xxx_messageInfo_ClientUpdateProposal proto.InternalMessageInfo // that can be compared against another Height for the purposes of updating and // freezing clients // -// Normally the VersionHeight is incremented at each height while keeping version -// number the same However some consensus algorithms may choose to reset the +// Normally the RevisionHeight is incremented at each height while keeping RevisionNumber +// the same. However some consensus algorithms may choose to reset the // height in certain conditions e.g. hard forks, state-machine breaking changes -// In these cases, the version number is incremented so that height continues to -// be monitonically increasing even as the VersionHeight gets reset +// In these cases, the RevisionNumber is incremented so that height continues to +// be monitonically increasing even as the RevisionHeight gets reset type Height struct { - // the version that the client is currently on - VersionNumber uint64 `protobuf:"varint,1,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty" yaml:"version_number"` - // the height within the given version - VersionHeight uint64 `protobuf:"varint,2,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty" yaml:"version_height"` + // the revision that the client is currently on + RevisionNumber uint64 `protobuf:"varint,1,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty" yaml:"revision_number"` + // the height within the given revision + RevisionHeight uint64 `protobuf:"varint,2,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty" yaml:"revision_height"` } func (m *Height) Reset() { *m = Height{} } @@ -344,44 +344,43 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 579 bytes of a gzipped FileDescriptorProto + // 574 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0xbd, 0x8e, 0xd3, 0x4c, - 0x14, 0xcd, 0x6c, 0xf2, 0x45, 0x9b, 0xc9, 0x47, 0xb2, 0x32, 0x09, 0xeb, 0x4d, 0x61, 0x47, 0x53, - 0xa5, 0xd8, 0xb5, 0x49, 0x28, 0x40, 0xa9, 0xc0, 0x69, 0xd8, 0x02, 0x14, 0x8c, 0x10, 0x88, 0x26, - 0xf2, 0xcf, 0xac, 0x33, 0xc2, 0xf1, 0x44, 0x9e, 0x49, 0xd8, 0xbc, 0x01, 0x25, 0x15, 0xa2, 0xa0, - 0xe0, 0x09, 0xe8, 0x78, 0x03, 0x8a, 0x2d, 0xb7, 0xa4, 0xb2, 0x50, 0xf2, 0x06, 0x79, 0x02, 0x64, - 0xcf, 0xec, 0x66, 0x1d, 0x88, 0xb4, 0xa2, 0xf2, 0x9d, 0x7b, 0xaf, 0xcf, 0x3d, 0xe7, 0xdc, 0xd1, - 0x40, 0x9d, 0xb8, 0x9e, 0xe9, 0xd1, 0x18, 0x9b, 0x5e, 0x48, 0x70, 0xc4, 0xcd, 0x79, 0x57, 0x46, - 0xc6, 0x34, 0xa6, 0x9c, 0x2a, 0x0a, 0x71, 0x3d, 0x23, 0x6d, 0x30, 0x64, 0x7a, 0xde, 0x6d, 0x35, - 0x02, 0x1a, 0xd0, 0xac, 0x6c, 0xa6, 0x91, 0xe8, 0x6c, 0x1d, 0x05, 0x94, 0x06, 0x21, 0x36, 0xb3, - 0x93, 0x3b, 0x3b, 0x33, 0x9d, 0x68, 0x21, 0x4a, 0xe8, 0x0b, 0x80, 0xcd, 0x53, 0x1f, 0x47, 0x9c, - 0x9c, 0x11, 0xec, 0x0f, 0x32, 0xa0, 0x97, 0xdc, 0xe1, 0x58, 0xe9, 0xc2, 0x8a, 0xc0, 0x1d, 0x11, - 0x5f, 0x05, 0x6d, 0xd0, 0xa9, 0x58, 0x8d, 0x75, 0xa2, 0x1f, 0x2c, 0x9c, 0x49, 0xd8, 0x47, 0xd7, - 0x25, 0x64, 0xef, 0x8b, 0xf8, 0xd4, 0x57, 0x86, 0xf0, 0x7f, 0x99, 0x67, 0x29, 0x84, 0xba, 0xd7, - 0x06, 0x9d, 0x6a, 0xaf, 0x61, 0x88, 0xf1, 0xc6, 0xd5, 0x78, 0xe3, 0x49, 0xb4, 0xb0, 0x0e, 0xd7, - 0x89, 0x7e, 0x37, 0x87, 0x95, 0xfd, 0x83, 0xec, 0xaa, 0xb7, 0x21, 0x81, 0xbe, 0x01, 0xa8, 0x0e, - 0x68, 0xc4, 0x70, 0xc4, 0x66, 0x2c, 0x4b, 0xbd, 0x26, 0x7c, 0xfc, 0x14, 0x93, 0x60, 0xcc, 0x95, - 0x47, 0xb0, 0x3c, 0xce, 0xa2, 0x8c, 0x5e, 0xb5, 0xd7, 0x32, 0xfe, 0x74, 0xc4, 0x10, 0xbd, 0x56, - 0xe9, 0x22, 0xd1, 0x0b, 0xb6, 0xec, 0x57, 0xde, 0xc0, 0xba, 0x77, 0x85, 0x7a, 0x0b, 0xae, 0x47, - 0xeb, 0x44, 0x6f, 0xa6, 0x5c, 0xd1, 0xd6, 0x5f, 0xc8, 0xae, 0x79, 0x39, 0x76, 0xe8, 0x07, 0x80, - 0x4d, 0xe1, 0x62, 0x9e, 0x36, 0xfb, 0x17, 0x3f, 0xcf, 0xe1, 0xc1, 0xd6, 0x40, 0xa6, 0xee, 0xb5, - 0x8b, 0x9d, 0x6a, 0xef, 0xf8, 0x6f, 0x52, 0x77, 0x19, 0x65, 0xe9, 0xa9, 0xf8, 0x75, 0xa2, 0x1f, - 0xca, 0x59, 0x5b, 0x98, 0xc8, 0xae, 0xe7, 0x55, 0x30, 0xf4, 0x1d, 0xc0, 0x86, 0x90, 0xf1, 0x6a, - 0xea, 0x3b, 0x1c, 0x0f, 0x63, 0x3a, 0xa5, 0xcc, 0x09, 0x95, 0x06, 0xfc, 0x8f, 0x13, 0x1e, 0x62, - 0xa1, 0xc0, 0x16, 0x07, 0xa5, 0x0d, 0xab, 0x3e, 0x66, 0x5e, 0x4c, 0xa6, 0x9c, 0xd0, 0x28, 0xf3, - 0xb2, 0x62, 0xdf, 0x4c, 0xe5, 0xd5, 0x17, 0x6f, 0xa5, 0xfe, 0x38, 0x5d, 0xaf, 0xe3, 0xe3, 0x58, - 0x2d, 0xed, 0xde, 0x8d, 0x2d, 0x7b, 0xfa, 0xa5, 0x0f, 0x5f, 0xf5, 0x02, 0xfa, 0x04, 0x60, 0x59, - 0xde, 0x8e, 0xc7, 0xb0, 0x36, 0xc7, 0x31, 0x23, 0x34, 0x1a, 0x45, 0xb3, 0x89, 0x8b, 0xe3, 0x8c, - 0x72, 0x69, 0xb3, 0xcc, 0x3e, 0xca, 0xd7, 0x91, 0x7d, 0x47, 0x26, 0x9e, 0x67, 0xe7, 0x9b, 0x08, - 0xf2, 0x9e, 0xed, 0xed, 0x42, 0x10, 0xf5, 0x0d, 0x82, 0xe0, 0xd0, 0xdf, 0x4f, 0x49, 0x7d, 0x4e, - 0x89, 0x3d, 0x83, 0xe5, 0xa1, 0x13, 0x3b, 0x13, 0xa6, 0x0c, 0x60, 0xdd, 0x09, 0x43, 0xfa, 0x1e, - 0xfb, 0x23, 0x21, 0x95, 0xa9, 0xa0, 0x5d, 0xec, 0x54, 0xac, 0xd6, 0x3a, 0xd1, 0xef, 0x09, 0xd8, - 0xad, 0x06, 0x64, 0xd7, 0x64, 0x46, 0xec, 0x84, 0x59, 0x2f, 0x2e, 0x96, 0x1a, 0xb8, 0x5c, 0x6a, - 0xe0, 0xd7, 0x52, 0x03, 0x1f, 0x57, 0x5a, 0xe1, 0x72, 0xa5, 0x15, 0x7e, 0xae, 0xb4, 0xc2, 0xdb, - 0x87, 0x01, 0xe1, 0xe3, 0x99, 0x6b, 0x78, 0x74, 0x62, 0x7a, 0x94, 0x4d, 0x28, 0x93, 0x9f, 0x13, - 0xe6, 0xbf, 0x33, 0xcf, 0xcd, 0xeb, 0x57, 0xe5, 0x7e, 0xef, 0x44, 0x3e, 0x2c, 0x7c, 0x31, 0xc5, - 0xcc, 0x2d, 0x67, 0xb6, 0x3e, 0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x91, 0xd2, 0x2f, 0x3f, 0x78, - 0x04, 0x00, 0x00, + 0x14, 0x8d, 0x93, 0x7c, 0xd1, 0x66, 0xf2, 0x29, 0x59, 0x99, 0x84, 0xf5, 0xa6, 0xb0, 0xa3, 0xa9, + 0x52, 0xec, 0xda, 0x24, 0x14, 0xa0, 0x74, 0x38, 0x0d, 0x5b, 0x80, 0x82, 0x11, 0x02, 0xd1, 0x44, + 0xfe, 0x99, 0x75, 0x46, 0x38, 0x9e, 0xc8, 0x33, 0x09, 0x9b, 0x37, 0xa0, 0xa4, 0xa4, 0xa0, 0xe0, + 0x09, 0xe8, 0x78, 0x03, 0x8a, 0x2d, 0xb7, 0xa4, 0xb2, 0x50, 0xf2, 0x06, 0x79, 0x02, 0xe4, 0x99, + 0xc9, 0x12, 0x07, 0x22, 0xad, 0xa8, 0x7c, 0x7d, 0xe6, 0xcc, 0xb9, 0xe7, 0xdc, 0x19, 0x0d, 0x30, + 0xb0, 0xe7, 0x5b, 0x3e, 0x49, 0x90, 0xe5, 0x47, 0x18, 0xc5, 0xcc, 0x5a, 0xf4, 0x64, 0x65, 0xce, + 0x12, 0xc2, 0x88, 0xaa, 0x62, 0xcf, 0x37, 0x33, 0x82, 0x29, 0xe1, 0x45, 0xaf, 0xdd, 0x0c, 0x49, + 0x48, 0xf8, 0xb2, 0x95, 0x55, 0x82, 0xd9, 0x3e, 0x0d, 0x09, 0x09, 0x23, 0x64, 0xf1, 0x3f, 0x6f, + 0x7e, 0x69, 0xb9, 0xf1, 0x52, 0x2c, 0xc1, 0xcf, 0x0a, 0x68, 0x5d, 0x04, 0x28, 0x66, 0xf8, 0x12, + 0xa3, 0x60, 0xc8, 0x85, 0x5e, 0x32, 0x97, 0x21, 0xb5, 0x07, 0xaa, 0x42, 0x77, 0x8c, 0x03, 0x4d, + 0xe9, 0x28, 0xdd, 0xaa, 0xdd, 0xdc, 0xa4, 0xc6, 0xf1, 0xd2, 0x9d, 0x46, 0x03, 0x78, 0xbb, 0x04, + 0x9d, 0x23, 0x51, 0x5f, 0x04, 0xea, 0x08, 0xfc, 0x2f, 0x71, 0x9a, 0x49, 0x68, 0xc5, 0x8e, 0xd2, + 0xad, 0xf5, 0x9b, 0xa6, 0x68, 0x6f, 0x6e, 0xdb, 0x9b, 0x4f, 0xe2, 0xa5, 0x7d, 0xb2, 0x49, 0x8d, + 0x7b, 0x39, 0x2d, 0xbe, 0x07, 0x3a, 0x35, 0xff, 0xb7, 0x09, 0xf8, 0x55, 0x01, 0xda, 0x90, 0xc4, + 0x14, 0xc5, 0x74, 0x4e, 0x39, 0xf4, 0x1a, 0xb3, 0xc9, 0x53, 0x84, 0xc3, 0x09, 0x53, 0x1f, 0x83, + 0xca, 0x84, 0x57, 0xdc, 0x5e, 0xad, 0xdf, 0x36, 0xff, 0x9c, 0x88, 0x29, 0xb8, 0x76, 0xf9, 0x3a, + 0x35, 0x0a, 0x8e, 0xe4, 0xab, 0x6f, 0x40, 0xc3, 0xdf, 0xaa, 0xde, 0xc1, 0xeb, 0xe9, 0x26, 0x35, + 0x5a, 0x99, 0x57, 0xb8, 0xb7, 0x0b, 0x3a, 0x75, 0x3f, 0xe7, 0x0e, 0x7e, 0x57, 0x40, 0x4b, 0x4c, + 0x31, 0x6f, 0x9b, 0xfe, 0xcb, 0x3c, 0xaf, 0xc0, 0xf1, 0x5e, 0x43, 0xaa, 0x15, 0x3b, 0xa5, 0x6e, + 0xad, 0x7f, 0xf6, 0xb7, 0xa8, 0x87, 0x06, 0x65, 0x1b, 0x59, 0xf8, 0x4d, 0x6a, 0x9c, 0xc8, 0x5e, + 0x7b, 0x9a, 0xd0, 0x69, 0xe4, 0x53, 0x50, 0xf8, 0x4d, 0x01, 0x4d, 0x11, 0xe3, 0xd5, 0x2c, 0x70, + 0x19, 0x1a, 0x25, 0x64, 0x46, 0xa8, 0x1b, 0xa9, 0x4d, 0xf0, 0x1f, 0xc3, 0x2c, 0x42, 0x22, 0x81, + 0x23, 0x7e, 0xd4, 0x0e, 0xa8, 0x05, 0x88, 0xfa, 0x09, 0x9e, 0x31, 0x4c, 0x62, 0x3e, 0xcb, 0xaa, + 0xb3, 0x0b, 0xe5, 0xd3, 0x97, 0xee, 0x94, 0xfe, 0x2c, 0x3b, 0x5e, 0x37, 0x40, 0x89, 0x56, 0x3e, + 0x7c, 0x36, 0x8e, 0xe4, 0x0c, 0xca, 0x1f, 0xbe, 0x18, 0x85, 0xec, 0x3a, 0x57, 0xe4, 0xed, 0x18, + 0x82, 0x46, 0x82, 0x16, 0x98, 0x62, 0x12, 0x8f, 0xe3, 0xf9, 0xd4, 0x43, 0x09, 0xf7, 0x5c, 0xb6, + 0xdb, 0x9b, 0xd4, 0xb8, 0x2f, 0xfa, 0xee, 0x11, 0xa0, 0x53, 0xdf, 0x22, 0xcf, 0x39, 0x90, 0x13, + 0x91, 0x77, 0xad, 0x78, 0x50, 0x44, 0x10, 0x76, 0x44, 0x84, 0x93, 0xc1, 0x51, 0x66, 0xed, 0x53, + 0x66, 0xef, 0x19, 0xa8, 0x8c, 0xdc, 0xc4, 0x9d, 0xd2, 0x4c, 0xd8, 0x8d, 0x22, 0xf2, 0x1e, 0x05, + 0x63, 0x11, 0x98, 0x6a, 0x4a, 0xa7, 0xd4, 0xad, 0xee, 0x0a, 0xef, 0x11, 0xa0, 0x53, 0x97, 0x88, + 0x38, 0x19, 0x6a, 0xbf, 0xb8, 0x5e, 0xe9, 0xca, 0xcd, 0x4a, 0x57, 0x7e, 0xae, 0x74, 0xe5, 0xe3, + 0x5a, 0x2f, 0xdc, 0xac, 0xf5, 0xc2, 0x8f, 0xb5, 0x5e, 0x78, 0xfb, 0x28, 0xc4, 0x6c, 0x32, 0xf7, + 0x4c, 0x9f, 0x4c, 0x2d, 0x9f, 0xd0, 0x29, 0xa1, 0xf2, 0x73, 0x4e, 0x83, 0x77, 0xd6, 0x95, 0x75, + 0xfb, 0xb6, 0x3c, 0xe8, 0x9f, 0xcb, 0xe7, 0x85, 0x2d, 0x67, 0x88, 0x7a, 0x15, 0x3e, 0xdc, 0x87, + 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x39, 0xbe, 0xfd, 0x04, 0x7e, 0x04, 0x00, 0x00, } func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) { @@ -591,13 +590,13 @@ func (m *Height) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintClient(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x10 } - if m.VersionNumber != 0 { - i = encodeVarintClient(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintClient(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x8 } @@ -729,11 +728,11 @@ func (m *Height) Size() (n int) { } var l int _ = l - if m.VersionNumber != 0 { - n += 1 + sovClient(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovClient(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovClient(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovClient(uint64(m.RevisionHeight)) } return n } @@ -1337,9 +1336,9 @@ func (m *Height) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowClient @@ -1349,16 +1348,16 @@ func (m *Height) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowClient @@ -1368,7 +1367,7 @@ func (m *Height) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/02-client/types/genesis_test.go b/x/ibc/core/02-client/types/genesis_test.go index 1b60fb5c44..7d131bae61 100644 --- a/x/ibc/core/02-client/types/genesis_test.go +++ b/x/ibc/core/02-client/types/genesis_test.go @@ -52,7 +52,7 @@ func (suite *TypesTestSuite) TestValidateGenesis() { valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) heightMinus1 := types.NewHeight(0, height-1) - header := suite.chainA.CreateTMClientHeader(chainID, int64(clientHeight.VersionHeight), heightMinus1, now, valSet, valSet, []tmtypes.PrivValidator{privVal}) + header := suite.chainA.CreateTMClientHeader(chainID, int64(clientHeight.RevisionHeight), heightMinus1, now, valSet, valSet, []tmtypes.PrivValidator{privVal}) testCases := []struct { name string diff --git a/x/ibc/core/02-client/types/height.go b/x/ibc/core/02-client/types/height.go index ab156e80de..d507ddea8c 100644 --- a/x/ibc/core/02-client/types/height.go +++ b/x/ibc/core/02-client/types/height.go @@ -14,10 +14,10 @@ import ( var _ exported.Height = (*Height)(nil) -// IsVersionFormat checks if a chainID is in the format required for parsing versions -// The chainID must be in the form: `{chainID}-{version} +// IsRevisionFormat checks if a chainID is in the format required for parsing revisions +// The chainID must be in the form: `{chainID}-{revision} // 24-host may enforce stricter checks on chainID -var IsVersionFormat = regexp.MustCompile(`^.+[^-]-{1}[1-9][0-9]*$`).MatchString +var IsRevisionFormat = regexp.MustCompile(`^.+[^-]-{1}[1-9][0-9]*$`).MatchString // ZeroHeight is a helper function which returns an uninitialized height. func ZeroHeight() Height { @@ -25,21 +25,21 @@ func ZeroHeight() Height { } // NewHeight is a constructor for the IBC height type -func NewHeight(versionNumber, versionHeight uint64) Height { +func NewHeight(revisionNumber, revisionHeight uint64) Height { return Height{ - VersionNumber: versionNumber, - VersionHeight: versionHeight, + RevisionNumber: revisionNumber, + RevisionHeight: revisionHeight, } } -// GetVersionNumber returns the version-number of the height -func (h Height) GetVersionNumber() uint64 { - return h.VersionNumber +// GetRevisionNumber returns the revision-number of the height +func (h Height) GetRevisionNumber() uint64 { + return h.RevisionNumber } -// GetVersionHeight returns the version-height of the height -func (h Height) GetVersionHeight() uint64 { - return h.VersionHeight +// GetRevisionHeight returns the revision-height of the height +func (h Height) GetRevisionHeight() uint64 { + return h.RevisionHeight } // Compare implements a method to compare two heights. When comparing two heights a, b @@ -48,20 +48,20 @@ func (h Height) GetVersionHeight() uint64 { // 0 if a = b // 1 if a > b // -// It first compares based on version numbers, whichever has the higher version number is the higher height -// If version number is the same, then the version height is compared +// It first compares based on revision numbers, whichever has the higher revision number is the higher height +// If revision number is the same, then the revision height is compared func (h Height) Compare(other exported.Height) int64 { height, ok := other.(Height) if !ok { panic(fmt.Sprintf("cannot compare against invalid height type: %T. expected height type: %T", other, h)) } var a, b big.Int - if h.VersionNumber != height.VersionNumber { - a.SetUint64(h.VersionNumber) - b.SetUint64(height.VersionNumber) + if h.RevisionNumber != height.RevisionNumber { + a.SetUint64(h.RevisionNumber) + b.SetUint64(height.RevisionNumber) } else { - a.SetUint64(h.VersionHeight) - b.SetUint64(height.VersionHeight) + a.SetUint64(h.RevisionHeight) + b.SetUint64(height.RevisionHeight) } return int64(a.Cmp(&b)) } @@ -95,27 +95,27 @@ func (h Height) EQ(other exported.Height) bool { // String returns a string representation of Height func (h Height) String() string { - return fmt.Sprintf("%d-%d", h.VersionNumber, h.VersionHeight) + return fmt.Sprintf("%d-%d", h.RevisionNumber, h.RevisionHeight) } -// Decrement will return a new height with the VersionHeight decremented -// If the VersionHeight is already at lowest value (1), then false success flag is returend +// Decrement will return a new height with the RevisionHeight decremented +// If the RevisionHeight is already at lowest value (1), then false success flag is returend func (h Height) Decrement() (decremented exported.Height, success bool) { - if h.VersionHeight == 0 { + if h.RevisionHeight == 0 { return Height{}, false } - return NewHeight(h.VersionNumber, h.VersionHeight-1), true + return NewHeight(h.RevisionNumber, h.RevisionHeight-1), true } -// Increment will return a height with the same version number but an -// incremented version height +// Increment will return a height with the same revision number but an +// incremented revision height func (h Height) Increment() Height { - return NewHeight(h.VersionNumber, h.VersionHeight+1) + return NewHeight(h.RevisionNumber, h.RevisionHeight+1) } -// IsZero returns true if height version and version-height are both 0 +// IsZero returns true if height revision and revision-height are both 0 func (h Height) IsZero() bool { - return h.VersionNumber == 0 && h.VersionHeight == 0 + return h.RevisionNumber == 0 && h.RevisionHeight == 0 } // MustParseHeight will attempt to parse a string representation of a height and panic if @@ -134,55 +134,55 @@ func MustParseHeight(heightStr string) Height { func ParseHeight(heightStr string) (Height, error) { splitStr := strings.Split(heightStr, "-") if len(splitStr) != 2 { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "expected height string format: {version}-{height}. Got: %s", heightStr) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "expected height string format: {revision}-{height}. Got: %s", heightStr) } - versionNumber, err := strconv.ParseUint(splitStr[0], 10, 64) + revisionNumber, err := strconv.ParseUint(splitStr[0], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid version number. parse err: %s", err) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision number. parse err: %s", err) } - versionHeight, err := strconv.ParseUint(splitStr[1], 10, 64) + revisionHeight, err := strconv.ParseUint(splitStr[1], 10, 64) if err != nil { - return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid version height. parse err: %s", err) + return Height{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "invalid revision height. parse err: %s", err) } - return NewHeight(versionNumber, versionHeight), nil + return NewHeight(revisionNumber, revisionHeight), nil } -// SetVersionNumber takes a chainID in valid version format and swaps the version number -// in the chainID with the given version number. -func SetVersionNumber(chainID string, version uint64) (string, error) { - if !IsVersionFormat(chainID) { +// SetRevisionNumber takes a chainID in valid revision format and swaps the revision number +// in the chainID with the given revision number. +func SetRevisionNumber(chainID string, revision uint64) (string, error) { + if !IsRevisionFormat(chainID) { return "", sdkerrors.Wrapf( - sdkerrors.ErrInvalidChainID, "chainID is not in version format: %s", chainID, + sdkerrors.ErrInvalidChainID, "chainID is not in revision format: %s", chainID, ) } splitStr := strings.Split(chainID, "-") - // swap out version number with given version - splitStr[len(splitStr)-1] = strconv.Itoa(int(version)) + // swap out revision number with given revision + splitStr[len(splitStr)-1] = strconv.Itoa(int(revision)) return strings.Join(splitStr, "-"), nil } -// ParseChainID is a utility function that returns an version number from the given ChainID. -// ParseChainID attempts to parse a chain id in the format: `{chainID}-{version}` -// and return the versionnumber as a uint64. -// If the chainID is not in the expected format, a default version value of 0 is returned. +// ParseChainID is a utility function that returns an revision number from the given ChainID. +// ParseChainID attempts to parse a chain id in the format: `{chainID}-{revision}` +// and return the revisionnumber as a uint64. +// If the chainID is not in the expected format, a default revision value of 0 is returned. func ParseChainID(chainID string) uint64 { - if !IsVersionFormat(chainID) { - // chainID is not in version format, return 0 as default + if !IsRevisionFormat(chainID) { + // chainID is not in revision format, return 0 as default return 0 } splitStr := strings.Split(chainID, "-") - version, err := strconv.ParseUint(splitStr[len(splitStr)-1], 10, 64) + revision, err := strconv.ParseUint(splitStr[len(splitStr)-1], 10, 64) // sanity check: error should always be nil since regex only allows numbers in last element if err != nil { panic(fmt.Sprintf("regex allowed non-number value as last split element for chainID: %s", chainID)) } - return version + return revision } // GetSelfHeight is a utility function that returns self height given context -// Version number is retrieved from ctx.ChainID() +// Revision number is retrieved from ctx.ChainID() func GetSelfHeight(ctx sdk.Context) Height { - version := ParseChainID(ctx.ChainID()) - return NewHeight(version, uint64(ctx.BlockHeight())) + revision := ParseChainID(ctx.ChainID()) + return NewHeight(revision, uint64(ctx.BlockHeight())) } diff --git a/x/ibc/core/02-client/types/height_test.go b/x/ibc/core/02-client/types/height_test.go index 0bd8f0848f..f2615c8c1d 100644 --- a/x/ibc/core/02-client/types/height_test.go +++ b/x/ibc/core/02-client/types/height_test.go @@ -20,12 +20,12 @@ func TestCompareHeights(t *testing.T) { height2 types.Height compareSign int64 }{ - {"version number 1 is lesser", types.NewHeight(1, 3), types.NewHeight(3, 4), -1}, - {"version number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, - {"version height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, - {"version height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, - {"version number is MaxUint64", types.NewHeight(math.MaxUint64, 1), types.NewHeight(0, 1), 1}, - {"version height is MaxUint64", types.NewHeight(1, math.MaxUint64), types.NewHeight(1, 0), 1}, + {"revision number 1 is lesser", types.NewHeight(1, 3), types.NewHeight(3, 4), -1}, + {"revision number 1 is greater", types.NewHeight(7, 5), types.NewHeight(4, 5), 1}, + {"revision height 1 is lesser", types.NewHeight(3, 4), types.NewHeight(3, 9), -1}, + {"revision height 1 is greater", types.NewHeight(3, 8), types.NewHeight(3, 3), 1}, + {"revision number is MaxUint64", types.NewHeight(math.MaxUint64, 1), types.NewHeight(0, 1), 1}, + {"revision height is MaxUint64", types.NewHeight(1, math.MaxUint64), types.NewHeight(1, 0), 1}, {"height is equal", types.NewHeight(4, 4), types.NewHeight(4, 4), 0}, } @@ -66,11 +66,11 @@ func TestString(t *testing.T) { _, err := types.ParseHeight("height") require.Error(t, err, "invalid height string passed") - _, err = types.ParseHeight("version-10") - require.Error(t, err, "invalid version string passed") + _, err = types.ParseHeight("revision-10") + require.Error(t, err, "invalid revision string passed") _, err = types.ParseHeight("3-height") - require.Error(t, err, "invalid version-height string passed") + require.Error(t, err, "invalid revision-height string passed") height := types.NewHeight(3, 4) recovered, err := types.ParseHeight(height.String()) @@ -100,7 +100,7 @@ func (suite *TypesTestSuite) TestMustParseHeight() { func TestParseChainID(t *testing.T) { cases := []struct { chainID string - version uint64 + revision uint64 formatted bool }{ {"gaiamainnet-3", 3, true}, @@ -114,36 +114,36 @@ func TestParseChainID(t *testing.T) { } for i, tc := range cases { - require.Equal(t, tc.formatted, types.IsVersionFormat(tc.chainID), "case %d does not match expected format", i) + require.Equal(t, tc.formatted, types.IsRevisionFormat(tc.chainID), "case %d does not match expected format", i) - version := types.ParseChainID(tc.chainID) - require.Equal(t, tc.version, version, "case %d returns incorrect version", i) + revision := types.ParseChainID(tc.chainID) + require.Equal(t, tc.revision, revision, "case %d returns incorrect revision", i) } } -func TestSetVersionNumber(t *testing.T) { - // Test SetVersionNumber - chainID, err := types.SetVersionNumber("gaiamainnet", 3) - require.Error(t, err, "invalid version format passed SetVersionNumber") - require.Equal(t, "", chainID, "invalid version format returned non-empty string on SetVersionNumber") +func TestSetRevisionNumber(t *testing.T) { + // Test SetRevisionNumber + chainID, err := types.SetRevisionNumber("gaiamainnet", 3) + require.Error(t, err, "invalid revision format passed SetRevisionNumber") + require.Equal(t, "", chainID, "invalid revision format returned non-empty string on SetRevisionNumber") chainID = "gaiamainnet-3" - chainID, err = types.SetVersionNumber(chainID, 4) - require.NoError(t, err, "valid version format failed SetVersionNumber") - require.Equal(t, "gaiamainnet-4", chainID, "valid version format returned incorrect string on SetVersionNumber") + chainID, err = types.SetRevisionNumber(chainID, 4) + require.NoError(t, err, "valid revision format failed SetRevisionNumber") + require.Equal(t, "gaiamainnet-4", chainID, "valid revision format returned incorrect string on SetRevisionNumber") } func (suite *TypesTestSuite) TestSelfHeight() { ctx := suite.chainA.GetContext() - // Test default version + // Test default revision ctx = ctx.WithChainID("gaiamainnet") ctx = ctx.WithBlockHeight(10) height := types.GetSelfHeight(ctx) suite.Require().Equal(types.NewHeight(0, 10), height, "default self height failed") - // Test successful version format + // Test successful revision format ctx = ctx.WithChainID("gaiamainnet-3") ctx = ctx.WithBlockHeight(18) height = types.GetSelfHeight(ctx) diff --git a/x/ibc/core/02-client/types/msgs_test.go b/x/ibc/core/02-client/types/msgs_test.go index 7781ea42b7..7d2da65d2c 100644 --- a/x/ibc/core/02-client/types/msgs_test.go +++ b/x/ibc/core/02-client/types/msgs_test.go @@ -497,8 +497,8 @@ func (suite *TypesTestSuite) TestMarshalMsgSubmitMisbehaviour() { "tendermint client", func() { height := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)) heightMinus1 := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)-1) - header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress()) @@ -555,8 +555,8 @@ func (suite *TypesTestSuite) TestMsgSubmitMisbehaviour_ValidateBasic() { func() { height := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)) heightMinus1 := types.NewHeight(0, uint64(suite.chainA.CurrentHeader.Height)-1) - header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) - header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.VersionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header1 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time, suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) + header2 := suite.chainA.CreateTMClientHeader(suite.chainA.ChainID, int64(height.RevisionHeight), heightMinus1, suite.chainA.CurrentHeader.Time.Add(time.Minute), suite.chainA.Vals, suite.chainA.Vals, suite.chainA.Signers) misbehaviour := ibctmtypes.NewMisbehaviour("tendermint", header1, header2) msg, err = types.NewMsgSubmitMisbehaviour("tendermint", misbehaviour, suite.chainA.SenderAccount.GetAddress()) diff --git a/x/ibc/core/02-client/types/query.pb.go b/x/ibc/core/02-client/types/query.pb.go index 755d401802..afe6670d4b 100644 --- a/x/ibc/core/02-client/types/query.pb.go +++ b/x/ibc/core/02-client/types/query.pb.go @@ -253,10 +253,10 @@ func (m *QueryClientStatesResponse) GetPagination() *query.PageResponse { type QueryConsensusStateRequest struct { // client identifier ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` - // consensus state version number - VersionNumber uint64 `protobuf:"varint,2,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - // consensus state version height - VersionHeight uint64 `protobuf:"varint,3,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + // consensus state revision number + RevisionNumber uint64 `protobuf:"varint,2,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + // consensus state revision height + RevisionHeight uint64 `protobuf:"varint,3,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` // latest_height overrrides the height field and queries the latest stored // ConsensusState LatestHeight bool `protobuf:"varint,4,opt,name=latest_height,json=latestHeight,proto3" json:"latest_height,omitempty"` @@ -302,16 +302,16 @@ func (m *QueryConsensusStateRequest) GetClientId() string { return "" } -func (m *QueryConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -599,59 +599,59 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/query.proto", fileDescriptor_dc42cdfd1d52d76e) } var fileDescriptor_dc42cdfd1d52d76e = []byte{ - // 823 bytes of a gzipped FileDescriptorProto + // 824 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4d, 0x4f, 0xdb, 0x48, - 0x18, 0xce, 0xf0, 0x25, 0x98, 0x04, 0x58, 0x8d, 0xd0, 0x6e, 0x30, 0xc8, 0x44, 0x5e, 0x2d, 0x9b, - 0xdd, 0x85, 0x19, 0x92, 0xdd, 0x2d, 0x52, 0x25, 0x0e, 0x05, 0x89, 0x96, 0x4b, 0x0b, 0xee, 0xa1, - 0x52, 0xa5, 0x0a, 0xd9, 0xce, 0xc4, 0xb1, 0x4a, 0x3c, 0x21, 0xe3, 0x44, 0x45, 0x88, 0x0b, 0x7f, - 0xa0, 0x95, 0x7a, 0xec, 0xb5, 0xa7, 0xaa, 0xea, 0xa5, 0x87, 0xfe, 0x83, 0x8a, 0x23, 0x52, 0x7b, - 0xe8, 0xa9, 0x1f, 0xd0, 0x1f, 0xd1, 0x63, 0xe5, 0x99, 0x31, 0xb1, 0x89, 0x11, 0x16, 0x6a, 0x4f, - 0xb1, 0xdf, 0xaf, 0x79, 0x9e, 0xe7, 0x7d, 0xdf, 0x71, 0xa0, 0xee, 0xd9, 0x0e, 0x71, 0x58, 0x9b, - 0x12, 0x67, 0xc7, 0xa3, 0x7e, 0x40, 0xba, 0x15, 0xb2, 0xdb, 0xa1, 0xed, 0x3d, 0xdc, 0x6a, 0xb3, - 0x80, 0x21, 0xe4, 0xd9, 0x0e, 0x0e, 0xfd, 0x58, 0xfa, 0x71, 0xb7, 0xa2, 0xfd, 0xed, 0x30, 0xde, - 0x64, 0x9c, 0xd8, 0x16, 0xa7, 0x32, 0x98, 0x74, 0x2b, 0x36, 0x0d, 0xac, 0x0a, 0x69, 0x59, 0xae, - 0xe7, 0x5b, 0x81, 0xc7, 0x7c, 0x99, 0xaf, 0xcd, 0xa5, 0xd4, 0x57, 0x95, 0x64, 0xc0, 0xb4, 0xcb, - 0x98, 0xbb, 0x43, 0x89, 0x78, 0xb3, 0x3b, 0x75, 0x62, 0xf9, 0xea, 0x6c, 0x6d, 0x56, 0xb9, 0xac, - 0x96, 0x47, 0x2c, 0xdf, 0x67, 0x81, 0x28, 0xcc, 0x95, 0x77, 0xca, 0x65, 0x2e, 0x13, 0x8f, 0x24, - 0x7c, 0x92, 0x56, 0xe3, 0x1a, 0xfc, 0x6d, 0x2b, 0x44, 0xb4, 0x26, 0xce, 0xb8, 0x1b, 0x58, 0x01, - 0x35, 0xe9, 0x6e, 0x87, 0xf2, 0x00, 0xcd, 0xc0, 0x31, 0x79, 0xf2, 0xb6, 0x57, 0x2b, 0x82, 0x12, - 0x28, 0x8f, 0x99, 0xa3, 0xd2, 0xb0, 0x51, 0x33, 0x5e, 0x01, 0x58, 0xec, 0x4f, 0xe4, 0x2d, 0xe6, - 0x73, 0x8a, 0x96, 0x61, 0x41, 0x65, 0xf2, 0xd0, 0x2e, 0x92, 0xf3, 0xd5, 0x29, 0x2c, 0xf1, 0xe1, - 0x08, 0x3a, 0xbe, 0xe1, 0xef, 0x99, 0x79, 0xa7, 0x57, 0x00, 0x4d, 0xc1, 0xe1, 0x56, 0x9b, 0xb1, - 0x7a, 0x71, 0xa0, 0x04, 0xca, 0x05, 0x53, 0xbe, 0xa0, 0x35, 0x58, 0x10, 0x0f, 0xdb, 0x0d, 0xea, - 0xb9, 0x8d, 0xa0, 0x38, 0x28, 0xca, 0x69, 0xb8, 0x5f, 0x6a, 0x7c, 0x4b, 0x44, 0xac, 0x0e, 0x1d, - 0x7d, 0x9c, 0xcb, 0x99, 0x79, 0x91, 0x25, 0x4d, 0x86, 0xdd, 0x8f, 0x97, 0x47, 0x4c, 0xd7, 0x21, - 0xec, 0x35, 0x42, 0xa1, 0x9d, 0xc7, 0xb2, 0x6b, 0x38, 0xec, 0x1a, 0x96, 0x2d, 0x56, 0x5d, 0xc3, - 0x9b, 0x96, 0x1b, 0xa9, 0x64, 0xc6, 0x32, 0x8d, 0xf7, 0x00, 0x4e, 0xa7, 0x1c, 0xa2, 0x54, 0xf1, - 0xe1, 0x78, 0x5c, 0x15, 0x5e, 0x04, 0xa5, 0xc1, 0x72, 0xbe, 0xfa, 0x57, 0x1a, 0x8f, 0x8d, 0x1a, - 0xf5, 0x03, 0xaf, 0xee, 0xd1, 0x5a, 0xac, 0xd4, 0xaa, 0x1e, 0xd2, 0x7a, 0xf1, 0x69, 0xee, 0xd7, - 0x54, 0x37, 0x37, 0x0b, 0x31, 0x2d, 0x39, 0xba, 0x99, 0x60, 0x35, 0x20, 0x58, 0xfd, 0x79, 0x29, - 0x2b, 0x09, 0x36, 0x41, 0xeb, 0x25, 0x80, 0x9a, 0xa4, 0x15, 0xba, 0x7c, 0xde, 0xe1, 0x99, 0xe7, - 0x04, 0xfd, 0x01, 0x27, 0xba, 0xb4, 0xcd, 0x3d, 0xe6, 0x6f, 0xfb, 0x9d, 0xa6, 0x4d, 0xdb, 0x02, - 0xc8, 0x90, 0x39, 0xae, 0xac, 0xb7, 0x85, 0x31, 0x1e, 0x16, 0x6b, 0x72, 0x2f, 0x4c, 0x36, 0x11, - 0xfd, 0x0e, 0xc7, 0x77, 0x42, 0x6e, 0x41, 0x14, 0x35, 0x54, 0x02, 0xe5, 0x51, 0xb3, 0x20, 0x8d, - 0xaa, 0xd3, 0x6f, 0x00, 0x9c, 0x49, 0x85, 0xab, 0xfa, 0xb0, 0x02, 0x27, 0x9d, 0xc8, 0x93, 0x61, - 0x40, 0x27, 0x9c, 0x44, 0x99, 0x9f, 0x39, 0xa3, 0x87, 0xe9, 0xc8, 0x79, 0x26, 0xa5, 0xd7, 0x53, - 0xda, 0x7d, 0x95, 0x21, 0x7e, 0x0b, 0xe0, 0x6c, 0x3a, 0x08, 0xa5, 0xdf, 0x03, 0xf8, 0xcb, 0x39, - 0xfd, 0xa2, 0x51, 0x5e, 0x48, 0xa3, 0x9b, 0x2c, 0x73, 0xcf, 0x0b, 0x1a, 0x09, 0x01, 0x26, 0x93, - 0xf2, 0xfe, 0xc0, 0xb1, 0xd5, 0x12, 0x1b, 0xbf, 0x69, 0xb5, 0xad, 0x66, 0xa4, 0xa4, 0x71, 0x27, - 0xb1, 0xa8, 0x91, 0x4f, 0x11, 0xac, 0xc2, 0x91, 0x96, 0xb0, 0xa8, 0xb9, 0x48, 0xed, 0xa2, 0xca, - 0x51, 0x91, 0xd5, 0x6f, 0x23, 0x70, 0x58, 0x54, 0x44, 0xcf, 0x01, 0xcc, 0xc7, 0xb6, 0x12, 0xfd, - 0x93, 0x96, 0x7d, 0xc1, 0x9d, 0xab, 0x2d, 0x64, 0x0b, 0x96, 0x40, 0x8d, 0xeb, 0x87, 0xef, 0xbe, - 0x3e, 0x1d, 0xf8, 0x0f, 0x55, 0x49, 0xff, 0x57, 0x43, 0x7e, 0x5f, 0x12, 0x17, 0x0e, 0xd9, 0x3f, - 0x9b, 0x9e, 0x03, 0xf4, 0x0c, 0xc0, 0x42, 0xfc, 0xf2, 0x40, 0x99, 0x8e, 0x8e, 0x04, 0xd4, 0x16, - 0x33, 0x46, 0x2b, 0xa4, 0x58, 0x20, 0x2d, 0xa3, 0xf9, 0x6c, 0x48, 0xd1, 0x17, 0x00, 0x27, 0x92, - 0x83, 0x83, 0xf0, 0xc5, 0x27, 0xa6, 0x5d, 0x4b, 0x1a, 0xc9, 0x1c, 0xaf, 0x30, 0xfa, 0x02, 0x63, - 0x03, 0xd5, 0x2f, 0xc6, 0x78, 0x6e, 0xec, 0xe3, 0x82, 0x12, 0x75, 0x53, 0x91, 0xfd, 0xe4, 0x7d, - 0x77, 0x40, 0xe4, 0x8d, 0xd0, 0xb3, 0xcb, 0xf7, 0x03, 0xf4, 0x1a, 0xc0, 0xc9, 0x73, 0x3b, 0x86, - 0xb2, 0x82, 0x3e, 0xeb, 0xc3, 0x52, 0xf6, 0x04, 0x45, 0x73, 0x45, 0xd0, 0x5c, 0x46, 0xff, 0x5f, - 0x89, 0x26, 0x7a, 0x7c, 0x36, 0x37, 0x72, 0x03, 0x2e, 0x9d, 0x9b, 0xc4, 0xe2, 0x5d, 0x3a, 0x37, - 0xc9, 0x55, 0x34, 0x0c, 0x01, 0x76, 0x16, 0x69, 0x12, 0x6c, 0x12, 0xa7, 0x5c, 0xbd, 0xd5, 0xad, - 0xa3, 0x13, 0x1d, 0x1c, 0x9f, 0xe8, 0xe0, 0xf3, 0x89, 0x0e, 0x9e, 0x9c, 0xea, 0xb9, 0xe3, 0x53, - 0x3d, 0xf7, 0xe1, 0x54, 0xcf, 0xdd, 0x5f, 0x76, 0xbd, 0xa0, 0xd1, 0xb1, 0xb1, 0xc3, 0x9a, 0x44, - 0xfd, 0x07, 0x93, 0x3f, 0x8b, 0xbc, 0xf6, 0x90, 0x3c, 0xea, 0x09, 0xb0, 0x54, 0x5d, 0x54, 0xb5, - 0x83, 0xbd, 0x16, 0xe5, 0xf6, 0x88, 0xf8, 0x02, 0xfc, 0xfb, 0x3d, 0x00, 0x00, 0xff, 0xff, 0xca, - 0xdc, 0xd5, 0x38, 0xee, 0x09, 0x00, 0x00, + 0x18, 0xce, 0xf0, 0x25, 0x98, 0x04, 0xb2, 0x1a, 0xa1, 0xdd, 0x60, 0x90, 0x89, 0xbc, 0x12, 0x64, + 0x77, 0x61, 0x86, 0x64, 0x3f, 0x90, 0x56, 0xe2, 0xb0, 0x20, 0xb1, 0xe5, 0xd2, 0x82, 0x7b, 0xa8, + 0x54, 0xa9, 0x42, 0xb6, 0x33, 0x38, 0x16, 0xc4, 0x13, 0x32, 0x4e, 0x54, 0x84, 0xb8, 0xf0, 0x07, + 0x5a, 0xa9, 0xc7, 0x5e, 0x7b, 0xea, 0xa1, 0xaa, 0xd4, 0x43, 0xff, 0x41, 0xc5, 0x11, 0xa9, 0x3d, + 0xf4, 0xd4, 0x56, 0xc0, 0xbf, 0xe8, 0xa5, 0xf2, 0xcc, 0x18, 0xec, 0xc4, 0x08, 0x0b, 0xb5, 0xa7, + 0xd8, 0xef, 0xd7, 0x3c, 0xcf, 0xf3, 0xbe, 0xef, 0x38, 0x50, 0xf7, 0x6c, 0x87, 0x38, 0xac, 0x4d, + 0x89, 0xb3, 0xe7, 0x51, 0x3f, 0x20, 0xdd, 0x2a, 0xd9, 0xef, 0xd0, 0xf6, 0x01, 0x6e, 0xb5, 0x59, + 0xc0, 0x10, 0xf2, 0x6c, 0x07, 0x87, 0x7e, 0x2c, 0xfd, 0xb8, 0x5b, 0xd5, 0x7e, 0x77, 0x18, 0x6f, + 0x32, 0x4e, 0x6c, 0x8b, 0x53, 0x19, 0x4c, 0xba, 0x55, 0x9b, 0x06, 0x56, 0x95, 0xb4, 0x2c, 0xd7, + 0xf3, 0xad, 0xc0, 0x63, 0xbe, 0xcc, 0xd7, 0x66, 0x53, 0xea, 0xab, 0x4a, 0x32, 0x60, 0xca, 0x65, + 0xcc, 0xdd, 0xa3, 0x44, 0xbc, 0xd9, 0x9d, 0x1d, 0x62, 0xf9, 0xea, 0x6c, 0x6d, 0x46, 0xb9, 0xac, + 0x96, 0x47, 0x2c, 0xdf, 0x67, 0x81, 0x28, 0xcc, 0x95, 0x77, 0xd2, 0x65, 0x2e, 0x13, 0x8f, 0x24, + 0x7c, 0x92, 0x56, 0xe3, 0x1f, 0xf8, 0xcb, 0x56, 0x88, 0x68, 0x4d, 0x9c, 0x71, 0x3f, 0xb0, 0x02, + 0x6a, 0xd2, 0xfd, 0x0e, 0xe5, 0x01, 0x9a, 0x86, 0x63, 0xf2, 0xe4, 0x6d, 0xaf, 0x5e, 0x02, 0x65, + 0x50, 0x19, 0x33, 0x47, 0xa5, 0x61, 0xa3, 0x6e, 0xbc, 0x02, 0xb0, 0xd4, 0x9f, 0xc8, 0x5b, 0xcc, + 0xe7, 0x14, 0x2d, 0xc3, 0x82, 0xca, 0xe4, 0xa1, 0x5d, 0x24, 0xe7, 0x6b, 0x93, 0x58, 0xe2, 0xc3, + 0x11, 0x74, 0xfc, 0x9f, 0x7f, 0x60, 0xe6, 0x9d, 0xab, 0x02, 0x68, 0x12, 0x0e, 0xb7, 0xda, 0x8c, + 0xed, 0x94, 0x06, 0xca, 0xa0, 0x52, 0x30, 0xe5, 0x0b, 0x5a, 0x83, 0x05, 0xf1, 0xb0, 0xdd, 0xa0, + 0x9e, 0xdb, 0x08, 0x4a, 0x83, 0xa2, 0x9c, 0x86, 0xfb, 0xa5, 0xc6, 0x77, 0x44, 0xc4, 0xea, 0xd0, + 0xc9, 0xa7, 0xd9, 0x9c, 0x99, 0x17, 0x59, 0xd2, 0x64, 0xd8, 0xfd, 0x78, 0x79, 0xc4, 0x74, 0x1d, + 0xc2, 0xab, 0x46, 0x28, 0xb4, 0x73, 0x58, 0x76, 0x0d, 0x87, 0x5d, 0xc3, 0xb2, 0xc5, 0xaa, 0x6b, + 0x78, 0xd3, 0x72, 0x23, 0x95, 0xcc, 0x58, 0xa6, 0xf1, 0x01, 0xc0, 0xa9, 0x94, 0x43, 0x94, 0x2a, + 0x3e, 0x1c, 0x8f, 0xab, 0xc2, 0x4b, 0xa0, 0x3c, 0x58, 0xc9, 0xd7, 0x7e, 0x4b, 0xe3, 0xb1, 0x51, + 0xa7, 0x7e, 0xe0, 0xed, 0x78, 0xb4, 0x1e, 0x2b, 0xb5, 0xaa, 0x87, 0xb4, 0x5e, 0x7e, 0x9e, 0xfd, + 0x39, 0xd5, 0xcd, 0xcd, 0x42, 0x4c, 0x4b, 0x8e, 0xfe, 0x4f, 0xb0, 0x1a, 0x10, 0xac, 0xe6, 0x6f, + 0x64, 0x25, 0xc1, 0x26, 0x68, 0xbd, 0x06, 0x50, 0x93, 0xb4, 0x42, 0x97, 0xcf, 0x3b, 0x3c, 0xf3, + 0x9c, 0xa0, 0x79, 0x58, 0x6c, 0xd3, 0xae, 0xc7, 0x3d, 0xe6, 0x6f, 0xfb, 0x9d, 0xa6, 0x4d, 0xdb, + 0x02, 0xc9, 0x90, 0x39, 0x11, 0x99, 0xef, 0x0a, 0x6b, 0x22, 0x30, 0xd6, 0xe7, 0x58, 0xa0, 0x6c, + 0x24, 0xfa, 0x15, 0x8e, 0xef, 0x85, 0xfc, 0x82, 0x28, 0x6c, 0xa8, 0x0c, 0x2a, 0xa3, 0x66, 0x41, + 0x1a, 0x55, 0xb7, 0xdf, 0x02, 0x38, 0x9d, 0x0a, 0x59, 0xf5, 0x62, 0x05, 0x16, 0x9d, 0xc8, 0x93, + 0x61, 0x48, 0x27, 0x9c, 0x44, 0x99, 0x1f, 0x39, 0xa7, 0xc7, 0xe9, 0xc8, 0x79, 0x26, 0xb5, 0xd7, + 0x53, 0x5a, 0x7e, 0x9b, 0x41, 0x7e, 0x07, 0xe0, 0x4c, 0x3a, 0x08, 0xa5, 0xdf, 0x23, 0xf8, 0x53, + 0x8f, 0x7e, 0xd1, 0x38, 0x2f, 0xa4, 0xd1, 0x4d, 0x96, 0x79, 0xe0, 0x05, 0x8d, 0x84, 0x00, 0xc5, + 0xa4, 0xbc, 0xdf, 0x71, 0x74, 0xb5, 0xc4, 0xd6, 0x6f, 0x5a, 0x6d, 0xab, 0x19, 0x29, 0x69, 0xdc, + 0x4b, 0x2c, 0x6b, 0xe4, 0x53, 0x04, 0x6b, 0x70, 0xa4, 0x25, 0x2c, 0x6a, 0x2e, 0x52, 0xbb, 0xa8, + 0x72, 0x54, 0x64, 0xed, 0xeb, 0x08, 0x1c, 0x16, 0x15, 0xd1, 0x0b, 0x00, 0xf3, 0xb1, 0xcd, 0x44, + 0x7f, 0xa4, 0x65, 0x5f, 0x73, 0xef, 0x6a, 0x0b, 0xd9, 0x82, 0x25, 0x50, 0xe3, 0xdf, 0xe3, 0xf7, + 0x17, 0xcf, 0x06, 0xfe, 0x42, 0x35, 0xd2, 0xff, 0xe5, 0x90, 0xdf, 0x98, 0xc4, 0xa5, 0x43, 0x0e, + 0x2f, 0xa7, 0xe7, 0x08, 0x3d, 0x07, 0xb0, 0x10, 0xbf, 0x40, 0x50, 0xa6, 0xa3, 0x23, 0x01, 0xb5, + 0xc5, 0x8c, 0xd1, 0x0a, 0x29, 0x16, 0x48, 0x2b, 0x68, 0x2e, 0x1b, 0x52, 0x74, 0x01, 0xe0, 0x44, + 0x72, 0x70, 0x10, 0xbe, 0xfe, 0xc4, 0xb4, 0xab, 0x49, 0x23, 0x99, 0xe3, 0x15, 0xc6, 0x7d, 0x81, + 0x71, 0x17, 0x79, 0xd7, 0x63, 0xec, 0x19, 0xfb, 0xb8, 0xa0, 0x24, 0xba, 0xaa, 0xc8, 0x61, 0xcf, + 0xa5, 0x77, 0x44, 0xe4, 0x9d, 0x10, 0x73, 0x48, 0xc3, 0x11, 0x7a, 0x03, 0x60, 0xb1, 0x67, 0xcd, + 0x50, 0x56, 0xdc, 0x97, 0xad, 0x58, 0xca, 0x9e, 0xa0, 0x98, 0xae, 0x08, 0xa6, 0xcb, 0xe8, 0xef, + 0x5b, 0x31, 0x45, 0x4f, 0x2e, 0x47, 0x47, 0x2e, 0xc1, 0x8d, 0xa3, 0x93, 0xd8, 0xbd, 0x1b, 0x47, + 0x27, 0xb9, 0x8d, 0x86, 0x21, 0xc0, 0xce, 0x20, 0x4d, 0x82, 0x4d, 0xe2, 0x94, 0xdb, 0xb7, 0xba, + 0x75, 0x72, 0xa6, 0x83, 0xd3, 0x33, 0x1d, 0x7c, 0x39, 0xd3, 0xc1, 0xd3, 0x73, 0x3d, 0x77, 0x7a, + 0xae, 0xe7, 0x3e, 0x9e, 0xeb, 0xb9, 0x87, 0xcb, 0xae, 0x17, 0x34, 0x3a, 0x36, 0x76, 0x58, 0x93, + 0xa8, 0xbf, 0x62, 0xf2, 0x67, 0x91, 0xd7, 0x77, 0xc9, 0xe3, 0x2b, 0x01, 0x96, 0x6a, 0x8b, 0xaa, + 0x76, 0x70, 0xd0, 0xa2, 0xdc, 0x1e, 0x11, 0x1f, 0x81, 0x3f, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff, + 0xa7, 0x0d, 0x7c, 0x62, 0xf5, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1088,13 +1088,13 @@ func (m *QueryConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, err i-- dAtA[i] = 0x20 } - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x18 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x10 } @@ -1394,11 +1394,11 @@ func (m *QueryConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } if m.LatestHeight { n += 2 @@ -2005,9 +2005,9 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2017,16 +2017,16 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2036,7 +2036,7 @@ func (m *QueryConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/02-client/types/query.pb.gw.go b/x/ibc/core/02-client/types/query.pb.gw.go index 77b3df69a8..d4414d5ea3 100644 --- a/x/ibc/core/02-client/types/query.pb.gw.go +++ b/x/ibc/core/02-client/types/query.pb.gw.go @@ -122,7 +122,7 @@ func local_request_Query_ClientStates_0(ctx context.Context, marshaler runtime.M } var ( - filter_Query_ConsensusState_0 = &utilities.DoubleArray{Encoding: map[string]int{"client_id": 0, "version_number": 1, "version_height": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} + filter_Query_ConsensusState_0 = &utilities.DoubleArray{Encoding: map[string]int{"client_id": 0, "revision_number": 1, "revision_height": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} ) func request_Query_ConsensusState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -147,26 +147,26 @@ func request_Query_ConsensusState_0(ctx context.Context, marshaler runtime.Marsh return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } if err := req.ParseForm(); err != nil { @@ -203,26 +203,26 @@ func local_request_Query_ConsensusState_0(ctx context.Context, marshaler runtime return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } if err := req.ParseForm(); err != nil { @@ -582,7 +582,7 @@ var ( pattern_Query_ClientStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "core", "client", "v1beta1", "client_states"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_ConsensusStates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "core", "client", "v1beta1", "consensus_states", "client_id"}, "", runtime.AssumeColonVerbOpt(true))) diff --git a/x/ibc/core/03-connection/client/cli/query.go b/x/ibc/core/03-connection/client/cli/query.go index 0beddb2f42..0c22dbdc82 100644 --- a/x/ibc/core/03-connection/client/cli/query.go +++ b/x/ibc/core/03-connection/client/cli/query.go @@ -79,7 +79,7 @@ func GetCmdQueryConnection() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(connRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(connRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(connRes) }, } @@ -113,7 +113,7 @@ func GetCmdQueryClientConnections() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(connPathsRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(connPathsRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(connPathsRes) }, } diff --git a/x/ibc/core/03-connection/client/utils/utils.go b/x/ibc/core/03-connection/client/utils/utils.go index 44283aef82..e1eb1ce00c 100644 --- a/x/ibc/core/03-connection/client/utils/utils.go +++ b/x/ibc/core/03-connection/client/utils/utils.go @@ -143,9 +143,9 @@ func QueryConnectionConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryConnectionConsensusStateRequest{ - ConnectionId: connectionID, - VersionNumber: height.VersionNumber, - VersionHeight: height.VersionHeight, + ConnectionId: connectionID, + RevisionNumber: height.RevisionNumber, + RevisionHeight: height.RevisionHeight, } res, err := queryClient.ConnectionConsensusState(context.Background(), req) diff --git a/x/ibc/core/03-connection/keeper/grpc_query.go b/x/ibc/core/03-connection/keeper/grpc_query.go index 5b34d1e4ef..62b1c00a34 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query.go +++ b/x/ibc/core/03-connection/keeper/grpc_query.go @@ -160,7 +160,7 @@ func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConn ) } - height := clienttypes.NewHeight(req.VersionNumber, req.VersionHeight) + height := clienttypes.NewHeight(req.RevisionNumber, req.RevisionHeight) consensusState, found := q.clientKeeper.GetClientConsensusState(ctx, connection.ClientId, height) if !found { return nil, status.Error( diff --git a/x/ibc/core/03-connection/keeper/grpc_query_test.go b/x/ibc/core/03-connection/keeper/grpc_query_test.go index e710b0d547..553033810d 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query_test.go +++ b/x/ibc/core/03-connection/keeper/grpc_query_test.go @@ -339,8 +339,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { func() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: "", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -350,8 +350,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { func() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: "test-connection-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -363,8 +363,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: connA.ID, - VersionNumber: 0, - VersionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height + RevisionNumber: 0, + RevisionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height } }, false, }, @@ -380,8 +380,8 @@ func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() { req = &types.QueryConnectionConsensusStateRequest{ ConnectionId: connA.ID, - VersionNumber: clientState.GetLatestHeight().GetVersionNumber(), - VersionHeight: clientState.GetLatestHeight().GetVersionHeight(), + RevisionNumber: clientState.GetLatestHeight().GetRevisionNumber(), + RevisionHeight: clientState.GetLatestHeight().GetRevisionHeight(), } }, true, diff --git a/x/ibc/core/03-connection/keeper/verify_test.go b/x/ibc/core/03-connection/keeper/verify_test.go index 3b047e741a..4bf1bfb9da 100644 --- a/x/ibc/core/03-connection/keeper/verify_test.go +++ b/x/ibc/core/03-connection/keeper/verify_test.go @@ -478,5 +478,5 @@ func (suite *KeeperTestSuite) TestVerifyNextSequenceRecv() { } func malleateHeight(height exported.Height, diff uint64) exported.Height { - return clienttypes.NewHeight(height.GetVersionNumber(), height.GetVersionHeight()+diff) + return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+diff) } diff --git a/x/ibc/core/03-connection/types/query.pb.go b/x/ibc/core/03-connection/types/query.pb.go index 5c3a2bcb26..2861c8a5fb 100644 --- a/x/ibc/core/03-connection/types/query.pb.go +++ b/x/ibc/core/03-connection/types/query.pb.go @@ -484,9 +484,9 @@ func (m *QueryConnectionClientStateResponse) GetProofHeight() types.Height { // Query/ConnectionConsensusState RPC method type QueryConnectionConsensusStateRequest struct { // connection identifier - ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - VersionNumber uint64 `protobuf:"varint,2,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - VersionHeight uint64 `protobuf:"varint,3,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` + RevisionNumber uint64 `protobuf:"varint,2,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + RevisionHeight uint64 `protobuf:"varint,3,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` } func (m *QueryConnectionConsensusStateRequest) Reset() { *m = QueryConnectionConsensusStateRequest{} } @@ -529,16 +529,16 @@ func (m *QueryConnectionConsensusStateRequest) GetConnectionId() string { return "" } -func (m *QueryConnectionConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryConnectionConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryConnectionConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryConnectionConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -635,63 +635,63 @@ func init() { } var fileDescriptor_cd8d529f8c7cd06b = []byte{ - // 887 bytes of a gzipped FileDescriptorProto + // 892 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x41, 0x4f, 0x33, 0x45, - 0x18, 0xee, 0x14, 0xbe, 0x2f, 0x1f, 0x53, 0x40, 0x9d, 0x14, 0xa8, 0xab, 0x16, 0x5c, 0x45, 0x0a, - 0x91, 0x19, 0x0a, 0xd1, 0x20, 0xd0, 0x44, 0x21, 0x88, 0x1c, 0x24, 0xb8, 0xc6, 0x8b, 0x17, 0xb2, - 0xbb, 0x1d, 0xb6, 0x1b, 0xe9, 0x4e, 0xe9, 0x6e, 0x1b, 0x1b, 0xd2, 0x83, 0xfe, 0x02, 0x13, 0x8f, - 0xde, 0x3c, 0x70, 0xf5, 0xe0, 0xd1, 0x1f, 0x20, 0x47, 0x12, 0x2f, 0x5e, 0x24, 0xa6, 0x78, 0xf5, - 0xe2, 0x2f, 0x30, 0x3b, 0x33, 0x65, 0x67, 0xe9, 0xb6, 0x94, 0xe6, 0xe3, 0xd4, 0xdd, 0x77, 0xde, - 0x77, 0xe6, 0x79, 0x9e, 0xf7, 0x9d, 0x67, 0x0b, 0x75, 0xd7, 0xb2, 0x89, 0xcd, 0xea, 0x94, 0xd8, - 0xcc, 0xf3, 0xa8, 0x1d, 0xb8, 0xcc, 0x23, 0xcd, 0x22, 0x39, 0x6f, 0xd0, 0x7a, 0x0b, 0xd7, 0xea, - 0x2c, 0x60, 0x68, 0xd6, 0xb5, 0x6c, 0x1c, 0xe6, 0xe0, 0x28, 0x07, 0x37, 0x8b, 0x5a, 0xd6, 0x61, - 0x0e, 0xe3, 0x29, 0x24, 0x7c, 0x12, 0xd9, 0xda, 0x8a, 0xcd, 0xfc, 0x2a, 0xf3, 0x89, 0x65, 0xfa, - 0x54, 0x6c, 0x43, 0x9a, 0x45, 0x8b, 0x06, 0x66, 0x91, 0xd4, 0x4c, 0xc7, 0xf5, 0x4c, 0x5e, 0x2e, - 0x72, 0xe7, 0xa3, 0xd3, 0xcf, 0x5c, 0xea, 0x05, 0xe1, 0xc9, 0xe2, 0x49, 0x26, 0x2c, 0xf5, 0x81, - 0xa7, 0x00, 0x11, 0x89, 0x6f, 0x3a, 0x8c, 0x39, 0x67, 0x94, 0x98, 0x35, 0x97, 0x98, 0x9e, 0xc7, - 0x02, 0x7e, 0x8c, 0x2f, 0x57, 0x5f, 0x97, 0xab, 0xfc, 0xcd, 0x6a, 0x9c, 0x12, 0xd3, 0x93, 0xe4, - 0xf4, 0x12, 0x9c, 0xfd, 0x22, 0x04, 0xb9, 0x77, 0xb7, 0xa3, 0x41, 0xcf, 0x1b, 0xd4, 0x0f, 0xd0, - 0x3b, 0x70, 0x2a, 0x3a, 0xe6, 0xc4, 0x2d, 0xe7, 0xc0, 0x02, 0x28, 0x4c, 0x18, 0x93, 0x51, 0xf0, - 0xb0, 0xac, 0xff, 0x06, 0xe0, 0x5c, 0x4f, 0xbd, 0x5f, 0x63, 0x9e, 0x4f, 0xd1, 0x3e, 0x84, 0x51, - 0x2e, 0xaf, 0xce, 0xac, 0x2f, 0xe2, 0x64, 0x31, 0x71, 0x54, 0xbf, 0xef, 0x95, 0x0d, 0xa5, 0x10, - 0x65, 0xe1, 0xb3, 0x5a, 0x9d, 0xb1, 0xd3, 0x5c, 0x7a, 0x01, 0x14, 0x26, 0x0d, 0xf1, 0x82, 0xf6, - 0xe0, 0x24, 0x7f, 0x38, 0xa9, 0x50, 0xd7, 0xa9, 0x04, 0xb9, 0x31, 0xbe, 0xbd, 0xa6, 0x6c, 0x2f, - 0x74, 0x6c, 0x16, 0xf1, 0x67, 0x3c, 0x63, 0x77, 0xfc, 0xea, 0x66, 0x3e, 0x65, 0x64, 0x78, 0x95, - 0x08, 0xe9, 0x66, 0x0f, 0x78, 0xbf, 0xcb, 0xfe, 0x53, 0x08, 0xa3, 0x76, 0x49, 0xf0, 0xef, 0x61, - 0xd1, 0x5b, 0x1c, 0xf6, 0x16, 0x8b, 0x11, 0x91, 0xbd, 0xc5, 0xc7, 0xa6, 0x43, 0x65, 0xad, 0xa1, - 0x54, 0xea, 0xff, 0x02, 0x98, 0xeb, 0x3d, 0x43, 0x2a, 0x74, 0x04, 0x33, 0x11, 0x51, 0x3f, 0x07, - 0x16, 0xc6, 0x0a, 0x99, 0xf5, 0xf7, 0xfb, 0x49, 0x74, 0x58, 0xa6, 0x5e, 0xe0, 0x9e, 0xba, 0xb4, - 0xac, 0x88, 0xad, 0x6e, 0x80, 0x0e, 0x62, 0xa0, 0xd3, 0x1c, 0xf4, 0xd2, 0x83, 0xa0, 0x05, 0x18, - 0x15, 0x35, 0xda, 0x84, 0xcf, 0x1f, 0xa9, 0xab, 0xcc, 0xd7, 0x77, 0xe0, 0x5b, 0x82, 0x2e, 0x4f, - 0x4b, 0x10, 0xf6, 0x0d, 0x38, 0x21, 0xb6, 0x88, 0x46, 0xea, 0x85, 0x08, 0x1c, 0x96, 0xf5, 0x4b, - 0x00, 0xf3, 0xfd, 0xca, 0xa5, 0x66, 0xcb, 0xf0, 0x55, 0x65, 0x2c, 0x6b, 0x66, 0x50, 0x11, 0xc2, - 0x4d, 0x18, 0xaf, 0x44, 0xf1, 0xe3, 0x30, 0xfc, 0x94, 0x93, 0x63, 0xc1, 0xb7, 0xef, 0x75, 0x55, - 0x20, 0xfe, 0x32, 0x30, 0x83, 0xee, 0x1c, 0xa0, 0x52, 0xe2, 0x0d, 0xda, 0xcd, 0xfd, 0x77, 0x33, - 0x9f, 0x6d, 0x99, 0xd5, 0xb3, 0x2d, 0x3d, 0xb6, 0xac, 0xdf, 0xbb, 0x5b, 0x1d, 0x00, 0xf5, 0x41, - 0x87, 0x48, 0x41, 0x4c, 0x38, 0xe7, 0xde, 0x4d, 0xc6, 0x89, 0xd4, 0xd6, 0x0f, 0x53, 0xe4, 0xd8, - 0x2e, 0x27, 0x51, 0x53, 0x86, 0x49, 0xd9, 0x73, 0xc6, 0x4d, 0x0a, 0x3f, 0xa5, 0x90, 0xbf, 0x02, - 0xf8, 0xee, 0x7d, 0x92, 0x21, 0x2d, 0xcf, 0x6f, 0xf8, 0x2f, 0x51, 0x4c, 0xb4, 0x08, 0xa7, 0x9b, - 0xb4, 0xee, 0x87, 0x8b, 0x5e, 0xa3, 0x6a, 0xd1, 0x3a, 0xe7, 0x32, 0x6e, 0x4c, 0xc9, 0xe8, 0x11, - 0x0f, 0xaa, 0x69, 0x0a, 0xab, 0x28, 0x4d, 0xa2, 0xbe, 0x01, 0x70, 0xf1, 0x01, 0xd4, 0xb2, 0x3b, - 0x25, 0x18, 0x8e, 0xa5, 0x58, 0x89, 0x75, 0x25, 0x8b, 0x85, 0x29, 0xe3, 0xae, 0x29, 0xe3, 0x4f, - 0xbc, 0x96, 0x31, 0x6d, 0xc7, 0xb6, 0x89, 0xdf, 0x96, 0x74, 0xfc, 0xb6, 0x44, 0x6d, 0x19, 0x1b, - 0xd4, 0x96, 0xf1, 0x11, 0xda, 0xb2, 0x7e, 0xf9, 0x02, 0x3e, 0xe3, 0x04, 0xd1, 0x2f, 0x00, 0xc2, - 0x88, 0x25, 0xc2, 0xfd, 0xdc, 0x29, 0xf9, 0x2b, 0xa2, 0x91, 0xa1, 0xf3, 0x85, 0x60, 0xfa, 0xc7, - 0xdf, 0xff, 0xf1, 0xcf, 0x8f, 0xe9, 0x2d, 0xb4, 0x49, 0x92, 0xbf, 0x7d, 0xe2, 0x53, 0xaa, 0xb8, - 0x1e, 0xb9, 0x88, 0x35, 0xbe, 0x8d, 0x7e, 0x06, 0x30, 0xa3, 0x38, 0x07, 0x1a, 0x16, 0x42, 0xd7, - 0xa2, 0xb4, 0xb5, 0xe1, 0x0b, 0x24, 0xe8, 0x35, 0x0e, 0x7a, 0x05, 0x15, 0x86, 0x05, 0x8d, 0x7e, - 0x07, 0xf0, 0xb5, 0x1e, 0x93, 0x43, 0x1f, 0x0c, 0x3e, 0xb9, 0x8f, 0xa7, 0x6a, 0x1f, 0x3e, 0xb6, - 0x4c, 0xc2, 0xde, 0xe3, 0xb0, 0x4b, 0x68, 0x7b, 0x30, 0x6c, 0x31, 0x80, 0x71, 0xc9, 0xbb, 0x43, - 0xd9, 0x46, 0x7f, 0x01, 0x38, 0x93, 0xe8, 0x50, 0xe8, 0xa3, 0x21, 0x75, 0xec, 0xb5, 0x4e, 0x6d, - 0x6b, 0x94, 0x52, 0xc9, 0xea, 0x73, 0xce, 0xea, 0x00, 0xed, 0x8f, 0x3a, 0x41, 0x44, 0x35, 0x51, - 0xf4, 0x53, 0x1a, 0xe6, 0xfa, 0x5d, 0x73, 0xb4, 0x33, 0x2c, 0xce, 0x24, 0x4f, 0xd3, 0x4a, 0x23, - 0x56, 0x4b, 0xa2, 0xdf, 0x01, 0xce, 0xf4, 0x02, 0xb5, 0x46, 0x67, 0x1a, 0xf7, 0x26, 0x22, 0x6d, - 0x8e, 0x5c, 0xc4, 0xcd, 0xb2, 0x4d, 0x84, 0x99, 0x44, 0x71, 0xf1, 0xde, 0xde, 0xfd, 0xea, 0xaa, - 0x93, 0x07, 0xd7, 0x9d, 0x3c, 0xf8, 0xbb, 0x93, 0x07, 0x3f, 0xdc, 0xe6, 0x53, 0xd7, 0xb7, 0xf9, - 0xd4, 0x9f, 0xb7, 0xf9, 0xd4, 0xd7, 0xdb, 0x8e, 0x1b, 0x54, 0x1a, 0x16, 0xb6, 0x59, 0x95, 0xc8, - 0xff, 0xc4, 0xe2, 0x67, 0xd5, 0x2f, 0x7f, 0x43, 0xbe, 0x8d, 0x20, 0xaf, 0x6d, 0xac, 0x2a, 0xa8, - 0x83, 0x56, 0x8d, 0xfa, 0xd6, 0x73, 0xee, 0x8a, 0x1b, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x91, - 0x3b, 0x2c, 0x79, 0xa0, 0x0b, 0x00, 0x00, + 0x18, 0xee, 0x14, 0xbe, 0x2f, 0x1f, 0x53, 0xfc, 0x3e, 0x9d, 0x14, 0xa8, 0xab, 0x16, 0x5c, 0x45, + 0x0a, 0x91, 0x19, 0x0a, 0xd1, 0x20, 0xd0, 0x44, 0x21, 0x88, 0x1c, 0x24, 0xb8, 0xc6, 0x8b, 0x17, + 0xb2, 0xbb, 0x1d, 0xb6, 0x1b, 0xe9, 0x4e, 0xe9, 0x6e, 0x1b, 0x1b, 0xac, 0x07, 0xe3, 0x0f, 0x30, + 0xf1, 0xee, 0xc1, 0x83, 0x89, 0x27, 0x8f, 0x1e, 0xfc, 0x01, 0x72, 0x24, 0xf1, 0xe2, 0x45, 0x62, + 0x8a, 0x57, 0x2f, 0xfe, 0x02, 0xb3, 0x33, 0x53, 0x76, 0xb6, 0xdd, 0x96, 0xd2, 0x7c, 0x9c, 0xba, + 0xfb, 0xce, 0xfb, 0xce, 0x3c, 0xcf, 0xf3, 0xbe, 0xf3, 0x6c, 0xa1, 0xee, 0x5a, 0x36, 0xb1, 0x59, + 0x9d, 0x12, 0x9b, 0x79, 0x1e, 0xb5, 0x03, 0x97, 0x79, 0xa4, 0x59, 0x24, 0xe7, 0x0d, 0x5a, 0x6f, + 0xe1, 0x5a, 0x9d, 0x05, 0x0c, 0xcd, 0xba, 0x96, 0x8d, 0xc3, 0x1c, 0x1c, 0xe5, 0xe0, 0x66, 0x51, + 0xcb, 0x3a, 0xcc, 0x61, 0x3c, 0x85, 0x84, 0x4f, 0x22, 0x5b, 0x5b, 0xb1, 0x99, 0x5f, 0x65, 0x3e, + 0xb1, 0x4c, 0x9f, 0x8a, 0x6d, 0x48, 0xb3, 0x68, 0xd1, 0xc0, 0x2c, 0x92, 0x9a, 0xe9, 0xb8, 0x9e, + 0xc9, 0xcb, 0x45, 0xee, 0x7c, 0x74, 0xfa, 0x99, 0x4b, 0xbd, 0x20, 0x3c, 0x59, 0x3c, 0xc9, 0x84, + 0xa5, 0x01, 0xf0, 0x14, 0x20, 0x22, 0xf1, 0x55, 0x87, 0x31, 0xe7, 0x8c, 0x12, 0xb3, 0xe6, 0x12, + 0xd3, 0xf3, 0x58, 0xc0, 0x8f, 0xf1, 0xe5, 0xea, 0xcb, 0x72, 0x95, 0xbf, 0x59, 0x8d, 0x53, 0x62, + 0x7a, 0x92, 0x9c, 0x5e, 0x82, 0xb3, 0x9f, 0x84, 0x20, 0xf7, 0x6e, 0x77, 0x34, 0xe8, 0x79, 0x83, + 0xfa, 0x01, 0x7a, 0x03, 0xbe, 0x10, 0x1d, 0x73, 0xe2, 0x96, 0x73, 0x60, 0x01, 0x14, 0xa6, 0x8c, + 0xe9, 0x28, 0x78, 0x58, 0xd6, 0x7f, 0x03, 0x70, 0xae, 0xaf, 0xde, 0xaf, 0x31, 0xcf, 0xa7, 0x68, + 0x1f, 0xc2, 0x28, 0x97, 0x57, 0x67, 0xd6, 0x17, 0x71, 0xb2, 0x98, 0x38, 0xaa, 0xdf, 0xf7, 0xca, + 0x86, 0x52, 0x88, 0xb2, 0xf0, 0x51, 0xad, 0xce, 0xd8, 0x69, 0x2e, 0xbd, 0x00, 0x0a, 0xd3, 0x86, + 0x78, 0x41, 0x7b, 0x70, 0x9a, 0x3f, 0x9c, 0x54, 0xa8, 0xeb, 0x54, 0x82, 0xdc, 0x04, 0xdf, 0x5e, + 0x53, 0xb6, 0x17, 0x3a, 0x36, 0x8b, 0xf8, 0x23, 0x9e, 0xb1, 0x3b, 0x79, 0x79, 0x3d, 0x9f, 0x32, + 0x32, 0xbc, 0x4a, 0x84, 0x74, 0xb3, 0x0f, 0xbc, 0xdf, 0x65, 0xff, 0x21, 0x84, 0x51, 0xbb, 0x24, + 0xf8, 0xb7, 0xb0, 0xe8, 0x2d, 0x0e, 0x7b, 0x8b, 0xc5, 0x88, 0xc8, 0xde, 0xe2, 0x63, 0xd3, 0xa1, + 0xb2, 0xd6, 0x50, 0x2a, 0xf5, 0x7f, 0x01, 0xcc, 0xf5, 0x9f, 0x21, 0x15, 0x3a, 0x82, 0x99, 0x88, + 0xa8, 0x9f, 0x03, 0x0b, 0x13, 0x85, 0xcc, 0xfa, 0xdb, 0x83, 0x24, 0x3a, 0x2c, 0x53, 0x2f, 0x70, + 0x4f, 0x5d, 0x5a, 0x56, 0xc4, 0x56, 0x37, 0x40, 0x07, 0x31, 0xd0, 0x69, 0x0e, 0x7a, 0xe9, 0x4e, + 0xd0, 0x02, 0x8c, 0x8a, 0x1a, 0x6d, 0xc2, 0xc7, 0xf7, 0xd4, 0x55, 0xe6, 0xeb, 0x3b, 0xf0, 0x35, + 0x41, 0x97, 0xa7, 0x25, 0x08, 0xfb, 0x0a, 0x9c, 0x12, 0x5b, 0x44, 0x23, 0xf5, 0x44, 0x04, 0x0e, + 0xcb, 0xfa, 0x4f, 0x00, 0xe6, 0x07, 0x95, 0x4b, 0xcd, 0x96, 0xe1, 0x8b, 0xca, 0x58, 0xd6, 0xcc, + 0xa0, 0x22, 0x84, 0x9b, 0x32, 0x9e, 0x45, 0xf1, 0xe3, 0x30, 0xfc, 0x90, 0x93, 0x63, 0xc1, 0xd7, + 0x7b, 0xba, 0x2a, 0x10, 0x7f, 0x1a, 0x98, 0x41, 0x77, 0x0e, 0x50, 0x29, 0xf1, 0x06, 0xed, 0xe6, + 0xfe, 0xbb, 0x9e, 0xcf, 0xb6, 0xcc, 0xea, 0xd9, 0x96, 0x1e, 0x5b, 0xd6, 0x7b, 0xee, 0x56, 0x07, + 0x40, 0x7d, 0xd8, 0x21, 0x52, 0x10, 0x13, 0xce, 0xb9, 0xb7, 0x93, 0x71, 0x22, 0xb5, 0xf5, 0xc3, + 0x14, 0x39, 0xb6, 0xcb, 0x49, 0xd4, 0x94, 0x61, 0x52, 0xf6, 0x9c, 0x71, 0x93, 0xc2, 0x0f, 0x29, + 0xe4, 0xaf, 0x00, 0xbe, 0xd9, 0x4b, 0x32, 0xa4, 0xe5, 0xf9, 0x0d, 0xff, 0x39, 0x8a, 0x89, 0x96, + 0xe0, 0xb3, 0x3a, 0x6d, 0xba, 0x7e, 0xb8, 0xea, 0x35, 0xaa, 0x16, 0xad, 0x73, 0x32, 0x93, 0xc6, + 0xd3, 0x6e, 0xf8, 0x88, 0x47, 0x63, 0x89, 0x0a, 0x31, 0x25, 0x51, 0x22, 0xbf, 0x06, 0x70, 0xf1, + 0x0e, 0xe4, 0xb2, 0x43, 0x25, 0x18, 0x8e, 0xa6, 0x58, 0x89, 0x75, 0x26, 0x8b, 0x85, 0x31, 0xe3, + 0xae, 0x31, 0xe3, 0x0f, 0xbc, 0x96, 0xf1, 0xd4, 0x8e, 0x6d, 0x13, 0xbf, 0x31, 0xe9, 0xf8, 0x8d, + 0x89, 0x5a, 0x33, 0x31, 0xac, 0x35, 0x93, 0x63, 0xb4, 0x66, 0xfd, 0xe7, 0x27, 0xf0, 0x11, 0x27, + 0x88, 0x7e, 0x01, 0x10, 0x46, 0x2c, 0x11, 0x1e, 0xe4, 0x50, 0xc9, 0x5f, 0x12, 0x8d, 0x8c, 0x9c, + 0x2f, 0x04, 0xd3, 0xdf, 0xff, 0xe6, 0x8f, 0x7f, 0xbe, 0x4f, 0x6f, 0xa1, 0x4d, 0x92, 0xfc, 0xfd, + 0x13, 0x9f, 0x53, 0xc5, 0xf9, 0xc8, 0x45, 0xac, 0xf9, 0x6d, 0xf4, 0x23, 0x80, 0x19, 0xc5, 0x3d, + 0xd0, 0xa8, 0x10, 0xba, 0x36, 0xa5, 0xad, 0x8d, 0x5e, 0x20, 0x41, 0xaf, 0x71, 0xd0, 0x2b, 0xa8, + 0x30, 0x2a, 0x68, 0xf4, 0x3b, 0x80, 0x2f, 0xf5, 0x19, 0x1d, 0x7a, 0x67, 0xf8, 0xc9, 0x03, 0x7c, + 0x55, 0x7b, 0xf7, 0xbe, 0x65, 0x12, 0xf6, 0x1e, 0x87, 0x5d, 0x42, 0xdb, 0xc3, 0x61, 0x8b, 0x01, + 0x8c, 0x4b, 0xde, 0x1d, 0xca, 0x36, 0xfa, 0x0b, 0xc0, 0x99, 0x44, 0x97, 0x42, 0xef, 0x8d, 0xa8, + 0x63, 0xbf, 0x7d, 0x6a, 0x5b, 0xe3, 0x94, 0x4a, 0x56, 0x1f, 0x73, 0x56, 0x07, 0x68, 0x7f, 0xdc, + 0x09, 0x22, 0xaa, 0x91, 0xa2, 0x1f, 0xd2, 0x30, 0x37, 0xe8, 0x9a, 0xa3, 0x9d, 0x51, 0x71, 0x26, + 0xf9, 0x9a, 0x56, 0x1a, 0xb3, 0x5a, 0x12, 0xfd, 0x16, 0x70, 0xa6, 0x5f, 0xa3, 0xaf, 0xc6, 0x67, + 0x1a, 0xf7, 0x26, 0xd2, 0xf5, 0x39, 0x72, 0xd1, 0xe3, 0x98, 0x6d, 0x22, 0xec, 0x44, 0x59, 0x10, + 0x81, 0xf6, 0xee, 0x67, 0x97, 0x9d, 0x3c, 0xb8, 0xea, 0xe4, 0xc1, 0xdf, 0x9d, 0x3c, 0xf8, 0xee, + 0x26, 0x9f, 0xba, 0xba, 0xc9, 0xa7, 0xfe, 0xbc, 0xc9, 0xa7, 0x3e, 0xdf, 0x76, 0xdc, 0xa0, 0xd2, + 0xb0, 0xb0, 0xcd, 0xaa, 0x44, 0xfe, 0x35, 0x16, 0x3f, 0xab, 0x7e, 0xf9, 0x0b, 0xf2, 0x65, 0x84, + 0x7a, 0x6d, 0x63, 0x55, 0x01, 0x1e, 0xb4, 0x6a, 0xd4, 0xb7, 0x1e, 0x73, 0x63, 0xdc, 0xf8, 0x3f, + 0x00, 0x00, 0xff, 0xff, 0x7c, 0x35, 0x91, 0xa4, 0xa7, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1291,13 +1291,13 @@ func (m *QueryConnectionConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x18 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x10 } @@ -1523,11 +1523,11 @@ func (m *QueryConnectionConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } return n } @@ -2588,9 +2588,9 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2600,16 +2600,16 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2619,7 +2619,7 @@ func (m *QueryConnectionConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/03-connection/types/query.pb.gw.go b/x/ibc/core/03-connection/types/query.pb.gw.go index 1d7151ad5b..3e6de4e064 100644 --- a/x/ibc/core/03-connection/types/query.pb.gw.go +++ b/x/ibc/core/03-connection/types/query.pb.gw.go @@ -251,26 +251,26 @@ func request_Query_ConnectionConsensusState_0(ctx context.Context, marshaler run return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := client.ConnectionConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -300,26 +300,26 @@ func local_request_Query_ConnectionConsensusState_0(ctx context.Context, marshal return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "connection_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := server.ConnectionConsensusState(ctx, &protoReq) @@ -586,7 +586,7 @@ var ( pattern_Query_ConnectionClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "consensus_state", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ConnectionConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 2, 7, 1, 0, 4, 1, 5, 8, 2, 9, 1, 0, 4, 1, 5, 10}, []string{"ibc", "core", "connection", "v1beta1", "connections", "connection_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( diff --git a/x/ibc/core/04-channel/client/cli/query.go b/x/ibc/core/04-channel/client/cli/query.go index cfb10183d1..69cd46e3a1 100644 --- a/x/ibc/core/04-channel/client/cli/query.go +++ b/x/ibc/core/04-channel/client/cli/query.go @@ -463,7 +463,7 @@ func GetCmdQueryNextSequenceReceive() *cobra.Command { return err } - clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight.VersionHeight)) + clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight.RevisionHeight)) return clientCtx.PrintOutput(sequenceRes) }, } diff --git a/x/ibc/core/04-channel/client/utils/utils.go b/x/ibc/core/04-channel/client/utils/utils.go index f28ffcf805..c10dc05c7f 100644 --- a/x/ibc/core/04-channel/client/utils/utils.go +++ b/x/ibc/core/04-channel/client/utils/utils.go @@ -101,10 +101,10 @@ func QueryChannelConsensusState( queryClient := types.NewQueryClient(clientCtx) req := &types.QueryChannelConsensusStateRequest{ - PortId: portID, - ChannelId: channelID, - VersionNumber: height.VersionNumber, - VersionHeight: height.VersionHeight, + PortId: portID, + ChannelId: channelID, + RevisionNumber: height.RevisionNumber, + RevisionHeight: height.RevisionHeight, } res, err := queryClient.ChannelConsensusState(context.Background(), req) diff --git a/x/ibc/core/04-channel/keeper/grpc_query.go b/x/ibc/core/04-channel/keeper/grpc_query.go index 355f192d75..30df0a33ac 100644 --- a/x/ibc/core/04-channel/keeper/grpc_query.go +++ b/x/ibc/core/04-channel/keeper/grpc_query.go @@ -182,7 +182,7 @@ func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannel ) } - consHeight := clienttypes.NewHeight(req.VersionNumber, req.VersionHeight) + consHeight := clienttypes.NewHeight(req.RevisionNumber, req.RevisionHeight) consensusState, found := q.clientKeeper.GetClientConsensusState(ctx, connection.ClientId, consHeight) if !found { return nil, status.Error( diff --git a/x/ibc/core/04-channel/keeper/grpc_query_test.go b/x/ibc/core/04-channel/keeper/grpc_query_test.go index 9e96d2b2fa..cd894520e8 100644 --- a/x/ibc/core/04-channel/keeper/grpc_query_test.go +++ b/x/ibc/core/04-channel/keeper/grpc_query_test.go @@ -439,8 +439,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "", ChannelId: "test-channel-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -451,8 +451,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "test-port-id", ChannelId: "", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -463,8 +463,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: "test-port-id", ChannelId: "test-channel-id", - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, @@ -484,8 +484,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: 0, - VersionHeight: 1, + RevisionNumber: 0, + RevisionHeight: 1, } }, false, }, @@ -497,8 +497,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: 0, - VersionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height + RevisionNumber: 0, + RevisionHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height } }, false, }, @@ -518,8 +518,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() { req = &types.QueryChannelConsensusStateRequest{ PortId: channelA.PortID, ChannelId: channelA.ID, - VersionNumber: clientState.GetLatestHeight().GetVersionNumber(), - VersionHeight: clientState.GetLatestHeight().GetVersionHeight(), + RevisionNumber: clientState.GetLatestHeight().GetRevisionNumber(), + RevisionHeight: clientState.GetLatestHeight().GetRevisionHeight(), } }, true, diff --git a/x/ibc/core/04-channel/keeper/handshake_test.go b/x/ibc/core/04-channel/keeper/handshake_test.go index 7aae08130c..120e1f8fe2 100644 --- a/x/ibc/core/04-channel/keeper/handshake_test.go +++ b/x/ibc/core/04-channel/keeper/handshake_test.go @@ -769,5 +769,5 @@ func (suite *KeeperTestSuite) TestChanCloseConfirm() { } func malleateHeight(height exported.Height, diff uint64) exported.Height { - return clienttypes.NewHeight(height.GetVersionNumber(), height.GetVersionHeight()+diff) + return clienttypes.NewHeight(height.GetRevisionNumber(), height.GetRevisionHeight()+diff) } diff --git a/x/ibc/core/04-channel/types/packet.go b/x/ibc/core/04-channel/types/packet.go index 18a3690b1e..b5c8d18043 100644 --- a/x/ibc/core/04-channel/types/packet.go +++ b/x/ibc/core/04-channel/types/packet.go @@ -12,7 +12,7 @@ import ( ) // CommitPacket returns the packet commitment bytes. The commitment consists of: -// sha256_hash(timeout_timestamp + timeout_height.VersionNumber + timeout_height.VersionHeight + sha256_hash(data)) +// sha256_hash(timeout_timestamp + timeout_height.RevisionNumber + timeout_height.RevisionHeight + sha256_hash(data)) // from a given packet. This results in a fixed length preimage. // NOTE: sdk.Uint64ToBigEndian sets the uint64 to a slice of length 8. func CommitPacket(cdc codec.BinaryMarshaler, packet exported.PacketI) []byte { @@ -20,11 +20,11 @@ func CommitPacket(cdc codec.BinaryMarshaler, packet exported.PacketI) []byte { buf := sdk.Uint64ToBigEndian(packet.GetTimeoutTimestamp()) - versionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionNumber()) - buf = append(buf, versionNumber...) + revisionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionNumber()) + buf = append(buf, revisionNumber...) - versionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetVersionHeight()) - buf = append(buf, versionHeight...) + revisionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionHeight()) + buf = append(buf, revisionHeight...) dataHash := sha256.Sum256(packet.GetData()) buf = append(buf, dataHash[:]...) diff --git a/x/ibc/core/04-channel/types/query.pb.go b/x/ibc/core/04-channel/types/query.pb.go index 7015a2acf9..d163f3d8ce 100644 --- a/x/ibc/core/04-channel/types/query.pb.go +++ b/x/ibc/core/04-channel/types/query.pb.go @@ -512,10 +512,10 @@ type QueryChannelConsensusStateRequest struct { PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` // channel unique identifier ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` - // version number of the consensus state - VersionNumber uint64 `protobuf:"varint,3,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"` - // version height of the consensus state - VersionHeight uint64 `protobuf:"varint,4,opt,name=version_height,json=versionHeight,proto3" json:"version_height,omitempty"` + // revision number of the consensus state + RevisionNumber uint64 `protobuf:"varint,3,opt,name=revision_number,json=revisionNumber,proto3" json:"revision_number,omitempty"` + // revision height of the consensus state + RevisionHeight uint64 `protobuf:"varint,4,opt,name=revision_height,json=revisionHeight,proto3" json:"revision_height,omitempty"` } func (m *QueryChannelConsensusStateRequest) Reset() { *m = QueryChannelConsensusStateRequest{} } @@ -565,16 +565,16 @@ func (m *QueryChannelConsensusStateRequest) GetChannelId() string { return "" } -func (m *QueryChannelConsensusStateRequest) GetVersionNumber() uint64 { +func (m *QueryChannelConsensusStateRequest) GetRevisionNumber() uint64 { if m != nil { - return m.VersionNumber + return m.RevisionNumber } return 0 } -func (m *QueryChannelConsensusStateRequest) GetVersionHeight() uint64 { +func (m *QueryChannelConsensusStateRequest) GetRevisionHeight() uint64 { if m != nil { - return m.VersionHeight + return m.RevisionHeight } return 0 } @@ -1699,100 +1699,100 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/query.proto", fileDescriptor_1034a1e9abc4cca1) } var fileDescriptor_1034a1e9abc4cca1 = []byte{ - // 1487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xdf, 0x6b, 0x14, 0xd7, - 0x17, 0xcf, 0xdd, 0x44, 0x4d, 0x8e, 0xbf, 0x6f, 0x12, 0x8d, 0x63, 0x5c, 0xe3, 0x7e, 0xbf, 0x6d, - 0xa3, 0xe0, 0x5c, 0x13, 0xad, 0x15, 0x8a, 0x2d, 0x31, 0x50, 0x1b, 0x50, 0x6b, 0x47, 0x6d, 0x55, - 0x5a, 0x97, 0xd9, 0xd9, 0xeb, 0x66, 0x48, 0x32, 0xb3, 0xee, 0xcc, 0xc6, 0x84, 0xb0, 0xd0, 0x56, - 0x90, 0x52, 0x2a, 0x14, 0xa4, 0x14, 0xfa, 0xd2, 0x97, 0x42, 0xf1, 0xb1, 0xff, 0x43, 0x1f, 0x7c, - 0xe8, 0x83, 0xd0, 0x16, 0x2c, 0x05, 0x2b, 0x5a, 0xa8, 0x0f, 0x7d, 0x6e, 0x5f, 0xcb, 0xdc, 0x7b, - 0xe6, 0xd7, 0xee, 0xcc, 0x24, 0xeb, 0x66, 0x41, 0xfa, 0x94, 0x9d, 0x3b, 0xe7, 0x9c, 0xfb, 0xf9, - 0x7c, 0xce, 0x3d, 0x67, 0xef, 0xd9, 0xc0, 0x7e, 0xb3, 0x64, 0x30, 0xc3, 0xae, 0x71, 0x66, 0xcc, - 0xea, 0x96, 0xc5, 0xe7, 0xd9, 0xe2, 0x04, 0xbb, 0x51, 0xe7, 0xb5, 0x65, 0xb5, 0x5a, 0xb3, 0x5d, - 0x9b, 0x0e, 0x9a, 0x25, 0x43, 0xf5, 0x0c, 0x54, 0x34, 0x50, 0x17, 0x27, 0x94, 0x88, 0xd7, 0xbc, - 0xc9, 0x2d, 0xd7, 0x73, 0x92, 0x9f, 0xa4, 0x97, 0x72, 0xc8, 0xb0, 0x9d, 0x05, 0xdb, 0x61, 0x25, - 0xdd, 0xe1, 0x32, 0x1c, 0x5b, 0x9c, 0x28, 0x71, 0x57, 0x9f, 0x60, 0x55, 0xbd, 0x62, 0x5a, 0xba, - 0x6b, 0xda, 0x16, 0xda, 0x1e, 0x48, 0x82, 0xe0, 0x6f, 0x26, 0x4d, 0x46, 0x2b, 0xb6, 0x5d, 0x99, - 0xe7, 0x4c, 0xaf, 0x9a, 0x4c, 0xb7, 0x2c, 0xdb, 0x15, 0xfe, 0x0e, 0xbe, 0xdd, 0x83, 0x6f, 0xc5, - 0x53, 0xa9, 0x7e, 0x9d, 0xe9, 0x16, 0xa2, 0x57, 0x86, 0x2a, 0x76, 0xc5, 0x16, 0x1f, 0x99, 0xf7, - 0x49, 0xae, 0x16, 0xce, 0xc2, 0xe0, 0xbb, 0x1e, 0xa6, 0x69, 0xb9, 0x89, 0xc6, 0x6f, 0xd4, 0xb9, - 0xe3, 0xd2, 0xdd, 0xb0, 0xa9, 0x6a, 0xd7, 0xdc, 0xa2, 0x59, 0x1e, 0x21, 0x63, 0x64, 0x7c, 0x40, - 0xdb, 0xe8, 0x3d, 0xce, 0x94, 0xe9, 0x3e, 0x00, 0xc4, 0xe3, 0xbd, 0xcb, 0x89, 0x77, 0x03, 0xb8, - 0x32, 0x53, 0x2e, 0xdc, 0x23, 0x30, 0x14, 0x8f, 0xe7, 0x54, 0x6d, 0xcb, 0xe1, 0xf4, 0x38, 0x6c, - 0x42, 0x2b, 0x11, 0x70, 0xf3, 0xe4, 0xa8, 0x9a, 0xa0, 0xa6, 0xea, 0xbb, 0xf9, 0xc6, 0x74, 0x08, - 0x36, 0x54, 0x6b, 0xb6, 0x7d, 0x5d, 0x6c, 0xb5, 0x45, 0x93, 0x0f, 0x74, 0x1a, 0xb6, 0x88, 0x0f, - 0xc5, 0x59, 0x6e, 0x56, 0x66, 0xdd, 0x91, 0x5e, 0x11, 0x52, 0x89, 0x84, 0x94, 0x19, 0x58, 0x9c, - 0x50, 0xdf, 0x16, 0x16, 0xa7, 0xfa, 0xee, 0x3f, 0xda, 0xdf, 0xa3, 0x6d, 0x16, 0x5e, 0x72, 0xa9, - 0x70, 0x2d, 0x0e, 0xd5, 0xf1, 0xb9, 0xbf, 0x05, 0x10, 0x26, 0x06, 0xd1, 0xbe, 0xac, 0xca, 0x2c, - 0xaa, 0x5e, 0x16, 0x55, 0x79, 0x28, 0x30, 0x8b, 0xea, 0x79, 0xbd, 0xc2, 0xd1, 0x57, 0x8b, 0x78, - 0x16, 0x1e, 0x11, 0x18, 0x6e, 0xda, 0x00, 0xc5, 0x38, 0x05, 0xfd, 0xc8, 0xcf, 0x19, 0x21, 0x63, - 0xbd, 0x22, 0x7e, 0x92, 0x1a, 0x33, 0x65, 0x6e, 0xb9, 0xe6, 0x75, 0x93, 0x97, 0x7d, 0x5d, 0x02, - 0x3f, 0x7a, 0x3a, 0x86, 0x32, 0x27, 0x50, 0xbe, 0xb2, 0x2a, 0x4a, 0x09, 0x20, 0x0a, 0x93, 0x9e, - 0x80, 0x8d, 0x6d, 0xaa, 0x88, 0xf6, 0x85, 0x4f, 0x09, 0xe4, 0x25, 0x41, 0xdb, 0xb2, 0xb8, 0xe1, - 0x45, 0x6b, 0xd6, 0x32, 0x0f, 0x60, 0x04, 0x2f, 0xf1, 0x28, 0x45, 0x56, 0x9a, 0xb4, 0xce, 0x3d, - 0xb7, 0xd6, 0xcf, 0x08, 0xec, 0x4f, 0x85, 0xf2, 0xdf, 0x52, 0xfd, 0xb2, 0x2f, 0xba, 0xc4, 0x34, - 0x2d, 0xac, 0x2f, 0xb8, 0xba, 0xcb, 0x3b, 0x2d, 0xde, 0xdf, 0x03, 0x11, 0x13, 0x42, 0xa3, 0x88, - 0x3a, 0xec, 0x36, 0x03, 0x7d, 0x8a, 0x12, 0x6a, 0xd1, 0xf1, 0x4c, 0xb0, 0x52, 0x0e, 0x26, 0x11, - 0x89, 0x48, 0x1a, 0x89, 0x39, 0x6c, 0x26, 0x2d, 0x77, 0xb3, 0xe4, 0xef, 0x11, 0x38, 0x10, 0x63, - 0xe8, 0x71, 0xb2, 0x9c, 0xba, 0xb3, 0x1e, 0xfa, 0xd1, 0x97, 0x60, 0xdb, 0x22, 0xaf, 0x39, 0xa6, - 0x6d, 0x15, 0xad, 0xfa, 0x42, 0x89, 0xd7, 0x04, 0xc8, 0x3e, 0x6d, 0x2b, 0xae, 0x9e, 0x13, 0x8b, - 0x51, 0x33, 0xe4, 0xd2, 0x17, 0x33, 0x43, 0xac, 0xbf, 0x11, 0x28, 0x64, 0x61, 0xc5, 0x84, 0x9c, - 0x84, 0xed, 0x86, 0xff, 0x26, 0x96, 0x88, 0x21, 0x55, 0x7e, 0x17, 0xa8, 0xfe, 0x77, 0x81, 0x3a, - 0x65, 0x2d, 0x6b, 0xdb, 0x8c, 0x58, 0x18, 0xba, 0x17, 0x06, 0x30, 0x89, 0x01, 0xa3, 0x7e, 0xb9, - 0x30, 0x53, 0x0e, 0x33, 0xd1, 0x9b, 0x95, 0x89, 0xbe, 0xe7, 0xc9, 0x44, 0x0d, 0x46, 0x05, 0xb9, - 0xf3, 0xba, 0x31, 0xc7, 0xdd, 0x69, 0x7b, 0x61, 0xc1, 0x74, 0x17, 0xb8, 0xe5, 0x76, 0x9a, 0x03, - 0x05, 0xfa, 0x1d, 0x2f, 0x84, 0x65, 0x70, 0x54, 0x3f, 0x78, 0x2e, 0x7c, 0x4d, 0x60, 0x5f, 0xca, - 0xa6, 0x28, 0xa6, 0x68, 0x57, 0xfe, 0xaa, 0xd8, 0x78, 0x8b, 0x16, 0x59, 0xe9, 0xe6, 0xd1, 0xfc, - 0x26, 0x0d, 0x9c, 0xd3, 0xa9, 0x24, 0xf1, 0x1e, 0xdb, 0xfb, 0xdc, 0x3d, 0xf6, 0x4f, 0xbf, 0xdd, - 0x27, 0x20, 0x0c, 0x5a, 0xec, 0xe6, 0x50, 0x2d, 0xbf, 0xcb, 0x8e, 0x25, 0x76, 0x59, 0x19, 0x44, - 0x9e, 0xe5, 0xa8, 0xd3, 0x8b, 0xd0, 0x62, 0x6d, 0xd8, 0x13, 0x21, 0xaa, 0x71, 0x83, 0x9b, 0xd5, - 0xae, 0x9e, 0xcc, 0xbb, 0x04, 0x94, 0xa4, 0x1d, 0x51, 0x56, 0x05, 0xfa, 0x6b, 0xde, 0xd2, 0x22, - 0x97, 0x71, 0xfb, 0xb5, 0xe0, 0xb9, 0x9b, 0x35, 0x7a, 0x13, 0x9b, 0xa5, 0x04, 0x35, 0x65, 0xcc, - 0x59, 0xf6, 0xcd, 0x79, 0x5e, 0xae, 0xf0, 0x6e, 0x17, 0xea, 0x3d, 0xbf, 0xf5, 0xa5, 0xec, 0x8c, - 0xb2, 0x8c, 0xc3, 0x76, 0x3d, 0xfe, 0x0a, 0x4b, 0xb6, 0x79, 0xb9, 0x9b, 0x75, 0xfb, 0x6d, 0x26, - 0xd6, 0x17, 0xa6, 0x78, 0xff, 0x26, 0xf0, 0xbf, 0x4c, 0x98, 0xa8, 0xe9, 0x19, 0xd8, 0xd1, 0x24, - 0xde, 0xda, 0xcb, 0xb8, 0xc5, 0xf3, 0x45, 0xa8, 0xe5, 0xaf, 0xfc, 0xbe, 0x7a, 0xc9, 0xf2, 0x6b, - 0x46, 0x62, 0xee, 0x38, 0x35, 0x6f, 0xc0, 0xde, 0xaa, 0x88, 0x54, 0x0c, 0xdb, 0x57, 0xd1, 0x3f, - 0xc3, 0xce, 0x48, 0xef, 0x58, 0xef, 0x78, 0x9f, 0xb6, 0xa7, 0xda, 0xd4, 0x2c, 0x2f, 0xf8, 0x06, - 0x85, 0x25, 0x6c, 0xa7, 0x09, 0xc0, 0x30, 0x19, 0xa3, 0x30, 0x10, 0xc6, 0x23, 0x22, 0x5e, 0xb8, - 0x10, 0xd1, 0x24, 0xd7, 0xa6, 0x26, 0xb7, 0xfd, 0x76, 0x13, 0x6e, 0x3d, 0x65, 0xcc, 0x75, 0x2c, - 0xc8, 0x11, 0x18, 0x42, 0x41, 0x74, 0x63, 0xae, 0x45, 0x09, 0x5a, 0xf5, 0x4f, 0x5e, 0x28, 0x41, - 0x1d, 0xf6, 0x26, 0xe2, 0xe8, 0x32, 0xff, 0x2b, 0x78, 0xcf, 0x3d, 0xc7, 0x97, 0x82, 0x7c, 0x68, - 0x12, 0x40, 0xa7, 0x77, 0xe8, 0xef, 0x09, 0x8c, 0xa5, 0xc7, 0x46, 0x5e, 0x93, 0x30, 0x6c, 0xf1, - 0xa5, 0xf0, 0xb0, 0x14, 0x91, 0xbd, 0xd8, 0xaa, 0x4f, 0x1b, 0xb4, 0x5a, 0x7d, 0xbb, 0xd8, 0xc2, - 0x26, 0x7f, 0xdc, 0x05, 0x1b, 0x04, 0x66, 0xfa, 0x1d, 0x81, 0x4d, 0x78, 0xdd, 0xa4, 0xe3, 0x89, - 0xf5, 0x9e, 0xf0, 0x63, 0x81, 0x72, 0x70, 0x0d, 0x96, 0x92, 0x79, 0xe1, 0xf4, 0x27, 0x3f, 0xfd, - 0x71, 0x37, 0x37, 0x45, 0xdf, 0x64, 0x09, 0xbf, 0x74, 0xc8, 0x1f, 0x45, 0xfc, 0x59, 0x8b, 0xad, - 0x84, 0x3a, 0x37, 0x98, 0xa7, 0xbe, 0xc3, 0x56, 0x30, 0x27, 0x0d, 0x7a, 0x87, 0x40, 0xbf, 0x3f, - 0xe1, 0xd1, 0xd5, 0x01, 0xf8, 0x67, 0x5b, 0x39, 0xb4, 0x16, 0x53, 0x04, 0x7b, 0x48, 0x80, 0xfd, - 0x3f, 0x2d, 0xac, 0x0e, 0x96, 0xfe, 0x40, 0x80, 0xb6, 0xce, 0x9e, 0xf4, 0x68, 0xc6, 0x76, 0x69, - 0x43, 0xb3, 0x72, 0xac, 0x3d, 0x27, 0x44, 0x3b, 0x2d, 0xd0, 0x9e, 0xa4, 0xaf, 0x67, 0xa0, 0x0d, - 0xbc, 0x3d, 0x75, 0x83, 0x87, 0x46, 0x48, 0xe3, 0x17, 0x8f, 0x46, 0xcb, 0xf4, 0x97, 0x49, 0x23, - 0x6d, 0x0c, 0xcd, 0xa4, 0x91, 0x3a, 0x60, 0x16, 0x2e, 0x0a, 0x1a, 0xe7, 0xe8, 0x99, 0x0e, 0x4f, - 0x08, 0x8b, 0xce, 0xa6, 0xf4, 0xcb, 0x1c, 0x0c, 0x27, 0xce, 0x51, 0xf4, 0xf8, 0xea, 0x28, 0x93, - 0x86, 0x44, 0xe5, 0xb5, 0xb6, 0xfd, 0x90, 0xe0, 0x67, 0x44, 0x30, 0xbc, 0x45, 0xe8, 0x47, 0xa4, - 0x63, 0x8e, 0xf1, 0xc9, 0x8f, 0xe1, 0x04, 0xc9, 0x56, 0xe2, 0x73, 0x68, 0x83, 0xc9, 0xf6, 0x10, - 0xae, 0xcb, 0xe7, 0x06, 0x7d, 0x4c, 0x60, 0x47, 0xf3, 0x75, 0x9e, 0x4e, 0xa4, 0x53, 0x4b, 0x19, - 0xd7, 0x94, 0xc9, 0x76, 0x5c, 0x50, 0x08, 0x2e, 0x74, 0x28, 0xd2, 0x0f, 0x3b, 0x55, 0xa1, 0xe5, - 0x5b, 0xd8, 0x61, 0x2b, 0x7e, 0x6b, 0x6d, 0xd0, 0x87, 0x04, 0x76, 0xb6, 0x4c, 0x2c, 0xb4, 0x0d, - 0xc0, 0x41, 0x5d, 0x1e, 0x6d, 0xcb, 0x07, 0x59, 0x5e, 0x15, 0x2c, 0x2f, 0x52, 0x6d, 0xfd, 0x59, - 0xd2, 0x9f, 0x09, 0x6c, 0x8d, 0x4d, 0x0c, 0x54, 0x5d, 0x0d, 0x62, 0x7c, 0x98, 0x51, 0xd8, 0x9a, - 0xed, 0x91, 0x4e, 0x49, 0xd0, 0xf9, 0x80, 0x5e, 0x5d, 0x27, 0x3a, 0x35, 0x19, 0x3f, 0x96, 0xb1, - 0x67, 0x04, 0x86, 0x13, 0xaf, 0xa9, 0x59, 0xc5, 0x9a, 0x35, 0xa4, 0x64, 0x15, 0x6b, 0xe6, 0x88, - 0x51, 0xb8, 0x26, 0xe8, 0x5e, 0xa6, 0xef, 0xad, 0x13, 0x5d, 0xdd, 0x98, 0x8b, 0x51, 0xfd, 0x8b, - 0xc0, 0xae, 0xe4, 0x1b, 0x39, 0x6d, 0x17, 0x73, 0x70, 0x4c, 0x4f, 0xb4, 0xef, 0x88, 0x6c, 0x8b, - 0x82, 0xed, 0x15, 0xfa, 0xfe, 0xfa, 0xb1, 0x8d, 0x73, 0xfa, 0x3c, 0x07, 0x3b, 0x5b, 0xae, 0xbb, - 0x59, 0xb5, 0x98, 0x76, 0x69, 0xcf, 0xaa, 0xc5, 0xd4, 0xfb, 0x74, 0xe1, 0x8e, 0x6c, 0xbd, 0xb7, - 0x09, 0xbd, 0x45, 0xba, 0xd1, 0x74, 0x32, 0xc6, 0x81, 0x06, 0xab, 0x07, 0xb0, 0x8a, 0x55, 0x24, - 0xfe, 0x0f, 0x81, 0x6d, 0xf1, 0xab, 0x2f, 0x65, 0x6b, 0xe1, 0x15, 0xb9, 0xac, 0x2b, 0x47, 0xd6, - 0xee, 0x80, 0x2a, 0x7c, 0x2c, 0x55, 0x58, 0xa1, 0xcb, 0x5d, 0xd4, 0x20, 0x36, 0x01, 0xc4, 0xc8, - 0x7b, 0x25, 0x40, 0x7f, 0x25, 0x30, 0x98, 0x70, 0x43, 0xa6, 0x19, 0x77, 0x86, 0xf4, 0xcb, 0xba, - 0xf2, 0x6a, 0x9b, 0x5e, 0x28, 0xc4, 0x25, 0xa1, 0xc3, 0x3b, 0xf4, 0x6c, 0xa7, 0x3a, 0xc4, 0x2e, - 0xf3, 0xa7, 0xb4, 0xfb, 0x4f, 0xf2, 0xe4, 0xc1, 0x93, 0x3c, 0x79, 0xfc, 0x24, 0x4f, 0xbe, 0x78, - 0x9a, 0xef, 0x79, 0xf0, 0x34, 0xdf, 0xf3, 0xf0, 0x69, 0xbe, 0xe7, 0xea, 0x89, 0x8a, 0xe9, 0xce, - 0xd6, 0x4b, 0xaa, 0x61, 0x2f, 0x30, 0xfc, 0xaf, 0xa0, 0xfc, 0x73, 0xd8, 0x29, 0xcf, 0xb1, 0xa5, - 0x10, 0xc6, 0x91, 0x63, 0x87, 0x7d, 0x24, 0xee, 0x72, 0x95, 0x3b, 0xa5, 0x8d, 0xe2, 0x47, 0xdc, - 0xa3, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x48, 0x61, 0x15, 0x26, 0xa4, 0x1c, 0x00, 0x00, + // 1482 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xdd, 0x6f, 0x14, 0x55, + 0x14, 0xef, 0xdd, 0x16, 0x68, 0x0f, 0xc8, 0xc7, 0x6d, 0x0b, 0x65, 0x28, 0x4b, 0x19, 0x8d, 0x14, + 0x12, 0xe6, 0xd2, 0x82, 0x48, 0x62, 0xd0, 0x94, 0x26, 0x62, 0x13, 0x40, 0x1c, 0x40, 0x81, 0x28, + 0x9b, 0xd9, 0xd9, 0xcb, 0x76, 0xd2, 0x76, 0x66, 0xd8, 0x99, 0x2d, 0x6d, 0x9a, 0x7d, 0x50, 0x13, + 0xe2, 0x83, 0x24, 0x26, 0x3c, 0x68, 0x7c, 0xf1, 0xc5, 0xc4, 0xf0, 0xe0, 0x83, 0xff, 0x83, 0x0f, + 0xbc, 0x49, 0xa2, 0x26, 0x18, 0x13, 0x24, 0x60, 0x22, 0x0f, 0x3e, 0xeb, 0xab, 0x99, 0xfb, 0x31, + 0x1f, 0xbb, 0x33, 0xd3, 0x2e, 0xdb, 0x4d, 0x1a, 0x9f, 0xba, 0x73, 0xe7, 0x9c, 0x73, 0x7f, 0xbf, + 0xdf, 0xb9, 0xe7, 0xec, 0x3d, 0x5b, 0x38, 0x60, 0x95, 0x4d, 0x62, 0x3a, 0x35, 0x4a, 0xcc, 0x59, + 0xc3, 0xb6, 0xe9, 0x3c, 0x59, 0x9c, 0x20, 0xb7, 0xea, 0xb4, 0xb6, 0xac, 0xb9, 0x35, 0xc7, 0x77, + 0xf0, 0xa0, 0x55, 0x36, 0xb5, 0xc0, 0x40, 0x13, 0x06, 0xda, 0xe2, 0x84, 0x12, 0xf3, 0x9a, 0xb7, + 0xa8, 0xed, 0x07, 0x4e, 0xfc, 0x13, 0xf7, 0x52, 0x8e, 0x98, 0x8e, 0xb7, 0xe0, 0x78, 0xa4, 0x6c, + 0x78, 0x94, 0x87, 0x23, 0x8b, 0x13, 0x65, 0xea, 0x1b, 0x13, 0xc4, 0x35, 0xaa, 0x96, 0x6d, 0xf8, + 0x96, 0x63, 0x0b, 0xdb, 0x83, 0x69, 0x10, 0xe4, 0x66, 0xdc, 0x64, 0xb4, 0xea, 0x38, 0xd5, 0x79, + 0x4a, 0x0c, 0xd7, 0x22, 0x86, 0x6d, 0x3b, 0x3e, 0xf3, 0xf7, 0xc4, 0xdb, 0xbd, 0xe2, 0x2d, 0x7b, + 0x2a, 0xd7, 0x6f, 0x12, 0xc3, 0x16, 0xe8, 0x95, 0xa1, 0xaa, 0x53, 0x75, 0xd8, 0x47, 0x12, 0x7c, + 0xe2, 0xab, 0xea, 0x79, 0x18, 0x7c, 0x2f, 0xc0, 0x34, 0xcd, 0x37, 0xd1, 0xe9, 0xad, 0x3a, 0xf5, + 0x7c, 0xbc, 0x07, 0xb6, 0xb8, 0x4e, 0xcd, 0x2f, 0x59, 0x95, 0x11, 0x34, 0x86, 0xc6, 0x07, 0xf4, + 0xcd, 0xc1, 0xe3, 0x4c, 0x05, 0xef, 0x07, 0x10, 0x78, 0x82, 0x77, 0x05, 0xf6, 0x6e, 0x40, 0xac, + 0xcc, 0x54, 0xd4, 0xfb, 0x08, 0x86, 0x92, 0xf1, 0x3c, 0xd7, 0xb1, 0x3d, 0x8a, 0x4f, 0xc2, 0x16, + 0x61, 0xc5, 0x02, 0x6e, 0x9d, 0x1c, 0xd5, 0x52, 0xd4, 0xd4, 0xa4, 0x9b, 0x34, 0xc6, 0x43, 0xb0, + 0xc9, 0xad, 0x39, 0xce, 0x4d, 0xb6, 0xd5, 0x36, 0x9d, 0x3f, 0xe0, 0x69, 0xd8, 0xc6, 0x3e, 0x94, + 0x66, 0xa9, 0x55, 0x9d, 0xf5, 0x47, 0x7a, 0x59, 0x48, 0x25, 0x16, 0x92, 0x67, 0x60, 0x71, 0x42, + 0x7b, 0x87, 0x59, 0x9c, 0xe9, 0x7b, 0xf0, 0xf8, 0x40, 0x8f, 0xbe, 0x95, 0x79, 0xf1, 0x25, 0xf5, + 0x46, 0x12, 0xaa, 0x27, 0xb9, 0xbf, 0x0d, 0x10, 0x25, 0x46, 0xa0, 0x7d, 0x55, 0xe3, 0x59, 0xd4, + 0x82, 0x2c, 0x6a, 0xfc, 0x50, 0x88, 0x2c, 0x6a, 0x17, 0x8d, 0x2a, 0x15, 0xbe, 0x7a, 0xcc, 0x53, + 0x7d, 0x8c, 0x60, 0xb8, 0x69, 0x03, 0x21, 0xc6, 0x19, 0xe8, 0x17, 0xfc, 0xbc, 0x11, 0x34, 0xd6, + 0xcb, 0xe2, 0xa7, 0xa9, 0x31, 0x53, 0xa1, 0xb6, 0x6f, 0xdd, 0xb4, 0x68, 0x45, 0xea, 0x12, 0xfa, + 0xe1, 0xb3, 0x09, 0x94, 0x05, 0x86, 0xf2, 0xd0, 0xaa, 0x28, 0x39, 0x80, 0x38, 0x4c, 0x7c, 0x0a, + 0x36, 0xb7, 0xa9, 0xa2, 0xb0, 0x57, 0x3f, 0x43, 0x50, 0xe4, 0x04, 0x1d, 0xdb, 0xa6, 0x66, 0x10, + 0xad, 0x59, 0xcb, 0x22, 0x80, 0x19, 0xbe, 0x14, 0x47, 0x29, 0xb6, 0xd2, 0xa4, 0x75, 0xe1, 0x85, + 0xb5, 0x7e, 0x8e, 0xe0, 0x40, 0x26, 0x94, 0xff, 0x97, 0xea, 0x57, 0xa5, 0xe8, 0x1c, 0xd3, 0x34, + 0xb3, 0xbe, 0xe4, 0x1b, 0x3e, 0xed, 0xb4, 0x78, 0xff, 0x08, 0x45, 0x4c, 0x09, 0x2d, 0x44, 0x34, + 0x60, 0x8f, 0x15, 0xea, 0x53, 0xe2, 0x50, 0x4b, 0x5e, 0x60, 0x22, 0x2a, 0xe5, 0x70, 0x1a, 0x91, + 0x98, 0xa4, 0xb1, 0x98, 0xc3, 0x56, 0xda, 0x72, 0x37, 0x4b, 0xfe, 0x7b, 0x04, 0x07, 0x13, 0x0c, + 0x03, 0x4e, 0xb6, 0x57, 0xf7, 0xd6, 0x43, 0x3f, 0x7c, 0x08, 0x76, 0xd4, 0xe8, 0xa2, 0xe5, 0x59, + 0x8e, 0x5d, 0xb2, 0xeb, 0x0b, 0x65, 0x5a, 0x63, 0x28, 0xfb, 0xf4, 0xed, 0x72, 0xf9, 0x02, 0x5b, + 0x4d, 0x18, 0x0a, 0x3a, 0x7d, 0x49, 0x43, 0x81, 0xf7, 0x77, 0x04, 0x6a, 0x1e, 0x5e, 0x91, 0x94, + 0xd3, 0xb0, 0xc3, 0x94, 0x6f, 0x12, 0xc9, 0x18, 0xd2, 0xf8, 0xf7, 0x81, 0x26, 0xbf, 0x0f, 0xb4, + 0x29, 0x7b, 0x59, 0xdf, 0x6e, 0x26, 0xc2, 0xe0, 0x7d, 0x30, 0x20, 0x12, 0x19, 0xb2, 0xea, 0xe7, + 0x0b, 0x33, 0x95, 0x28, 0x1b, 0xbd, 0x79, 0xd9, 0xe8, 0x7b, 0x91, 0x6c, 0xd4, 0x60, 0x94, 0x91, + 0xbb, 0x68, 0x98, 0x73, 0xd4, 0x9f, 0x76, 0x16, 0x16, 0x2c, 0x7f, 0x81, 0xda, 0x7e, 0xa7, 0x79, + 0x50, 0xa0, 0xdf, 0x0b, 0x42, 0xd8, 0x26, 0x15, 0x09, 0x08, 0x9f, 0xd5, 0xaf, 0x11, 0xec, 0xcf, + 0xd8, 0x54, 0x88, 0xc9, 0x5a, 0x96, 0x5c, 0x65, 0x1b, 0x6f, 0xd3, 0x63, 0x2b, 0xdd, 0x3c, 0x9e, + 0xdf, 0x64, 0x81, 0xf3, 0x3a, 0x95, 0x24, 0xd9, 0x67, 0x7b, 0x5f, 0xb8, 0xcf, 0xfe, 0x25, 0x5b, + 0x7e, 0x0a, 0xc2, 0xb0, 0xcd, 0x6e, 0x8d, 0xd4, 0x92, 0x9d, 0x76, 0x2c, 0xb5, 0xd3, 0xf2, 0x20, + 0xfc, 0x2c, 0xc7, 0x9d, 0x36, 0x42, 0x9b, 0x75, 0x60, 0x6f, 0x8c, 0xa8, 0x4e, 0x4d, 0x6a, 0xb9, + 0x5d, 0x3d, 0x99, 0xf7, 0x10, 0x28, 0x69, 0x3b, 0x0a, 0x59, 0x15, 0xe8, 0xaf, 0x05, 0x4b, 0x8b, + 0x94, 0xc7, 0xed, 0xd7, 0xc3, 0xe7, 0x6e, 0xd6, 0xe8, 0x6d, 0xd1, 0x30, 0x39, 0xa8, 0x29, 0x73, + 0xce, 0x76, 0x6e, 0xcf, 0xd3, 0x4a, 0x95, 0x76, 0xbb, 0x50, 0xef, 0xcb, 0xd6, 0x97, 0xb1, 0xb3, + 0x90, 0x65, 0x1c, 0x76, 0x18, 0xc9, 0x57, 0xa2, 0x64, 0x9b, 0x97, 0xbb, 0x59, 0xb7, 0xdf, 0xe6, + 0x62, 0xdd, 0x30, 0xc5, 0xfb, 0x0f, 0x82, 0x97, 0x73, 0x61, 0x0a, 0x4d, 0xcf, 0xc1, 0xce, 0x26, + 0xf1, 0xd6, 0x5e, 0xc6, 0x2d, 0x9e, 0x1b, 0xa1, 0x96, 0xbf, 0x94, 0x7d, 0xf5, 0x8a, 0x2d, 0x6b, + 0x86, 0x63, 0xee, 0x38, 0x35, 0x6f, 0xc2, 0x3e, 0x97, 0x45, 0x2a, 0x45, 0xed, 0xab, 0x24, 0xcf, + 0xb0, 0x37, 0xd2, 0x3b, 0xd6, 0x3b, 0xde, 0xa7, 0xef, 0x75, 0x9b, 0x9a, 0xe5, 0x25, 0x69, 0xa0, + 0x2e, 0x89, 0x76, 0x9a, 0x02, 0x4c, 0x24, 0x63, 0x14, 0x06, 0xa2, 0x78, 0x88, 0xc5, 0x8b, 0x16, + 0x62, 0x9a, 0x14, 0xda, 0xd4, 0xe4, 0x8e, 0x6c, 0x37, 0xd1, 0xd6, 0x53, 0xe6, 0x5c, 0xc7, 0x82, + 0x1c, 0x83, 0x21, 0x21, 0x88, 0x61, 0xce, 0xb5, 0x28, 0x81, 0x5d, 0x79, 0xf2, 0x22, 0x09, 0xea, + 0xb0, 0x2f, 0x15, 0x47, 0x97, 0xf9, 0x5f, 0x13, 0x77, 0xdd, 0x0b, 0x74, 0x29, 0xcc, 0x87, 0xce, + 0x01, 0x74, 0x7a, 0x8f, 0xfe, 0x01, 0xc1, 0x58, 0x76, 0x6c, 0xc1, 0x6b, 0x12, 0x86, 0x6d, 0xba, + 0x14, 0x1d, 0x96, 0x92, 0x60, 0xcf, 0xb6, 0xea, 0xd3, 0x07, 0xed, 0x56, 0xdf, 0x2e, 0xb6, 0xb0, + 0xc9, 0x9f, 0x76, 0xc3, 0x26, 0x86, 0x19, 0x7f, 0x87, 0x60, 0x8b, 0xb8, 0x6e, 0xe2, 0xf1, 0xd4, + 0x7a, 0x4f, 0xf9, 0xc1, 0x40, 0x39, 0xbc, 0x06, 0x4b, 0xce, 0x5c, 0x3d, 0xfb, 0xc9, 0xcf, 0x7f, + 0xde, 0x2b, 0x4c, 0xe1, 0xb7, 0x48, 0xca, 0xaf, 0x1d, 0xfc, 0x87, 0x11, 0x39, 0x6f, 0x91, 0x95, + 0x48, 0xe7, 0x06, 0x09, 0xd4, 0xf7, 0xc8, 0x8a, 0xc8, 0x49, 0x03, 0xdf, 0x45, 0xd0, 0x2f, 0xa7, + 0x3c, 0xbc, 0x3a, 0x00, 0x79, 0xb6, 0x95, 0x23, 0x6b, 0x31, 0x15, 0x60, 0x8f, 0x30, 0xb0, 0xaf, + 0x60, 0x75, 0x75, 0xb0, 0xf8, 0x47, 0x04, 0xb8, 0x75, 0xfe, 0xc4, 0xc7, 0x73, 0xb6, 0xcb, 0x1a, + 0x9c, 0x95, 0x13, 0xed, 0x39, 0x09, 0xb4, 0xd3, 0x0c, 0xed, 0x69, 0xfc, 0x46, 0x0e, 0xda, 0xd0, + 0x3b, 0x50, 0x37, 0x7c, 0x68, 0x44, 0x34, 0x7e, 0x0d, 0x68, 0xb4, 0x4c, 0x80, 0xb9, 0x34, 0xb2, + 0x46, 0xd1, 0x5c, 0x1a, 0x99, 0x43, 0xa6, 0x7a, 0x99, 0xd1, 0xb8, 0x80, 0xcf, 0x75, 0x78, 0x42, + 0x48, 0x7c, 0x3e, 0xc5, 0x5f, 0x15, 0x60, 0x38, 0x75, 0x8e, 0xc2, 0x27, 0x57, 0x47, 0x99, 0x36, + 0x28, 0x2a, 0xaf, 0xb7, 0xed, 0x27, 0x08, 0xde, 0x45, 0x8c, 0xe1, 0x1d, 0x84, 0x3f, 0x45, 0x1d, + 0x73, 0x4c, 0x4e, 0x7e, 0x44, 0x8e, 0x90, 0x64, 0xa5, 0x69, 0x18, 0x6d, 0x10, 0xde, 0x20, 0x62, + 0x2f, 0xf8, 0x42, 0x03, 0x3f, 0x41, 0xb0, 0xb3, 0xf9, 0x46, 0x8f, 0x27, 0xb2, 0xd9, 0x65, 0x4c, + 0x6c, 0xca, 0x64, 0x3b, 0x2e, 0x42, 0x0b, 0xca, 0xa4, 0x28, 0xe1, 0x8f, 0x3a, 0x15, 0xa2, 0xe5, + 0x8b, 0xd8, 0x23, 0x2b, 0xb2, 0xbb, 0x36, 0xf0, 0x23, 0x04, 0xbb, 0x5a, 0x86, 0x16, 0xdc, 0x06, + 0xe0, 0xb0, 0x34, 0x8f, 0xb7, 0xe5, 0x23, 0x58, 0x5e, 0x67, 0x2c, 0x2f, 0x63, 0x7d, 0xfd, 0x59, + 0xe2, 0x5f, 0x10, 0xbc, 0x94, 0x18, 0x1a, 0xb0, 0xb6, 0x1a, 0xc4, 0xe4, 0x3c, 0xa3, 0x90, 0x35, + 0xdb, 0x0b, 0x3a, 0x65, 0x46, 0xe7, 0x43, 0x7c, 0x7d, 0x9d, 0xe8, 0xd4, 0x78, 0xfc, 0x44, 0xc6, + 0x9e, 0x23, 0x18, 0x4e, 0xbd, 0xa9, 0xe6, 0xd5, 0x6b, 0xde, 0x9c, 0x92, 0x57, 0xaf, 0xb9, 0x53, + 0x86, 0x7a, 0x83, 0xd1, 0xbd, 0x8a, 0xdf, 0x5f, 0x27, 0xba, 0x86, 0x39, 0x97, 0xa0, 0xfa, 0x37, + 0x82, 0xdd, 0xe9, 0x97, 0x72, 0xdc, 0x2e, 0xe6, 0xf0, 0x98, 0x9e, 0x6a, 0xdf, 0x51, 0xb0, 0x2d, + 0x31, 0xb6, 0xd7, 0xf0, 0x07, 0xeb, 0xc7, 0x36, 0xc9, 0xe9, 0xf3, 0x02, 0xec, 0x6a, 0xb9, 0xf1, + 0xe6, 0xd5, 0x62, 0xd6, 0xbd, 0x3d, 0xaf, 0x16, 0x33, 0xaf, 0xd4, 0xeb, 0xda, 0x7d, 0xd3, 0x9a, + 0x4e, 0xce, 0x44, 0xd0, 0x20, 0xf5, 0x10, 0x56, 0xc9, 0x15, 0xc4, 0xff, 0x45, 0xb0, 0x3d, 0x79, + 0xfb, 0xc5, 0x64, 0x2d, 0xbc, 0x62, 0xf7, 0x75, 0xe5, 0xd8, 0xda, 0x1d, 0x84, 0x0a, 0x1f, 0x73, + 0x15, 0x56, 0xf0, 0x72, 0x17, 0x35, 0x48, 0x0c, 0x01, 0x09, 0xf2, 0x41, 0x09, 0xe0, 0xdf, 0x10, + 0x0c, 0xa6, 0x5c, 0x92, 0x71, 0xce, 0xb5, 0x21, 0xfb, 0xbe, 0xae, 0xbc, 0xd6, 0xa6, 0x97, 0x10, + 0xe2, 0x0a, 0xd3, 0xe1, 0x5d, 0x7c, 0xbe, 0x53, 0x1d, 0x12, 0xf7, 0xf9, 0x33, 0xfa, 0x83, 0xa7, + 0x45, 0xf4, 0xf0, 0x69, 0x11, 0x3d, 0x79, 0x5a, 0x44, 0x5f, 0x3c, 0x2b, 0xf6, 0x3c, 0x7c, 0x56, + 0xec, 0x79, 0xf4, 0xac, 0xd8, 0x73, 0xfd, 0x54, 0xd5, 0xf2, 0x67, 0xeb, 0x65, 0xcd, 0x74, 0x16, + 0x88, 0xf8, 0xe7, 0x20, 0xff, 0x73, 0xd4, 0xab, 0xcc, 0x91, 0xa5, 0x08, 0xc6, 0xb1, 0x13, 0x47, + 0x25, 0x12, 0x7f, 0xd9, 0xa5, 0x5e, 0x79, 0x33, 0xfb, 0x1d, 0xf7, 0xf8, 0x7f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xce, 0x1d, 0x1b, 0xcd, 0xab, 0x1c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2740,13 +2740,13 @@ func (m *QueryChannelConsensusStateRequest) MarshalToSizedBuffer(dAtA []byte) (i _ = i var l int _ = l - if m.VersionHeight != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionHeight)) i-- dAtA[i] = 0x20 } - if m.VersionNumber != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RevisionNumber)) i-- dAtA[i] = 0x18 } @@ -3775,11 +3775,11 @@ func (m *QueryChannelConsensusStateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - if m.VersionNumber != 0 { - n += 1 + sovQuery(uint64(m.VersionNumber)) + if m.RevisionNumber != 0 { + n += 1 + sovQuery(uint64(m.RevisionNumber)) } - if m.VersionHeight != 0 { - n += 1 + sovQuery(uint64(m.VersionHeight)) + if m.RevisionHeight != 0 { + n += 1 + sovQuery(uint64(m.RevisionHeight)) } return n } @@ -5295,9 +5295,9 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionNumber", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionNumber", wireType) } - m.VersionNumber = 0 + m.RevisionNumber = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5307,16 +5307,16 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionNumber |= uint64(b&0x7F) << shift + m.RevisionNumber |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RevisionHeight", wireType) } - m.VersionHeight = 0 + m.RevisionHeight = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5326,7 +5326,7 @@ func (m *QueryChannelConsensusStateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VersionHeight |= uint64(b&0x7F) << shift + m.RevisionHeight |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ibc/core/04-channel/types/query.pb.gw.go b/x/ibc/core/04-channel/types/query.pb.gw.go index 270aa3db9f..bb5a94aba7 100644 --- a/x/ibc/core/04-channel/types/query.pb.gw.go +++ b/x/ibc/core/04-channel/types/query.pb.gw.go @@ -324,26 +324,26 @@ func request_Query_ChannelConsensusState_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := client.ChannelConsensusState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -384,26 +384,26 @@ func local_request_Query_ChannelConsensusState_0(ctx context.Context, marshaler return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "port_id", err) } - val, ok = pathParams["version_number"] + val, ok = pathParams["revision_number"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_number") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_number") } - protoReq.VersionNumber, err = runtime.Uint64(val) + protoReq.RevisionNumber, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_number", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_number", err) } - val, ok = pathParams["version_height"] + val, ok = pathParams["revision_height"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version_height") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "revision_height") } - protoReq.VersionHeight, err = runtime.Uint64(val) + protoReq.RevisionHeight, err = runtime.Uint64(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version_height", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "revision_height", err) } msg, err := server.ChannelConsensusState(ctx, &protoReq) @@ -1744,7 +1744,7 @@ var ( pattern_Query_ChannelClientState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "client_state"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "consensus_state", "version", "version_number", "height", "version_height"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_ChannelConsensusState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 2, 9, 1, 0, 4, 1, 5, 10, 2, 11, 1, 0, 4, 1, 5, 12}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "consensus_state", "revision", "revision_number", "height", "revision_height"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_PacketCommitment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 2, 8, 1, 0, 4, 1, 5, 9}, []string{"ibc", "core", "channel", "v1beta1", "channels", "channel_id", "ports", "port_id", "packet_commitments", "sequence"}, "", runtime.AssumeColonVerbOpt(true))) diff --git a/x/ibc/core/client/query.go b/x/ibc/core/client/query.go index dad0c28998..7055f1c740 100644 --- a/x/ibc/core/client/query.go +++ b/x/ibc/core/client/query.go @@ -62,6 +62,6 @@ func QueryTendermintProof(clientCtx client.Context, key []byte) ([]byte, []byte, return nil, nil, clienttypes.Height{}, err } - version := clienttypes.ParseChainID(clientCtx.ChainID) - return res.Value, proofBz, clienttypes.NewHeight(version, uint64(res.Height)+1), nil + revision := clienttypes.ParseChainID(clientCtx.ChainID) + return res.Value, proofBz, clienttypes.NewHeight(revision, uint64(res.Height)+1), nil } diff --git a/x/ibc/core/exported/client.go b/x/ibc/core/exported/client.go index 50cd8bea30..67c71526d1 100644 --- a/x/ibc/core/exported/client.go +++ b/x/ibc/core/exported/client.go @@ -39,9 +39,9 @@ type ClientState interface { CheckProposedHeaderAndUpdateState(sdk.Context, codec.BinaryMarshaler, sdk.KVStore, Header) (ClientState, ConsensusState, error) // Upgrade functions - // NOTE: proof heights are not included as upgrade to a new version is expected to pass only on the last - // height committed by the current version. Clients are responsible for ensuring that the planned last - // height of the current version is somehow encoded in the proof verification process. + // NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last + // height committed by the current revision. Clients are responsible for ensuring that the planned last + // height of the current revision is somehow encoded in the proof verification process. // This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty // may be cancelled or modified before the last planned height. VerifyUpgradeAndUpdateState( @@ -182,8 +182,8 @@ type Height interface { EQ(Height) bool GT(Height) bool GTE(Height) bool - GetVersionNumber() uint64 - GetVersionHeight() uint64 + GetRevisionNumber() uint64 + GetRevisionHeight() uint64 Decrement() (Height, bool) String() string } diff --git a/x/ibc/core/keeper/msg_server_test.go b/x/ibc/core/keeper/msg_server_test.go index d2e54debe5..1af4cdc18e 100644 --- a/x/ibc/core/keeper/msg_server_test.go +++ b/x/ibc/core/keeper/msg_server_test.go @@ -640,8 +640,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -652,8 +652,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradeClient, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradeClient, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ := suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) msg, err = clienttypes.NewMsgUpgradeClient(clientA, upgradedClient, upgradedConsState, proofUpgradeClient, proofUpgradedConsState, suite.chainA.SenderAccount.GetAddress()) @@ -677,8 +677,8 @@ func (suite *KeeperTestSuite) TestUpgradeClient() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients diff --git a/x/ibc/core/spec/01_concepts.md b/x/ibc/core/spec/01_concepts.md index 4b002458eb..c3059e5f58 100644 --- a/x/ibc/core/spec/01_concepts.md +++ b/x/ibc/core/spec/01_concepts.md @@ -78,38 +78,38 @@ IBC Client Heights are represented by the struct: ```go type Height struct { - VersionNumber uint64 - VersionHeight uint64 + RevisionNumber uint64 + RevisionHeight uint64 } ``` -The `VersionNumber` represents the version of the chain that the height is representing. -An version typically represents a continuous, monotonically increasing range of block-heights. -The `VersionHeight` represents the height of the chain within the given version. +The `RevisionNumber` represents the revision of the chain that the height is representing. +An revision typically represents a continuous, monotonically increasing range of block-heights. +The `RevisionHeight` represents the height of the chain within the given revision. -On any reset of the `VersionHeight`, for example, when hard-forking a Tendermint chain, -the `VersionNumber` will get incremented. This allows IBC clients to distinguish between a -block-height `n` of a previous version of the chain (at version `p`) and block-height `n` of the current -version of the chain (at version `e`). +On any reset of the `RevisionHeight`, for example, when hard-forking a Tendermint chain, +the `RevisionNumber` will get incremented. This allows IBC clients to distinguish between a +block-height `n` of a previous revision of the chain (at revision `p`) and block-height `n` of the current +revision of the chain (at revision `e`). -`Heights` that share the same version number can be compared by simply comparing their respective `VersionHeights`. -Heights that do not share the same version number will only be compared using their respective `VersionNumbers`. -Thus a height `h` with version number `e+1` will always be greater than a height `g` with version number `e`, -**REGARDLESS** of the difference in version heights. +`Heights` that share the same revision number can be compared by simply comparing their respective `RevisionHeights`. +Heights that do not share the same revision number will only be compared using their respective `RevisionNumbers`. +Thus a height `h` with revision number `e+1` will always be greater than a height `g` with revision number `e`, +**REGARDLESS** of the difference in revision heights. Ex: ```go -Height{VersionNumber: 3, VersionHeight: 0} > Height{VersionNumber: 2, VersionHeight: 100000000000} +Height{RevisionNumber: 3, RevisionHeight: 0} > Height{RevisionNumber: 2, RevisionHeight: 100000000000} ``` -When a Tendermint chain is running a particular version, relayers can simply submit headers and proofs with the version number -given by the chain's chainID, and the version height given by the Tendermint block height. When a chain updates using a hard-fork -and resets its block-height, it is responsible for updating its chain-id to increment the version number. -IBC Tendermint clients then verifies the version number against their `ChainId` and treat the `VersionHeight` as the Tendermint block-height. +When a Tendermint chain is running a particular revision, relayers can simply submit headers and proofs with the revision number +given by the chain's chainID, and the revision height given by the Tendermint block height. When a chain updates using a hard-fork +and resets its block-height, it is responsible for updating its chain-id to increment the revision number. +IBC Tendermint clients then verifies the revision number against their `ChainId` and treat the `RevisionHeight` as the Tendermint block-height. -Tendermint chains wishing to use versions to maintain persistent IBC connections even across height-resetting upgrades must format their chain-ids -in the following manner: `{chainID}-{version_number}`. On any height-resetting upgrade, the chainID **MUST** be updated with a higher version number +Tendermint chains wishing to use revisions to maintain persistent IBC connections even across height-resetting upgrades must format their chain-ids +in the following manner: `{chainID}-{revision_number}`. On any height-resetting upgrade, the chainID **MUST** be updated with a higher revision number than the previous value. Ex: @@ -117,8 +117,8 @@ Ex: - Before upgrade ChainID: `gaiamainnet-3` - After upgrade ChainID: `gaiamainnet-4` -Clients that do not require versions, such as the solo-machine client, simply hardcode `0` into the version number whenever they -need to return an IBC height when implementing IBC interfaces and use the `VersionHeight` exclusively. +Clients that do not require revisions, such as the solo-machine client, simply hardcode `0` into the revision number whenever they +need to return an IBC height when implementing IBC interfaces and use the `RevisionHeight` exclusively. Other client-types may implement their own logic to verify the IBC Heights that relayers provide in their `Update`, `Misbehavior`, and `Verify` functions respectively. diff --git a/x/ibc/light-clients/06-solomachine/types/client_state.go b/x/ibc/light-clients/06-solomachine/types/client_state.go index e4a4aa72d9..38004b292b 100644 --- a/x/ibc/light-clients/06-solomachine/types/client_state.go +++ b/x/ibc/light-clients/06-solomachine/types/client_state.go @@ -33,7 +33,7 @@ func (cs ClientState) ClientType() string { // GetLatestHeight returns the latest sequence number. // Return exported.Height to satisfy ClientState interface -// Version number is always 0 for a solo-machine. +// Revision number is always 0 for a solo-machine. func (cs ClientState) GetLatestHeight() exported.Height { return clienttypes.NewHeight(0, cs.Sequence) } @@ -45,7 +45,7 @@ func (cs ClientState) IsFrozen() bool { // GetFrozenHeight returns the frozen sequence of the client. // Return exported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (cs ClientState) GetFrozenHeight() exported.Height { return clienttypes.NewHeight(0, cs.FrozenSequence) } @@ -398,11 +398,11 @@ func produceVerificationArgs( prefix exported.Prefix, proof []byte, ) (cryptotypes.PubKey, signing.SignatureData, uint64, uint64, error) { - if version := height.GetVersionNumber(); version != 0 { - return nil, nil, 0, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "version must be 0 for solomachine, got version-number: %d", version) + if revision := height.GetRevisionNumber(); revision != 0 { + return nil, nil, 0, 0, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "revision must be 0 for solomachine, got revision-number: %d", revision) } - // sequence is encoded in the version height of height struct - sequence := height.GetVersionHeight() + // sequence is encoded in the revision height of height struct + sequence := height.GetRevisionHeight() if cs.IsFrozen() { return nil, nil, 0, 0, clienttypes.ErrClientFrozen } @@ -440,7 +440,7 @@ func produceVerificationArgs( return nil, nil, 0, 0, sdkerrors.Wrap(clienttypes.ErrInvalidConsensus, "consensus state cannot be empty") } - latestSequence := cs.GetLatestHeight().GetVersionHeight() + latestSequence := cs.GetLatestHeight().GetRevisionHeight() if latestSequence != sequence { return nil, nil, 0, 0, sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, diff --git a/x/ibc/light-clients/06-solomachine/types/header.go b/x/ibc/light-clients/06-solomachine/types/header.go index dc43cee4f7..60a9bfeeb7 100644 --- a/x/ibc/light-clients/06-solomachine/types/header.go +++ b/x/ibc/light-clients/06-solomachine/types/header.go @@ -18,7 +18,7 @@ func (Header) ClientType() string { // GetHeight returns the current sequence number as the height. // Return clientexported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (h Header) GetHeight() exported.Height { return clienttypes.NewHeight(0, h.Sequence) } diff --git a/x/ibc/light-clients/06-solomachine/types/misbehaviour.go b/x/ibc/light-clients/06-solomachine/types/misbehaviour.go index 8a59eb2d9a..65b8a4ee47 100644 --- a/x/ibc/light-clients/06-solomachine/types/misbehaviour.go +++ b/x/ibc/light-clients/06-solomachine/types/misbehaviour.go @@ -30,7 +30,7 @@ func (misbehaviour Misbehaviour) Type() string { // GetHeight returns the sequence at which misbehaviour occurred. // Return exported.Height to satisfy interface -// Version number is always 0 for a solo-machine +// Revision number is always 0 for a solo-machine func (misbehaviour Misbehaviour) GetHeight() exported.Height { return clienttypes.NewHeight(0, misbehaviour.Sequence) } diff --git a/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go b/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go index a976186eab..7c1f9168aa 100644 --- a/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go +++ b/x/ibc/light-clients/06-solomachine/types/misbehaviour_test.go @@ -11,8 +11,8 @@ func (suite *SoloMachineTestSuite) TestMisbehaviour() { suite.Require().Equal(exported.Solomachine, misbehaviour.ClientType()) suite.Require().Equal(suite.solomachine.ClientID, misbehaviour.GetClientID()) - suite.Require().Equal(uint64(0), misbehaviour.GetHeight().GetVersionNumber()) - suite.Require().Equal(suite.solomachine.Sequence, misbehaviour.GetHeight().GetVersionHeight()) + suite.Require().Equal(uint64(0), misbehaviour.GetHeight().GetRevisionNumber()) + suite.Require().Equal(suite.solomachine.Sequence, misbehaviour.GetHeight().GetRevisionHeight()) } func (suite *SoloMachineTestSuite) TestMisbehaviourValidateBasic() { diff --git a/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go b/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go index 86d5c78dcc..da5c815ecb 100644 --- a/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go +++ b/x/ibc/light-clients/06-solomachine/types/proposal_handle_test.go @@ -79,7 +79,7 @@ func (suite *SoloMachineTestSuite) TestCheckProposedHeaderAndUpdateState() { suite.Require().Equal(headerPubKey, consStatePubKey) suite.Require().Equal(smHeader.NewDiversifier, smConsState.Diversifier) suite.Require().Equal(smHeader.Timestamp, smConsState.Timestamp) - suite.Require().Equal(smHeader.GetHeight().GetVersionHeight(), cs.(*types.ClientState).Sequence) + suite.Require().Equal(smHeader.GetHeight().GetRevisionHeight(), cs.(*types.ClientState).Sequence) } else { suite.Require().Error(err) suite.Require().Nil(cs) diff --git a/x/ibc/light-clients/06-solomachine/types/solomachine_test.go b/x/ibc/light-clients/06-solomachine/types/solomachine_test.go index b3b647d829..0d9e726411 100644 --- a/x/ibc/light-clients/06-solomachine/types/solomachine_test.go +++ b/x/ibc/light-clients/06-solomachine/types/solomachine_test.go @@ -55,7 +55,7 @@ func (suite *SoloMachineTestSuite) GetSequenceFromStore() uint64 { var clientState exported.ClientState err := codec.UnmarshalAny(suite.chainA.Codec, &clientState, bz) suite.Require().NoError(err) - return clientState.GetLatestHeight().GetVersionHeight() + return clientState.GetLatestHeight().GetRevisionHeight() } func (suite *SoloMachineTestSuite) GetInvalidProof() []byte { diff --git a/x/ibc/light-clients/07-tendermint/types/client_state.go b/x/ibc/light-clients/07-tendermint/types/client_state.go index 976c837ad7..10f3bc3baa 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state.go @@ -92,8 +92,8 @@ func (cs ClientState) Validate() error { if cs.MaxClockDrift == 0 { return sdkerrors.Wrap(ErrInvalidMaxClockDrift, "max clock drift cannot be zero") } - if cs.LatestHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint version height cannot be zero") + if cs.LatestHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "tendermint revision height cannot be zero") } if cs.TrustingPeriod >= cs.UnbondingPeriod { return sdkerrors.Wrapf( diff --git a/x/ibc/light-clients/07-tendermint/types/client_state_test.go b/x/ibc/light-clients/07-tendermint/types/client_state_test.go index 0e0c049006..80be1472f8 100644 --- a/x/ibc/light-clients/07-tendermint/types/client_state_test.go +++ b/x/ibc/light-clients/07-tendermint/types/client_state_test.go @@ -137,7 +137,7 @@ func (suite *TendermintTestSuite) TestVerifyClientConsensusState() { }, { name: "client is frozen", - clientState: &types.ClientState{LatestHeight: height, FrozenHeight: clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1)}, + clientState: &types.ClientState{LatestHeight: height, FrozenHeight: clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1)}, consensusState: types.ConsensusState{ Root: commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), }, diff --git a/x/ibc/light-clients/07-tendermint/types/header.go b/x/ibc/light-clients/07-tendermint/types/header.go index 40858c7350..b5829e5f96 100644 --- a/x/ibc/light-clients/07-tendermint/types/header.go +++ b/x/ibc/light-clients/07-tendermint/types/header.go @@ -32,8 +32,8 @@ func (h Header) ClientType() string { // header is nil. // NOTE: the header.Header is checked to be non nil in ValidateBasic. func (h Header) GetHeight() exported.Height { - version := clienttypes.ParseChainID(h.Header.ChainID) - return clienttypes.NewHeight(version, uint64(h.Header.Height)) + revision := clienttypes.ParseChainID(h.Header.ChainID) + return clienttypes.NewHeight(revision, uint64(h.Header.Height)) } // GetTime returns the current block timestamp. It returns a zero time if diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go index d4de93504e..5158766040 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour.go @@ -60,11 +60,11 @@ func (misbehaviour Misbehaviour) ValidateBasic() error { if misbehaviour.Header2 == nil { return sdkerrors.Wrap(ErrInvalidHeader, "misbehaviour Header2 cannot be nil") } - if misbehaviour.Header1.TrustedHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero version height") + if misbehaviour.Header1.TrustedHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header1 cannot have zero revision height") } - if misbehaviour.Header2.TrustedHeight.VersionHeight == 0 { - return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero version height") + if misbehaviour.Header2.TrustedHeight.RevisionHeight == 0 { + return sdkerrors.Wrapf(ErrInvalidHeaderHeight, "misbehaviour Header2 cannot have zero revision height") } if misbehaviour.Header1.TrustedValidators == nil { return sdkerrors.Wrap(ErrInvalidValidatorSet, "trusted validator set in Header1 cannot be empty") diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go index 1f1a6943ce..4c55552d30 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle.go @@ -102,10 +102,10 @@ func checkMisbehaviourHeader( } chainID := clientState.GetChainID() - // If chainID is in version format, then set version number of chainID with the version number + // If chainID is in revision format, then set revision number of chainID with the revision number // of the misbehaviour header - if clienttypes.IsVersionFormat(chainID) { - chainID, _ = clienttypes.SetVersionNumber(chainID, header.GetHeight().GetVersionNumber()) + if clienttypes.IsRevisionFormat(chainID) { + chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) } // - ValidatorSet must have TrustLevel similarity with trusted FromValidatorSet diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go index 65ec7163d8..3ca2e4dc11 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_handle_test.go @@ -35,8 +35,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { altSigners := []tmtypes.PrivValidator{altPrivVal} - heightMinus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-3) + heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) + heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) testCases := []struct { name string @@ -57,8 +57,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -72,8 +72,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -87,53 +87,53 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour at a previous version", - types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour at a previous revision", + types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour at a future version", - types.NewClientState(chainIDVersion0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour at a future revision", + types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion0, 3, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion0, 3, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision0, 3, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, true, }, { - "valid misbehaviour with trusted heights at a previous version", - types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), + "valid misbehaviour with trusted heights at a previous revision", + types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false), types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), heightMinus1, types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, heightMinus3, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -147,8 +147,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -162,8 +162,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -177,8 +177,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -192,8 +192,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), suite.valsHash), heightMinus3, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus3, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -207,8 +207,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -222,8 +222,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -248,8 +248,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -263,8 +263,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now.Add(trustingPeriod), @@ -278,8 +278,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, suite.valSet, bothSigners), ClientId: chainID, }, suite.now, @@ -293,8 +293,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, altValSet, bothValSet, altSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), bothValSet, bothValSet, bothSigners), ClientId: chainID, }, suite.now, @@ -308,8 +308,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, bothValSet, bothValSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ClientId: chainID, }, suite.now, @@ -323,8 +323,8 @@ func (suite *TendermintTestSuite) TestCheckMisbehaviourAndUpdateState() { types.NewConsensusState(suite.now, commitmenttypes.NewMerkleRoot(tmhash.Sum([]byte("app_hash"))), bothValsHash), height, &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now, altValSet, bothValSet, altSigners), - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now, altValSet, bothValSet, altSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), height, suite.now.Add(time.Minute), altValSet, bothValSet, altSigners), ClientId: chainID, }, suite.now, diff --git a/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go b/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go index c8e4416612..dede4e6021 100644 --- a/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go +++ b/x/ibc/light-clients/07-tendermint/types/misbehaviour_test.go @@ -16,11 +16,11 @@ import ( func (suite *TendermintTestSuite) TestMisbehaviour() { signers := []tmtypes.PrivValidator{suite.privVal} - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) misbehaviour := &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: clientID, } @@ -34,9 +34,9 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - versionHeight := int64(height.VersionHeight) + revisionHeight := int64(height.RevisionHeight) - altVal := tmtypes.NewValidator(altPubKey, versionHeight) + altVal := tmtypes.NewValidator(altPubKey, revisionHeight) // Create bothValSet with both suite validator and altVal bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -51,7 +51,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { altSigners := []tmtypes.PrivValidator{altPrivVal} - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) testCases := []struct { name string @@ -63,7 +63,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -85,7 +85,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "valid misbehaviour with different trusted headers", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.NewHeight(0, height.VersionHeight-3), suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.NewHeight(0, height.RevisionHeight-3), suite.now.Add(time.Minute), suite.valSet, bothValSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -94,7 +94,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted height is 0 in Header1", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), Header2: suite.header, ClientId: clientID, }, @@ -105,7 +105,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted height is 0 in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), clienttypes.ZeroHeight(), suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -114,7 +114,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "trusted valset is nil in Header1", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), Header2: suite.header, ClientId: clientID, }, @@ -125,7 +125,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "trusted valset is nil in Header2", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now.Add(time.Minute), suite.valSet, nil, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -135,7 +135,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "invalid client ID ", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: "GAIA", }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -145,7 +145,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "chainIDs do not match", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), + Header2: suite.chainA.CreateTMClientHeader("ethermint", int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, signers), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { return nil }, @@ -174,19 +174,19 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { { "header 1 doesn't have 2/3 majority", &types.Misbehaviour{ - Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header1: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), Header2: suite.header, ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header1.GetHeight().GetVersionHeight()), 1, tmproto.PrecommitType, altValSet) + wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header1.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header1.Commit.BlockID) if err != nil { return err } - tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), misbehaviour.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) + tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), misbehaviour.Header1.Commit.Round, wrongVoteSet, altSigners, suite.now) misbehaviour.Header1.Commit = tmCommit.ToProto() return err }, @@ -196,18 +196,18 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "header 2 doesn't have 2/3 majority", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { // voteSet contains only altVal which is less than 2/3 of total power (height/1height) - wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), 1, tmproto.PrecommitType, altValSet) + wrongVoteSet := tmtypes.NewVoteSet(chainID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), 1, tmproto.PrecommitType, altValSet) blockID, err := tmtypes.BlockIDFromProto(&misbehaviour.Header2.Commit.BlockID) if err != nil { return err } - tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetVersionHeight()), misbehaviour.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) + tmCommit, err := tmtypes.MakeCommit(*blockID, int64(misbehaviour.Header2.GetHeight().GetRevisionHeight()), misbehaviour.Header2.Commit.Round, wrongVoteSet, altSigners, suite.now) misbehaviour.Header2.Commit = tmCommit.ToProto() return err }, @@ -217,7 +217,7 @@ func (suite *TendermintTestSuite) TestMisbehaviourValidateBasic() { "validators sign off on wrong commit", &types.Misbehaviour{ Header1: suite.header, - Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), + Header2: suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, bothValSet, suite.valSet, bothSigners), ClientId: clientID, }, func(misbehaviour *types.Misbehaviour) error { diff --git a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go index 34f0e50ef5..4f9b8142bf 100644 --- a/x/ibc/light-clients/07-tendermint/types/tendermint_test.go +++ b/x/ibc/light-clients/07-tendermint/types/tendermint_test.go @@ -19,13 +19,13 @@ import ( ) const ( - chainID = "gaia" - chainIDVersion0 = "gaia-version-0" - chainIDVersion1 = "gaia-version-1" - clientID = "gaiamainnet" - trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 - ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 - maxClockDrift time.Duration = time.Second * 10 + chainID = "gaia" + chainIDRevision0 = "gaia-revision-0" + chainIDRevision1 = "gaia-revision-1" + clientID = "gaiamainnet" + trustingPeriod time.Duration = time.Hour * 24 * 7 * 2 + ubdPeriod time.Duration = time.Hour * 24 * 7 * 3 + maxClockDrift time.Duration = time.Second * 10 ) var ( @@ -81,12 +81,12 @@ func (suite *TendermintTestSuite) SetupTest() { pubKey, err := suite.privVal.GetPubKey() suite.Require().NoError(err) - heightMinus1 := clienttypes.NewHeight(0, height.VersionHeight-1) + heightMinus1 := clienttypes.NewHeight(0, height.RevisionHeight-1) val := tmtypes.NewValidator(pubKey, 10) suite.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{val}) suite.valsHash = suite.valSet.Hash() - suite.header = suite.chainA.CreateTMClientHeader(chainID, int64(height.VersionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) + suite.header = suite.chainA.CreateTMClientHeader(chainID, int64(height.RevisionHeight), heightMinus1, suite.now, suite.valSet, suite.valSet, []tmtypes.PrivValidator{suite.privVal}) suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, Time: suite.now}) } diff --git a/x/ibc/light-clients/07-tendermint/types/update.go b/x/ibc/light-clients/07-tendermint/types/update.go index 50adcb1c1f..cee0015a1d 100644 --- a/x/ibc/light-clients/07-tendermint/types/update.go +++ b/x/ibc/light-clients/07-tendermint/types/update.go @@ -22,7 +22,7 @@ import ( // - the client or header provided are not parseable to tendermint types // - the header is invalid // - header height is less than or equal to the trusted header height -// - header version is not equal to trusted header version +// - header revision is not equal to trusted header revision // - header valset commit verification fails // - header timestamp is past the trusting period in relation to the consensus state // - header timestamp is less than or equal to the consensus state timestamp @@ -33,8 +33,8 @@ import ( // If we are updating to a past height, a consensus state is created for that height to be persisted in client store // If we are updating to a future height, the consensus state is created and the client state is updated to reflect // the new latest height -// UpdateClient must only be used to update within a single version, thus header version number and trusted height's version -// number must be the same. To update to a new version, use a separate upgrade path +// UpdateClient must only be used to update within a single revision, thus header revision number and trusted height's revision +// number must be the same. To update to a new revision, use a separate upgrade path // Tendermint client validity checking uses the bisection algorithm described // in the [Tendermint spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md). func (cs ClientState) CheckHeaderAndUpdateState( @@ -94,13 +94,13 @@ func checkValidity( return err } - // UpdateClient only accepts updates with a header at the same version + // UpdateClient only accepts updates with a header at the same revision // as the trusted consensus state - if header.GetHeight().GetVersionNumber() != header.TrustedHeight.VersionNumber { + if header.GetHeight().GetRevisionNumber() != header.TrustedHeight.RevisionNumber { return sdkerrors.Wrapf( ErrInvalidHeaderHeight, - "header height version %d does not match trusted header version %d", - header.GetHeight().GetVersionNumber(), header.TrustedHeight.VersionNumber, + "header height revision %d does not match trusted header revision %d", + header.GetHeight().GetRevisionNumber(), header.TrustedHeight.RevisionNumber, ) } @@ -128,21 +128,21 @@ func checkValidity( } chainID := clientState.GetChainID() - // If chainID is in version format, then set version number of chainID with the version number + // If chainID is in revision format, then set revision number of chainID with the revision number // of the header we are verifying - // This is useful if the update is at a previous version rather than an update to the latest version + // This is useful if the update is at a previous revision rather than an update to the latest revision // of the client. - // The chainID must be set correctly for the previous version before attempting verification. - // Updates for previous versions are not supported if the chainID is not in version format. - if clienttypes.IsVersionFormat(chainID) { - chainID, _ = clienttypes.SetVersionNumber(chainID, header.GetHeight().GetVersionNumber()) + // The chainID must be set correctly for the previous revision before attempting verification. + // Updates for previous revisions are not supported if the chainID is not in revision format. + if clienttypes.IsRevisionFormat(chainID) { + chainID, _ = clienttypes.SetRevisionNumber(chainID, header.GetHeight().GetRevisionNumber()) } // Construct a trusted header using the fields in consensus state // Only Height, Time, and NextValidatorsHash are necessary for verification trustedHeader := tmtypes.Header{ ChainID: chainID, - Height: int64(header.TrustedHeight.VersionHeight), + Height: int64(header.TrustedHeight.RevisionHeight), Time: consState.Timestamp, NextValidatorsHash: consState.NextValidatorsHash, } diff --git a/x/ibc/light-clients/07-tendermint/types/update_test.go b/x/ibc/light-clients/07-tendermint/types/update_test.go index b75d71b827..d9e550ed01 100644 --- a/x/ibc/light-clients/07-tendermint/types/update_test.go +++ b/x/ibc/light-clients/07-tendermint/types/update_test.go @@ -26,15 +26,15 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { altPubKey, err := altPrivVal.GetPubKey() suite.Require().NoError(err) - versionHeight := int64(height.VersionHeight) + revisionHeight := int64(height.RevisionHeight) // create modified heights to use for test-cases - heightPlus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight+1) - heightMinus1 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-1) - heightMinus3 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight-3) - heightPlus5 := clienttypes.NewHeight(height.VersionNumber, height.VersionHeight+5) + heightPlus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+1) + heightMinus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-1) + heightMinus3 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight-3) + heightPlus5 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+5) - altVal := tmtypes.NewValidator(altPubKey, versionHeight) + altVal := tmtypes.NewValidator(altPubKey, revisionHeight) // Create bothValSet with both suite validator and altVal. Would be valid update bothValSet := tmtypes.NewValidatorSet(append(suite.valSet.Validators, altVal)) @@ -57,9 +57,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with next height and same validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: true, @@ -67,9 +67,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with future height and different validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -77,9 +77,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update with next height and different validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -87,20 +87,20 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "successful update for a previous height", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) consStateHeight = heightMinus3 - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.VersionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, }, { - name: "successful update for a previous version", + name: "successful update for a previous revision", setup: func() { - clientState = types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion0, int64(height.VersionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision0, int64(height.RevisionHeight), heightMinus3, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: true, @@ -108,29 +108,29 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with incorrect header chain-id", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader("ethermint", int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader("ethermint", int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, }, { - name: "unsuccessful update to a future version", + name: "unsuccessful update to a future revision", setup: func() { - clientState = types.NewClientState(chainIDVersion0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision0, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion1, 1, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 1, height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, }, { - name: "unsuccessful update: header height version and trusted height version mismatch", + name: "unsuccessful update: header height revision and trusted height revision mismatch", setup: func() { - clientState = types.NewClientState(chainIDVersion1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainIDRevision1, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(1, 1), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainIDVersion1, 3, height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainIDRevision1, 3, height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -138,9 +138,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with next height: update header mismatches nextValSetHash", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, bothValSet, suite.valSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -148,9 +148,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with next height: update header mismatches different nextValSetHash", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), bothValSet.Hash()) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, bothValSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, bothValSet, signers) currentTime = suite.now }, expPass: false, @@ -158,9 +158,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update with future height: too much change in validator set", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, altValSet, suite.valSet, altSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, altValSet, suite.valSet, altSigners) currentTime = suite.now }, expPass: false, @@ -168,9 +168,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful updates, passed in incorrect trusted validators for given consensus state", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.VersionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus5.RevisionHeight), height, suite.headerTime, bothValSet, bothValSet, bothSigners) currentTime = suite.now }, expPass: false, @@ -178,9 +178,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: trusting period has passed since last client timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) // make current time pass trusting period from last timestamp on clientstate currentTime = suite.now.Add(trustingPeriod) }, @@ -189,9 +189,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: header timestamp is past current timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.now.Add(time.Minute), suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -199,9 +199,9 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "unsuccessful update: header timestamp is not past last client timestamp", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.clientTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.clientTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, @@ -209,11 +209,11 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "header basic validation failed", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightPlus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) // cause new header to fail validatebasic by changing commit height to mismatch header height - newHeader.SignedHeader.Commit.Height = versionHeight - 1 + newHeader.SignedHeader.Commit.Height = revisionHeight - 1 currentTime = suite.now }, expPass: false, @@ -221,10 +221,10 @@ func (suite *TendermintTestSuite) TestCheckHeaderAndUpdateState() { { name: "header height < consensus height", setup: func() { - clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(height.VersionNumber, heightPlus5.VersionHeight), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) + clientState = types.NewClientState(chainID, types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, clienttypes.NewHeight(height.RevisionNumber, heightPlus5.RevisionHeight), commitmenttypes.GetSDKSpecs(), upgradePath, false, false) consensusState = types.NewConsensusState(suite.clientTime, commitmenttypes.NewMerkleRoot(suite.header.Header.GetAppHash()), suite.valsHash) // Make new header at height less than latest client state - newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.VersionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) + newHeader = suite.chainA.CreateTMClientHeader(chainID, int64(heightMinus1.RevisionHeight), height, suite.headerTime, suite.valSet, suite.valSet, signers) currentTime = suite.now }, expPass: false, diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade.go b/x/ibc/light-clients/07-tendermint/types/upgrade.go index e058d77160..e3f230bbbf 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade.go @@ -17,7 +17,7 @@ import ( // in client state that must be the same across all valid Tendermint clients for the new chain. // VerifyUpgrade will return an error if: // - the upgradedClient is not a Tendermint ClientState -// - the lastest height of the client state does not have the same version number or has a greater +// - the lastest height of the client state does not have the same revision number or has a greater // height than the committed client. // - the height of upgraded client is not greater than that of current client // - the latest height of the new client does not match or is greater than the height in committed client @@ -35,8 +35,8 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( // last height of current counterparty chain must be client's latest height lastHeight := cs.GetLatestHeight() - if upgradedClient.GetLatestHeight().GetVersionNumber() <= lastHeight.GetVersionNumber() { - return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be at greater version than current client height %s", + if upgradedClient.GetLatestHeight().GetRevisionNumber() <= lastHeight.GetRevisionNumber() { + return nil, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "upgraded client height %s must be at greater revision than current client height %s", upgradedClient.GetLatestHeight(), lastHeight) } @@ -64,7 +64,7 @@ func (cs ClientState) VerifyUpgradeAndUpdateState( } // Must prove against latest consensus state to ensure we are verifying against latest upgrade plan - // This verifies that upgrade is intended for the provided version, since committed client must exist + // This verifies that upgrade is intended for the provided revision, since committed client must exist // at this consensus state consState, err := GetConsensusState(clientStore, cdc, lastHeight) if err != nil { @@ -132,7 +132,7 @@ func constructUpgradeClientMerklePath(upgradePath []string, lastHeight exported. // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath // this will create the IAVL key that is used to store client in upgrade store lastKey := upgradePath[len(upgradePath)-1] - appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetVersionHeight(), upgradetypes.KeyUpgradedClient) + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetRevisionHeight(), upgradetypes.KeyUpgradedClient) clientPath = append(clientPath, appendedKey) return commitmenttypes.NewMerklePath(clientPath...) @@ -147,7 +147,7 @@ func constructUpgradeConsStateMerklePath(upgradePath []string, lastHeight export // append lastHeight and `upgradedClient` to last key of upgradePath and use as lastKey of clientPath // this will create the IAVL key that is used to store client in upgrade store lastKey := upgradePath[len(upgradePath)-1] - appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetVersionHeight(), upgradetypes.KeyUpgradedConsState) + appendedKey := fmt.Sprintf("%s/%d/%s", lastKey, lastHeight.GetRevisionHeight(), upgradetypes.KeyUpgradedConsState) consPath = append(consPath, appendedKey) return commitmenttypes.NewMerklePath(consPath...) diff --git a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go index 3db9d2dbae..c6a40385d2 100644 --- a/x/ibc/light-clients/07-tendermint/types/upgrade_test.go +++ b/x/ibc/light-clients/07-tendermint/types/upgrade_test.go @@ -35,8 +35,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -47,13 +47,13 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: true, }, { - name: "unsuccessful upgrade: upgrade height version height is more than the current client version height", + name: "unsuccessful upgrade: upgrade height revision height is more than the current client revision height", setup: func() { upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, trustingPeriod, ubdPeriod+trustingPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, false, false) @@ -65,8 +65,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(10, uint64(suite.chainB.GetContext().BlockHeight()+10)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -77,8 +77,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -95,8 +95,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("wrongchainID", types.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, newClientHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, true) @@ -108,8 +108,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -123,8 +123,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { } // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change upgradedClient client-specified parameters upgradedClient = types.NewClientState("newChainId", types.DefaultTrustLevel, ubdPeriod, ubdPeriod+trustingPeriod, maxClockDrift+5, lastHeight, commitmenttypes.GetSDKSpecs(), upgradePath, true, false) @@ -136,8 +136,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -154,8 +154,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // change submitted upgradedConsensusState upgradedConsState = &types.ConsensusState{ @@ -171,8 +171,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -183,12 +183,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { upgradedConsState = &types.ConsensusState{ NextValidatorsHash: []byte("nextValsHash"), } - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) proofUpgradedClient = []byte("proof") }, @@ -202,12 +202,12 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { NextValidatorsHash: []byte("nextValsHash"), } - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) proofUpgradedConsState = []byte("proof") }, @@ -225,13 +225,13 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -247,13 +247,13 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { // upgrade Height is at next block lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -270,7 +270,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -281,8 +281,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) // SetClientState with empty upgrade path tmClient, _ := cs.(*types.ClientState) @@ -304,7 +304,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -315,8 +315,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -333,7 +333,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+100)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -344,8 +344,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -359,7 +359,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { } // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -373,8 +373,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -391,7 +391,7 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) // commit upgrade store changes and update clients @@ -402,8 +402,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, @@ -421,8 +421,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { lastHeight = clienttypes.NewHeight(0, uint64(suite.chainB.GetContext().BlockHeight()+1)) // zero custom fields and store in upgrade store - suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedClient) - suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetVersionHeight()), upgradedConsState) + suite.chainB.App.UpgradeKeeper.SetUpgradedClient(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedClient) + suite.chainB.App.UpgradeKeeper.SetUpgradedConsensusState(suite.chainB.GetContext(), int64(lastHeight.GetRevisionHeight()), upgradedConsState) // commit upgrade store changes and update clients @@ -433,8 +433,8 @@ func (suite *TendermintTestSuite) TestVerifyUpgrade() { cs, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientA) suite.Require().True(found) - proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) - proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetVersionHeight())), cs.GetLatestHeight().GetVersionHeight()) + proofUpgradedClient, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedClientKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) + proofUpgradedConsState, _ = suite.chainB.QueryUpgradeProof(upgradetypes.UpgradedConsStateKey(int64(lastHeight.GetRevisionHeight())), cs.GetLatestHeight().GetRevisionHeight()) }, expPass: false, }, diff --git a/x/ibc/light-clients/09-localhost/types/client_state.go b/x/ibc/light-clients/09-localhost/types/client_state.go index 0db79e8612..b828aa029a 100644 --- a/x/ibc/light-clients/09-localhost/types/client_state.go +++ b/x/ibc/light-clients/09-localhost/types/client_state.go @@ -58,8 +58,8 @@ func (cs ClientState) Validate() error { if strings.TrimSpace(cs.ChainId) == "" { return sdkerrors.Wrap(sdkerrors.ErrInvalidChainID, "chain id cannot be blank") } - if cs.Height.VersionHeight == 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local version height cannot be zero") + if cs.Height.RevisionHeight == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidHeight, "local revision height cannot be zero") } return nil } @@ -80,8 +80,8 @@ func (cs *ClientState) CheckHeaderAndUpdateState( ) (exported.ClientState, exported.ConsensusState, error) { // use the chain ID from context since the localhost client is from the running chain (i.e self). cs.ChainId = ctx.ChainID() - version := clienttypes.ParseChainID(cs.ChainId) - cs.Height = clienttypes.NewHeight(version, uint64(ctx.BlockHeight())) + revision := clienttypes.ParseChainID(cs.ChainId) + cs.Height = clienttypes.NewHeight(revision, uint64(ctx.BlockHeight())) return cs, nil, nil } diff --git a/x/ibc/light-clients/09-localhost/types/client_state_test.go b/x/ibc/light-clients/09-localhost/types/client_state_test.go index a4443867d7..17555b9453 100644 --- a/x/ibc/light-clients/09-localhost/types/client_state_test.go +++ b/x/ibc/light-clients/09-localhost/types/client_state_test.go @@ -123,8 +123,8 @@ func (suite *LocalhostTestSuite) TestCheckHeaderAndUpdateState() { clientState := types.NewClientState("chainID", clientHeight) cs, _, err := clientState.CheckHeaderAndUpdateState(suite.ctx, nil, nil, nil) suite.Require().NoError(err) - suite.Require().Equal(uint64(0), cs.GetLatestHeight().GetVersionNumber()) - suite.Require().Equal(suite.ctx.BlockHeight(), int64(cs.GetLatestHeight().GetVersionHeight())) + suite.Require().Equal(uint64(0), cs.GetLatestHeight().GetRevisionNumber()) + suite.Require().Equal(suite.ctx.BlockHeight(), int64(cs.GetLatestHeight().GetRevisionHeight())) suite.Require().Equal(suite.ctx.BlockHeader().ChainID, clientState.ChainId) } diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index 0ac3c51579..b63e72c3e9 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -187,12 +187,12 @@ func (chain *TestChain) QueryProof(key []byte) ([]byte, clienttypes.Height) { proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof) require.NoError(chain.t, err) - version := clienttypes.ParseChainID(chain.ChainID) + revision := clienttypes.ParseChainID(chain.ChainID) // proof height + 1 is returned as the proof created corresponds to the height the proof // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it // have heights 1 above the IAVL tree. Thus we return proof height + 1 - return proof, clienttypes.NewHeight(version, uint64(res.Height)+1) + return proof, clienttypes.NewHeight(revision, uint64(res.Height)+1) } // QueryUpgradeProof performs an abci query with the given key and returns the proto encoded merkle proof @@ -211,12 +211,12 @@ func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, cl proof, err := chain.App.AppCodec().MarshalBinaryBare(&merkleProof) require.NoError(chain.t, err) - version := clienttypes.ParseChainID(chain.ChainID) + revision := clienttypes.ParseChainID(chain.ChainID) // proof height + 1 is returned as the proof created corresponds to the height the proof // was created in the IAVL tree. Tendermint and subsequently the clients that rely on it // have heights 1 above the IAVL tree. Thus we return proof height + 1 - return proof, clienttypes.NewHeight(version, uint64(res.Height+1)) + return proof, clienttypes.NewHeight(revision, uint64(res.Height+1)) } // QueryClientStateProof performs and abci query for a client state @@ -510,13 +510,13 @@ func (chain *TestChain) ConstructUpdateTMClientHeader(counterparty *TestChain, c // since the last trusted validators for a header at height h // is the NextValidators at h+1 committed to in header h by // NextValidatorsHash - tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.VersionHeight + 1)) + tmTrustedVals, ok = counterparty.GetValsAtHeight(int64(trustedHeight.RevisionHeight + 1)) if !ok { return nil, sdkerrors.Wrapf(ibctmtypes.ErrInvalidHeaderHeight, "could not retrieve trusted validators at trustedHeight: %d", trustedHeight) } } // inject trusted fields into last header - // for now assume version number is 0 + // for now assume revision number is 0 header.TrustedHeight = trustedHeight trustedVals, err := tmTrustedVals.ToProto() diff --git a/x/ibc/testing/solomachine.go b/x/ibc/testing/solomachine.go index 03fe887b85..52621f8ad1 100644 --- a/x/ibc/testing/solomachine.go +++ b/x/ibc/testing/solomachine.go @@ -102,7 +102,7 @@ func (solo *Solomachine) ConsensusState() *solomachinetypes.ConsensusState { } } -// GetHeight returns an exported.Height with Sequence as VersionHeight +// GetHeight returns an exported.Height with Sequence as RevisionHeight func (solo *Solomachine) GetHeight() exported.Height { return clienttypes.NewHeight(0, solo.Sequence) } From 12a02b98a5eef0a5dc011ccf8503106048b93542 Mon Sep 17 00:00:00 2001 From: Amaury Date: Tue, 24 Nov 2020 18:09:30 +0100 Subject: [PATCH 51/57] CopyTx also copies timeoutHeight (#8015) Co-authored-by: Aleksandr Bezobchuk Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- client/tx/legacy.go | 1 + client/tx/legacy_test.go | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/client/tx/legacy.go b/client/tx/legacy.go index 62cbf9b7b4..b551ecebb8 100644 --- a/client/tx/legacy.go +++ b/client/tx/legacy.go @@ -61,6 +61,7 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) builder.SetMemo(tx.GetMemo()) builder.SetFeeAmount(tx.GetFee()) builder.SetGasLimit(tx.GetGas()) + builder.SetTimeoutHeight(tx.GetTimeoutHeight()) return nil } diff --git a/client/tx/legacy_test.go b/client/tx/legacy_test.go index 59a7b95d7f..b10c51e344 100644 --- a/client/tx/legacy_test.go +++ b/client/tx/legacy_test.go @@ -21,8 +21,9 @@ import ( ) const ( - memo = "waboom" - gas = uint64(10000) + memo = "waboom" + gas = uint64(10000) + timeoutHeight = 5 ) var ( @@ -47,6 +48,7 @@ func buildTestTx(t *testing.T, builder client.TxBuilder) { require.NoError(t, err) err = builder.SetSignatures(sig) require.NoError(t, err) + builder.SetTimeoutHeight(timeoutHeight) } type TestSuite struct { @@ -105,6 +107,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg, stdTx.Msgs[0]) + s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Equal(sig.PubKey, stdTx.Signatures[0].PubKey) s.Require().Equal(sig.Data.(*signing2.SingleSignatureData).Signature, stdTx.Signatures[0].Signature) @@ -123,6 +126,7 @@ func (s *TestSuite) TestConvertTxToStdTx() { s.Require().Equal(gas, stdTx.Fee.Gas) s.Require().Equal(fee, stdTx.Fee.Amount) s.Require().Equal(msg, stdTx.Msgs[0]) + s.Require().Equal(timeoutHeight, stdTx.TimeoutHeight) s.Require().Empty(stdTx.Signatures) // std tx From 1b3ce2c1d128866ef33eca34850b0343703df12e Mon Sep 17 00:00:00 2001 From: Amaury Date: Wed, 25 Nov 2020 00:32:32 +0100 Subject: [PATCH 52/57] CLI `migrate` command for x/{upgrade,params} proposals (#7875) * Add v038 upgrade types * Add migrate x/upgrade * remove nolint * Add ParameterChangeProposal * Revert change * Don't register crypto twice Co-authored-by: Anil Kumar Kammari Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/genutil/legacy/v036/migrate.go | 2 + x/genutil/legacy/v038/migrate.go | 5 + x/genutil/legacy/v039/migrate.go | 6 + x/genutil/legacy/v040/migrate.go | 6 +- x/gov/legacy/v040/migrate.go | 62 +++++++- x/gov/legacy/v040/migrate_test.go | 247 ++++++++++++++++++++++-------- x/params/legacy/v036/types.go | 172 +++++++++++++++++++++ x/upgrade/legacy/v038/types.go | 166 ++++++++++++++++++++ 8 files changed, 588 insertions(+), 78 deletions(-) create mode 100644 x/params/legacy/v036/types.go create mode 100644 x/upgrade/legacy/v038/types.go diff --git a/x/genutil/legacy/v036/migrate.go b/x/genutil/legacy/v036/migrate.go index 8b71361596..204eebc233 100644 --- a/x/genutil/legacy/v036/migrate.go +++ b/x/genutil/legacy/v036/migrate.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil/types" v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v034" v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v036" ) @@ -28,6 +29,7 @@ func Migrate(appState types.AppMap, _ client.Context) types.AppMap { cryptocodec.RegisterCrypto(v036Codec) v036gov.RegisterLegacyAminoCodec(v036Codec) v036distr.RegisterLegacyAminoCodec(v036Codec) + v036params.RegisterLegacyAminoCodec(v036Codec) // migrate genesis accounts state if appState[v034genAccounts.ModuleName] != nil { diff --git a/x/genutil/legacy/v038/migrate.go b/x/genutil/legacy/v038/migrate.go index 374092298a..d0ca4c4186 100644 --- a/x/genutil/legacy/v038/migrate.go +++ b/x/genutil/legacy/v038/migrate.go @@ -10,8 +10,10 @@ import ( v036genaccounts "github.com/cosmos/cosmos-sdk/x/genaccounts/legacy/v036" "github.com/cosmos/cosmos-sdk/x/genutil/types" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" v036staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v036" v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038" + v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038" ) // Migrate migrates exported state from v0.36/v0.37 to a v0.38 genesis state. @@ -19,11 +21,14 @@ func Migrate(appState types.AppMap, _ client.Context) types.AppMap { v036Codec := codec.NewLegacyAmino() v036gov.RegisterLegacyAminoCodec(v036Codec) v036distr.RegisterLegacyAminoCodec(v036Codec) + v036params.RegisterLegacyAminoCodec(v036Codec) v038Codec := codec.NewLegacyAmino() v038auth.RegisterLegacyAminoCodec(v038Codec) v036gov.RegisterLegacyAminoCodec(v038Codec) v036distr.RegisterLegacyAminoCodec(v038Codec) + v036params.RegisterLegacyAminoCodec(v038Codec) + v038upgrade.RegisterLegacyAminoCodec(v038Codec) if appState[v036genaccounts.ModuleName] != nil { // unmarshal relative source genesis application state diff --git a/x/genutil/legacy/v039/migrate.go b/x/genutil/legacy/v039/migrate.go index 97442e9380..99c7fce772 100644 --- a/x/genutil/legacy/v039/migrate.go +++ b/x/genutil/legacy/v039/migrate.go @@ -8,6 +8,8 @@ import ( v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036" "github.com/cosmos/cosmos-sdk/x/genutil/types" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" + v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038" ) // Migrate migrates exported state from v0.38 to a v0.39 genesis state. @@ -19,11 +21,15 @@ func Migrate(appState types.AppMap, _ client.Context) types.AppMap { v038auth.RegisterLegacyAminoCodec(v038Codec) v036gov.RegisterLegacyAminoCodec(v038Codec) v036distr.RegisterLegacyAminoCodec(v038Codec) + v036params.RegisterLegacyAminoCodec(v038Codec) + v038upgrade.RegisterLegacyAminoCodec(v038Codec) v039Codec := codec.NewLegacyAmino() v039auth.RegisterLegacyAminoCodec(v039Codec) v036gov.RegisterLegacyAminoCodec(v039Codec) v036distr.RegisterLegacyAminoCodec(v039Codec) + v036params.RegisterLegacyAminoCodec(v039Codec) + v038upgrade.RegisterLegacyAminoCodec(v039Codec) // migrate x/auth state (JSON serialization only) if appState[v038auth.ModuleName] != nil { diff --git a/x/genutil/legacy/v040/migrate.go b/x/genutil/legacy/v040/migrate.go index ec71038680..eb5d10690a 100644 --- a/x/genutil/legacy/v040/migrate.go +++ b/x/genutil/legacy/v040/migrate.go @@ -3,7 +3,6 @@ package v040 import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" v039auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v039" v040auth "github.com/cosmos/cosmos-sdk/x/auth/legacy/v040" v036supply "github.com/cosmos/cosmos-sdk/x/bank/legacy/v036" @@ -22,10 +21,12 @@ import ( v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" v039mint "github.com/cosmos/cosmos-sdk/x/mint/legacy/v039" v040mint "github.com/cosmos/cosmos-sdk/x/mint/legacy/v040" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" v039slashing "github.com/cosmos/cosmos-sdk/x/slashing/legacy/v039" v040slashing "github.com/cosmos/cosmos-sdk/x/slashing/legacy/v040" v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038" v040staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v040" + v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038" ) func migrateGenutil(oldGenState v039genutil.GenesisState) *types.GenesisState { @@ -37,10 +38,11 @@ func migrateGenutil(oldGenState v039genutil.GenesisState) *types.GenesisState { // Migrate migrates exported state from v0.39 to a v0.40 genesis state. func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { v039Codec := codec.NewLegacyAmino() - cryptocodec.RegisterCrypto(v039Codec) v039auth.RegisterLegacyAminoCodec(v039Codec) v036gov.RegisterLegacyAminoCodec(v039Codec) v036distr.RegisterLegacyAminoCodec(v039Codec) + v036params.RegisterLegacyAminoCodec(v039Codec) + v038upgrade.RegisterLegacyAminoCodec(v039Codec) v040Codec := clientCtx.JSONMarshaler diff --git a/x/gov/legacy/v040/migrate.go b/x/gov/legacy/v040/migrate.go index 223eb6626c..2accb74284 100644 --- a/x/gov/legacy/v040/migrate.go +++ b/x/gov/legacy/v040/migrate.go @@ -3,12 +3,18 @@ package v040 import ( "fmt" + proto "github.com/gogo/protobuf/proto" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036" v040distr "github.com/cosmos/cosmos-sdk/x/distribution/types" v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" v040gov "github.com/cosmos/cosmos-sdk/x/gov/types" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" + v040params "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038" + v040upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) func migrateVoteOption(oldVoteOption v034gov.VoteOption) v040gov.VoteOption { @@ -60,10 +66,12 @@ func migrateProposalStatus(oldProposalStatus v034gov.ProposalStatus) v040gov.Pro } func migrateContent(oldContent v036gov.Content) *codectypes.Any { + var protoProposal proto.Message + switch oldContent := oldContent.(type) { case v036gov.TextProposal: { - protoProposal := &v040gov.TextProposal{ + protoProposal = &v040gov.TextProposal{ Title: oldContent.Title, Description: oldContent.Description, } @@ -77,23 +85,61 @@ func migrateContent(oldContent v036gov.Content) *codectypes.Any { } case v036distr.CommunityPoolSpendProposal: { - protoProposal := &v040distr.CommunityPoolSpendProposal{ + protoProposal = &v040distr.CommunityPoolSpendProposal{ Title: oldContent.Title, Description: oldContent.Description, Recipient: oldContent.Recipient.String(), Amount: oldContent.Amount, } - // Convert the content into Any. - contentAny, err := codectypes.NewAnyWithValue(protoProposal) - if err != nil { - panic(err) + } + case v038upgrade.CancelSoftwareUpgradeProposal: + { + protoProposal = &v040upgrade.CancelSoftwareUpgradeProposal{ + Description: oldContent.Description, + Title: oldContent.Title, + } + } + case v038upgrade.SoftwareUpgradeProposal: + { + protoProposal = &v040upgrade.SoftwareUpgradeProposal{ + Description: oldContent.Description, + Title: oldContent.Title, + Plan: v040upgrade.Plan{ + Name: oldContent.Plan.Name, + Time: oldContent.Plan.Time, + Height: oldContent.Plan.Height, + Info: oldContent.Plan.Info, + }, + } + } + case v036params.ParameterChangeProposal: + { + newChanges := make([]v040params.ParamChange, len(oldContent.Changes)) + for i, oldChange := range oldContent.Changes { + newChanges[i] = v040params.ParamChange{ + Subspace: oldChange.Subspace, + Key: oldChange.Key, + Value: oldChange.Value, + } } - return contentAny + protoProposal = &v040params.ParameterChangeProposal{ + Description: oldContent.Description, + Title: oldContent.Title, + Changes: newChanges, + } } default: - panic(fmt.Errorf("'%T' is not a valid proposal content type", oldContent)) + panic(fmt.Errorf("%T is not a valid proposal content type", oldContent)) } + + // Convert the content into Any. + contentAny, err := codectypes.NewAnyWithValue(protoProposal) + if err != nil { + panic(err) + } + + return contentAny } // Migrate accepts exported v0.36 x/gov genesis state and migrates it to diff --git a/x/gov/legacy/v040/migrate_test.go b/x/gov/legacy/v040/migrate_test.go index 84c6a554af..049f5b8853 100644 --- a/x/gov/legacy/v040/migrate_test.go +++ b/x/gov/legacy/v040/migrate_test.go @@ -12,6 +12,8 @@ import ( v036distr "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v036" v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" + v036params "github.com/cosmos/cosmos-sdk/x/params/legacy/v036" + v038upgrade "github.com/cosmos/cosmos-sdk/x/upgrade/legacy/v038" ) func TestMigrate(t *testing.T) { @@ -28,8 +30,8 @@ func TestMigrate(t *testing.T) { Proposals: []v036gov.Proposal{ { Content: v036gov.TextProposal{ - Title: "foo_test", - Description: "bar_test", + Title: "foo_text", + Description: "bar_text", }, }, { @@ -40,6 +42,37 @@ func TestMigrate(t *testing.T) { Amount: sdk.NewCoins(sdk.NewCoin("footoken", sdk.NewInt(2))), }, }, + { + Content: v038upgrade.CancelSoftwareUpgradeProposal{ + Title: "foo_cancel_upgrade", + Description: "bar_cancel_upgrade", + }, + }, + { + Content: v038upgrade.SoftwareUpgradeProposal{ + Title: "foo_software_upgrade", + Description: "bar_software_upgrade", + Plan: v038upgrade.Plan{ + Name: "foo_upgrade_name", + Height: 123, + Info: "foo_upgrade_info", + }, + }, + }, + { + Content: v036params.ParameterChangeProposal{ + Title: "foo_param_change", + Description: "bar_param_change", + Changes: []v036params.ParamChange{ + { + Subspace: "foo_param_change_subspace", + Key: "foo_param_change_key", + Subkey: "foo_param_change_subkey", + Value: "foo_param_change_value", + }, + }, + }, + }, }, } @@ -52,76 +85,154 @@ func TestMigrate(t *testing.T) { var jsonObj map[string]interface{} err = json.Unmarshal(bz, &jsonObj) require.NoError(t, err) - indentedBz, err := json.MarshalIndent(jsonObj, "", " ") + indentedBz, err := json.MarshalIndent(jsonObj, "", "\t") require.NoError(t, err) // Make sure about: - // - TextProposal and CommunityPoolSpendProposal have correct any JSON. + // - TextProposal has correct JSON. + // - CommunityPoolSpendProposal has correct JSON. + // - CancelSoftwareUpgradeProposal has correct JSON. + // - SoftwareUpgradeProposal has correct JSON. + // - ParameterChangeProposal has correct JSON. expected := `{ - "deposit_params": { - "max_deposit_period": "0s", - "min_deposit": [] - }, - "deposits": [], - "proposals": [ - { - "content": { - "@type": "/cosmos.gov.v1beta1.TextProposal", - "description": "bar_test", - "title": "foo_test" - }, - "deposit_end_time": "0001-01-01T00:00:00Z", - "final_tally_result": { - "abstain": "0", - "no": "0", - "no_with_veto": "0", - "yes": "0" - }, - "proposal_id": "0", - "status": "PROPOSAL_STATUS_UNSPECIFIED", - "submit_time": "0001-01-01T00:00:00Z", - "total_deposit": [], - "voting_end_time": "0001-01-01T00:00:00Z", - "voting_start_time": "0001-01-01T00:00:00Z" - }, - { - "content": { - "@type": "/cosmos.distribution.v1beta1.CommunityPoolSpendProposal", - "amount": [ - { - "amount": "2", - "denom": "footoken" - } - ], - "description": "bar_community", - "recipient": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", - "title": "foo_community" - }, - "deposit_end_time": "0001-01-01T00:00:00Z", - "final_tally_result": { - "abstain": "0", - "no": "0", - "no_with_veto": "0", - "yes": "0" - }, - "proposal_id": "0", - "status": "PROPOSAL_STATUS_UNSPECIFIED", - "submit_time": "0001-01-01T00:00:00Z", - "total_deposit": [], - "voting_end_time": "0001-01-01T00:00:00Z", - "voting_start_time": "0001-01-01T00:00:00Z" - } - ], - "starting_proposal_id": "0", - "tally_params": { - "quorum": "0", - "threshold": "0", - "veto_threshold": "0" - }, - "votes": [], - "voting_params": { - "voting_period": "0s" - } + "deposit_params": { + "max_deposit_period": "0s", + "min_deposit": [] + }, + "deposits": [], + "proposals": [ + { + "content": { + "@type": "/cosmos.gov.v1beta1.TextProposal", + "description": "bar_text", + "title": "foo_text" + }, + "deposit_end_time": "0001-01-01T00:00:00Z", + "final_tally_result": { + "abstain": "0", + "no": "0", + "no_with_veto": "0", + "yes": "0" + }, + "proposal_id": "0", + "status": "PROPOSAL_STATUS_UNSPECIFIED", + "submit_time": "0001-01-01T00:00:00Z", + "total_deposit": [], + "voting_end_time": "0001-01-01T00:00:00Z", + "voting_start_time": "0001-01-01T00:00:00Z" + }, + { + "content": { + "@type": "/cosmos.distribution.v1beta1.CommunityPoolSpendProposal", + "amount": [ + { + "amount": "2", + "denom": "footoken" + } + ], + "description": "bar_community", + "recipient": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh", + "title": "foo_community" + }, + "deposit_end_time": "0001-01-01T00:00:00Z", + "final_tally_result": { + "abstain": "0", + "no": "0", + "no_with_veto": "0", + "yes": "0" + }, + "proposal_id": "0", + "status": "PROPOSAL_STATUS_UNSPECIFIED", + "submit_time": "0001-01-01T00:00:00Z", + "total_deposit": [], + "voting_end_time": "0001-01-01T00:00:00Z", + "voting_start_time": "0001-01-01T00:00:00Z" + }, + { + "content": { + "@type": "/cosmos.upgrade.v1beta1.CancelSoftwareUpgradeProposal", + "description": "bar_cancel_upgrade", + "title": "foo_cancel_upgrade" + }, + "deposit_end_time": "0001-01-01T00:00:00Z", + "final_tally_result": { + "abstain": "0", + "no": "0", + "no_with_veto": "0", + "yes": "0" + }, + "proposal_id": "0", + "status": "PROPOSAL_STATUS_UNSPECIFIED", + "submit_time": "0001-01-01T00:00:00Z", + "total_deposit": [], + "voting_end_time": "0001-01-01T00:00:00Z", + "voting_start_time": "0001-01-01T00:00:00Z" + }, + { + "content": { + "@type": "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + "description": "bar_software_upgrade", + "plan": { + "height": "123", + "info": "foo_upgrade_info", + "name": "foo_upgrade_name", + "time": "0001-01-01T00:00:00Z", + "upgraded_client_state": null + }, + "title": "foo_software_upgrade" + }, + "deposit_end_time": "0001-01-01T00:00:00Z", + "final_tally_result": { + "abstain": "0", + "no": "0", + "no_with_veto": "0", + "yes": "0" + }, + "proposal_id": "0", + "status": "PROPOSAL_STATUS_UNSPECIFIED", + "submit_time": "0001-01-01T00:00:00Z", + "total_deposit": [], + "voting_end_time": "0001-01-01T00:00:00Z", + "voting_start_time": "0001-01-01T00:00:00Z" + }, + { + "content": { + "@type": "/cosmos.params.v1beta1.ParameterChangeProposal", + "changes": [ + { + "key": "foo_param_change_key", + "subspace": "foo_param_change_subspace", + "value": "foo_param_change_value" + } + ], + "description": "bar_param_change", + "title": "foo_param_change" + }, + "deposit_end_time": "0001-01-01T00:00:00Z", + "final_tally_result": { + "abstain": "0", + "no": "0", + "no_with_veto": "0", + "yes": "0" + }, + "proposal_id": "0", + "status": "PROPOSAL_STATUS_UNSPECIFIED", + "submit_time": "0001-01-01T00:00:00Z", + "total_deposit": [], + "voting_end_time": "0001-01-01T00:00:00Z", + "voting_start_time": "0001-01-01T00:00:00Z" + } + ], + "starting_proposal_id": "0", + "tally_params": { + "quorum": "0", + "threshold": "0", + "veto_threshold": "0" + }, + "votes": [], + "voting_params": { + "voting_period": "0s" + } }` require.Equal(t, expected, string(indentedBz)) diff --git a/x/params/legacy/v036/types.go b/x/params/legacy/v036/types.go new file mode 100644 index 0000000000..66cc9e7d8a --- /dev/null +++ b/x/params/legacy/v036/types.go @@ -0,0 +1,172 @@ +package v036 + +import ( + "fmt" + "strings" + + "github.com/cosmos/cosmos-sdk/codec" + v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" +) + +const ( + // ModuleName defines the name of the module + ModuleName = "params" + + // RouterKey defines the routing key for a ParameterChangeProposal + RouterKey = "params" +) + +const ( + // ProposalTypeChange defines the type for a ParameterChangeProposal + ProposalTypeChange = "ParameterChange" +) + +// Param module codespace constants +const ( + DefaultCodespace = "params" + + CodeUnknownSubspace = 1 + CodeSettingParameter = 2 + CodeEmptyData = 3 +) + +// Assert ParameterChangeProposal implements v036gov.Content at compile-time +var _ v036gov.Content = ParameterChangeProposal{} + +// ParameterChangeProposal defines a proposal which contains multiple parameter +// changes. +type ParameterChangeProposal struct { + Title string `json:"title" yaml:"title"` + Description string `json:"description" yaml:"description"` + Changes []ParamChange `json:"changes" yaml:"changes"` +} + +func NewParameterChangeProposal(title, description string, changes []ParamChange) ParameterChangeProposal { + return ParameterChangeProposal{title, description, changes} +} + +// GetTitle returns the title of a parameter change proposal. +func (pcp ParameterChangeProposal) GetTitle() string { return pcp.Title } + +// GetDescription returns the description of a parameter change proposal. +func (pcp ParameterChangeProposal) GetDescription() string { return pcp.Description } + +// GetDescription returns the routing key of a parameter change proposal. +func (pcp ParameterChangeProposal) ProposalRoute() string { return RouterKey } + +// ProposalType returns the type of a parameter change proposal. +func (pcp ParameterChangeProposal) ProposalType() string { return ProposalTypeChange } + +// ValidateBasic validates the parameter change proposal +func (pcp ParameterChangeProposal) ValidateBasic() error { + err := v036gov.ValidateAbstract(pcp) + if err != nil { + return err + } + + return ValidateChanges(pcp.Changes) +} + +// String implements the Stringer interface. +func (pcp ParameterChangeProposal) String() string { + var b strings.Builder + + b.WriteString(fmt.Sprintf(`Parameter Change Proposal: + Title: %s + Description: %s + Changes: +`, pcp.Title, pcp.Description)) + + for _, pc := range pcp.Changes { + b.WriteString(fmt.Sprintf(` Param Change: + Subspace: %s + Key: %s + Subkey: %X + Value: %X +`, pc.Subspace, pc.Key, pc.Subkey, pc.Value)) + } + + return b.String() +} + +// ParamChange defines a parameter change. +type ParamChange struct { + Subspace string `json:"subspace" yaml:"subspace"` + Key string `json:"key" yaml:"key"` + Subkey string `json:"subkey,omitempty" yaml:"subkey,omitempty"` + Value string `json:"value" yaml:"value"` +} + +func NewParamChange(subspace, key, value string) ParamChange { + return ParamChange{subspace, key, "", value} +} + +func NewParamChangeWithSubkey(subspace, key, subkey, value string) ParamChange { + return ParamChange{subspace, key, subkey, value} +} + +// String implements the Stringer interface. +func (pc ParamChange) String() string { + return fmt.Sprintf(`Param Change: + Subspace: %s + Key: %s + Subkey: %X + Value: %X +`, pc.Subspace, pc.Key, pc.Subkey, pc.Value) +} + +// ValidateChange performs basic validation checks over a set of ParamChange. It +// returns an error if any ParamChange is invalid. +func ValidateChanges(changes []ParamChange) error { + if len(changes) == 0 { + return ErrEmptyChanges(DefaultCodespace) + } + + for _, pc := range changes { + if len(pc.Subspace) == 0 { + return ErrEmptySubspace(DefaultCodespace) + } + if len(pc.Key) == 0 { + return ErrEmptyKey(DefaultCodespace) + } + if len(pc.Value) == 0 { + return ErrEmptyValue(DefaultCodespace) + } + } + + return nil +} + +// ErrUnknownSubspace returns an unknown subspace error. +func ErrUnknownSubspace(codespace string, space string) error { + return fmt.Errorf("unknown subspace %s", space) +} + +// ErrSettingParameter returns an error for failing to set a parameter. +func ErrSettingParameter(codespace string, key, subkey, value, msg string) error { + return fmt.Errorf("error setting parameter %s on %s (%s): %s", value, key, subkey, msg) +} + +// ErrEmptyChanges returns an error for empty parameter changes. +func ErrEmptyChanges(codespace string) error { + return fmt.Errorf("submitted parameter changes are empty") +} + +// ErrEmptySubspace returns an error for an empty subspace. +func ErrEmptySubspace(codespace string) error { + return fmt.Errorf("parameter subspace is empty") +} + +// ErrEmptyKey returns an error for when an empty key is given. +func ErrEmptyKey(codespace string) error { + return fmt.Errorf("parameter key is empty") +} + +// ErrEmptyValue returns an error for when an empty key is given. +func ErrEmptyValue(codespace string) error { + return fmt.Errorf("parameter value is empty") +} + +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(ParameterChangeProposal{}, "cosmos-sdk/ParameterChangeProposal", nil) +} diff --git a/x/upgrade/legacy/v038/types.go b/x/upgrade/legacy/v038/types.go new file mode 100644 index 0000000000..fb06a6dc5a --- /dev/null +++ b/x/upgrade/legacy/v038/types.go @@ -0,0 +1,166 @@ +package v038 + +import ( + "fmt" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" +) + +const ( + // ModuleName is the name of this module + ModuleName = "upgrade" + + // RouterKey is used to route governance proposals + RouterKey = ModuleName + + // StoreKey is the prefix under which we store this module's data + StoreKey = ModuleName + + // QuerierKey is used to handle abci_query requests + QuerierKey = ModuleName +) + +// Plan specifies information about a planned upgrade and when it should occur +type Plan struct { + // Sets the name for the upgrade. This name will be used by the upgraded version of the software to apply any + // special "on-upgrade" commands during the first BeginBlock method after the upgrade is applied. It is also used + // to detect whether a software version can handle a given upgrade. If no upgrade handler with this name has been + // set in the software, it will be assumed that the software is out-of-date when the upgrade Time or Height + // is reached and the software will exit. + Name string `json:"name,omitempty"` + + // The time after which the upgrade must be performed. + // Leave set to its zero value to use a pre-defined Height instead. + Time time.Time `json:"time,omitempty"` + + // The height at which the upgrade must be performed. + // Only used if Time is not set. + Height int64 `json:"height,omitempty"` + + // Any application specific upgrade info to be included on-chain + // such as a git commit that validators could automatically upgrade to + Info string `json:"info,omitempty"` +} + +func (p Plan) String() string { + due := p.DueAt() + dueUp := strings.ToUpper(due[0:1]) + due[1:] + return fmt.Sprintf(`Upgrade Plan + Name: %s + %s + Info: %s`, p.Name, dueUp, p.Info) +} + +// ValidateBasic does basic validation of a Plan +func (p Plan) ValidateBasic() error { + if len(p.Name) == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "name cannot be empty") + } + if p.Height < 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "height cannot be negative") + } + if p.Time.IsZero() && p.Height == 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "must set either time or height") + } + if !p.Time.IsZero() && p.Height != 0 { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "cannot set both time and height") + } + + return nil +} + +// ShouldExecute returns true if the Plan is ready to execute given the current context +func (p Plan) ShouldExecute(ctx sdk.Context) bool { + if !p.Time.IsZero() { + return !ctx.BlockTime().Before(p.Time) + } + if p.Height > 0 { + return p.Height <= ctx.BlockHeight() + } + return false +} + +// DueAt is a string representation of when this plan is due to be executed +func (p Plan) DueAt() string { + if !p.Time.IsZero() { + return fmt.Sprintf("time: %s", p.Time.UTC().Format(time.RFC3339)) + } + return fmt.Sprintf("height: %d", p.Height) +} + +const ( + ProposalTypeSoftwareUpgrade string = "SoftwareUpgrade" + ProposalTypeCancelSoftwareUpgrade string = "CancelSoftwareUpgrade" +) + +// Software Upgrade Proposals +type SoftwareUpgradeProposal struct { + Title string `json:"title" yaml:"title"` + Description string `json:"description" yaml:"description"` + Plan Plan `json:"plan" yaml:"plan"` +} + +func NewSoftwareUpgradeProposal(title, description string, plan Plan) v036gov.Content { + return SoftwareUpgradeProposal{title, description, plan} +} + +// Implements Proposal Interface +var _ v036gov.Content = SoftwareUpgradeProposal{} + +func (sup SoftwareUpgradeProposal) GetTitle() string { return sup.Title } +func (sup SoftwareUpgradeProposal) GetDescription() string { return sup.Description } +func (sup SoftwareUpgradeProposal) ProposalRoute() string { return RouterKey } +func (sup SoftwareUpgradeProposal) ProposalType() string { return ProposalTypeSoftwareUpgrade } +func (sup SoftwareUpgradeProposal) ValidateBasic() error { + if err := sup.Plan.ValidateBasic(); err != nil { + return err + } + return v036gov.ValidateAbstract(sup) +} + +func (sup SoftwareUpgradeProposal) String() string { + return fmt.Sprintf(`Software Upgrade Proposal: + Title: %s + Description: %s +`, sup.Title, sup.Description) +} + +// Cancel Software Upgrade Proposals +type CancelSoftwareUpgradeProposal struct { + Title string `json:"title" yaml:"title"` + Description string `json:"description" yaml:"description"` +} + +func NewCancelSoftwareUpgradeProposal(title, description string) v036gov.Content { + return CancelSoftwareUpgradeProposal{title, description} +} + +// Implements Proposal Interface +var _ v036gov.Content = CancelSoftwareUpgradeProposal{} + +func (sup CancelSoftwareUpgradeProposal) GetTitle() string { return sup.Title } +func (sup CancelSoftwareUpgradeProposal) GetDescription() string { return sup.Description } +func (sup CancelSoftwareUpgradeProposal) ProposalRoute() string { return RouterKey } +func (sup CancelSoftwareUpgradeProposal) ProposalType() string { + return ProposalTypeCancelSoftwareUpgrade +} +func (sup CancelSoftwareUpgradeProposal) ValidateBasic() error { + return v036gov.ValidateAbstract(sup) +} + +func (sup CancelSoftwareUpgradeProposal) String() string { + return fmt.Sprintf(`Cancel Software Upgrade Proposal: + Title: %s + Description: %s +`, sup.Title, sup.Description) +} + +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(SoftwareUpgradeProposal{}, "cosmos-sdk/SoftwareUpgradeProposal", nil) + cdc.RegisterConcrete(CancelSoftwareUpgradeProposal{}, "cosmos-sdk/CancelSoftwareUpgradeProposal", nil) +} From 9c47612b5d4e753a763673ad7a56570caeff72af Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 25 Nov 2020 11:23:37 +0000 Subject: [PATCH 53/57] Makefile: use docker run --rm whenever possible (#8026) Remove terminated containers once their execution has finished. This saves the users a bit of disk space. Closes: #8023 --- Makefile | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 1d8164219f..4c94c2d492 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ BUILDDIR ?= $(CURDIR)/build SIMAPP = ./simapp MOCKS_DIR = $(CURDIR)/tests/mocks HTTPS_GIT := https://github.com/cosmos/cosmos-sdk.git -DOCKER_BUF := docker run -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf +DOCKER := $(shell which docker) +DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf export GO111MODULE = on @@ -112,26 +113,26 @@ $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ build-simd-all: go.sum - docker rm latest-build || true - docker run --volume=$(CURDIR):/sources:ro \ + $(DOCKER) rm latest-build || true + $(DOCKER) run --volume=$(CURDIR):/sources:ro \ --env TARGET_PLATFORMS='linux/amd64 darwin/amd64 linux/arm64 windows/amd64' \ --env APP=simd \ --env VERSION=$(VERSION) \ --env COMMIT=$(COMMIT) \ --env LEDGER_ENABLED=$(LEDGER_ENABLED) \ --name latest-build cosmossdk/rbuilder:latest - docker cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ + $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ build-simd-linux: go.sum $(BUILDDIR)/ - docker rm latest-build || true - docker run --volume=$(CURDIR):/sources:ro \ + $(DOCKER) rm latest-build || true + $(DOCKER) run --volume=$(CURDIR):/sources:ro \ --env TARGET_PLATFORMS='linux/amd64' \ --env APP=simd \ --env VERSION=$(VERSION) \ --env COMMIT=$(COMMIT) \ --env LEDGER_ENABLED=false \ --name latest-build cosmossdk/rbuilder:latest - docker cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ + $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ cp artifacts/simd-*-linux-amd64 $(BUILDDIR)/simd cosmovisor: @@ -333,12 +334,12 @@ format: DEVDOC_SAVE = docker commit `docker ps -a -n 1 -q` devdoc:local devdoc-init: - docker run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" tendermint/devdoc echo + $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" tendermint/devdoc echo # TODO make this safer $(call DEVDOC_SAVE) devdoc: - docker run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" devdoc:local bash + $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" devdoc:local bash devdoc-save: # TODO make this safer @@ -360,17 +361,17 @@ proto-all: proto-format proto-lint proto-check-breaking proto-gen proto-gen: @echo "Generating Protobuf files" - docker run -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh + $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh proto-format: @echo "Formatting Protobuf files" - docker run -v $(CURDIR):/workspace \ + $(DOCKER) run --rm -v $(CURDIR):/workspace \ --workdir /workspace tendermintdev/docker-build-proto \ find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \; # This generates the SDK's custom wrapper for google.protobuf.Any. It should only be run manually when needed proto-gen-any: - docker run -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen-any.sh + $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen-any.sh proto-swagger-gen: @./scripts/protoc-swagger-gen.sh @@ -440,8 +441,8 @@ proto-update-deps: # Run a 4-node testnet locally localnet-start: build-linux localnet-stop - $(if $(shell docker inspect -f '{{ .Id }}' cosmossdk/simd-env 2>/dev/null),$(info found image cosmossdk/simd-env),$(MAKE) -C contrib/images simd-env) - if ! [ -f build/node0/simd/config/genesis.json ]; then docker run --rm \ + $(if $(shell $(DOCKER) inspect -f '{{ .Id }}' cosmossdk/simd-env 2>/dev/null),$(info found image cosmossdk/simd-env),$(MAKE) -C contrib/images simd-env) + if ! [ -f build/node0/simd/config/genesis.json ]; then $(DOCKER) run --rm \ --user $(shell id -u):$(shell id -g) \ -v $(BUILDDIR):/simd:Z \ -v /etc/group:/etc/group:ro \ From a9dd334c344f3edb2c1055b5809bad90b24db13e Mon Sep 17 00:00:00 2001 From: Amaury Date: Wed, 25 Nov 2020 13:02:31 +0100 Subject: [PATCH 54/57] Fix legacy querying tx ("unregistered type" bug) (#7992) * Add tests for query txs * Add test for IBC * Refactor checkSignModeError * Fix lint * Add successful IBC test * Remove logs * break * Remove known errors * Update error message * Better comments * Revert variable renaming * Fix lint * Add mention of gRPC as TODO --- docs/migrations/rest.md | 5 + x/auth/client/rest/decode.go | 5 +- x/auth/client/rest/query.go | 32 ++-- x/auth/client/rest/rest_test.go | 260 +++++++++++++++++++++++--------- 4 files changed, 211 insertions(+), 91 deletions(-) diff --git a/docs/migrations/rest.md b/docs/migrations/rest.md index 4de2946faa..d418587d08 100644 --- a/docs/migrations/rest.md +++ b/docs/migrations/rest.md @@ -16,6 +16,7 @@ Some important information concerning all legacy REST endpoints: | Legacy REST Endpoint | Description | Breaking Change | | ------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `POST /txs` | Query tx by hash | Endpoint will error when trying to broadcast transactions that don't support Amino serialization (e.g. IBC txs)1. | | `GET /txs/{hash}` | Query tx by hash | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | | `GET /txs` | Query tx by events | Endpoint will error when trying to output transactions that don't support Amino serialization (e.g. IBC txs)1. | | `GET /staking/validators` | Get all validators | BondStatus is now a protobuf enum instead of an int32, and JSON serialized using its protobuf name, so expect query parameters like `?status=BOND_STATUS_{BONDED,UNBONDED,UNBONDING}` as opposed to `?status={bonded,unbonded,unbonding}`. | @@ -87,3 +88,7 @@ Some modules expose legacy `POST` endpoints to generate unsigned transactions fo | `POST /upgrade/*` | Create unsigned `Msg`s for upgrade | N/A, use Protobuf directly | | `GET /upgrade/current` | Get the current plan | `GET /cosmos/upgrade/v1beta1/current_plan` | | `GET /upgrade/applied_plan/{name}` | Get a previously applied plan | `GET /cosmos/upgrade/v1beta1/applied/{name}` | + +## Migrating to gRPC + +Instead of hitting REST endpoints as described in the previous paragraph, the SDK also exposes a gRPC server. Any client can use gRPC instead of REST to interact with the node. An overview of different ways to communicate with a node can be found [here (TODO)](https://github.com/cosmos/cosmos-sdk/issues/7657), and a concrete tutorial for setting up a gRPC client [here (TODO)](https://github.com/cosmos/cosmos-sdk/issues/7657). diff --git a/x/auth/client/rest/decode.go b/x/auth/client/rest/decode.go index d048f91b4c..3061d71cf4 100644 --- a/x/auth/client/rest/decode.go +++ b/x/auth/client/rest/decode.go @@ -55,9 +55,10 @@ func DecodeTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { response := DecodeResp(stdTx) - err = checkSignModeError(w, clientCtx, response, "/cosmos/tx/v1beta1/txs/decode") + err = checkSignModeError(clientCtx, response, "/cosmos/tx/v1beta1/txs/decode") if err != nil { - // Error is already returned by checkSignModeError. + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 674e24a008..f9abae6b71 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -18,8 +18,6 @@ import ( genutilrest "github.com/cosmos/cosmos-sdk/x/genutil/client/rest" ) -const unRegisteredConcreteTypeErr = "unregistered concrete type" - // QueryAccountRequestHandlerFn is the query accountREST Handler. func QueryAccountRequestHandlerFn(storeName string, clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -110,9 +108,10 @@ func QueryTxsRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { packStdTxResponse(w, clientCtx, txRes) } - err = checkSignModeError(w, clientCtx, searchResult, "/cosmos/tx/v1beta1/txs") + err = checkSignModeError(clientCtx, searchResult, "/cosmos/tx/v1beta1/txs") if err != nil { - // Error is already returned by checkSignModeError. + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return } @@ -152,9 +151,10 @@ func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr)) } - err = checkSignModeError(w, clientCtx, output, "/cosmos/tx/v1beta1/tx/{txhash}") + err = checkSignModeError(clientCtx, output, "/cosmos/tx/v1beta1/tx/{txhash}") if err != nil { - // Error is already returned by checkSignModeError. + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return } @@ -198,18 +198,22 @@ func packStdTxResponse(w http.ResponseWriter, clientCtx client.Context, txRes *s return nil } -func checkSignModeError(w http.ResponseWriter, ctx client.Context, resp interface{}, grpcEndPoint string) error { +// checkSignModeError checks if there are errors with marshalling non-amino +// txs with amino. +func checkSignModeError(ctx client.Context, resp interface{}, grpcEndPoint string) error { // LegacyAmino used intentionally here to handle the SignMode errors marshaler := ctx.LegacyAmino _, err := marshaler.MarshalJSON(resp) - if err != nil && strings.Contains(err.Error(), unRegisteredConcreteTypeErr) { - rest.WriteErrorResponse(w, http.StatusInternalServerError, - "This transaction was created with the new SIGN_MODE_DIRECT signing method, and therefore cannot be displayed"+ - " via legacy REST handlers, please use CLI or directly query the Tendermint RPC endpoint to query"+ - " this transaction. gRPC gateway endpoint is "+grpcEndPoint+". Please also see the REST endpoints migration"+ - " guide at "+clientrest.DeprecationURL+".") - return err + if err != nil { + + // If there's an unmarshalling error, we assume that it's because we're + // using amino to unmarshal a non-amino tx. + return fmt.Errorf("this transaction cannot be displayed via legacy REST endpoints, because it does not support"+ + " Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC"+ + " endpoint to query this transaction. The new REST endpoint (via gRPC-gateway) is %s. Please also see the"+ + "REST endpoints migration guide at %s for more info", grpcEndPoint, clientrest.DeprecationURL) + } return nil diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index 889067d852..1d7cac6848 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/spf13/cobra" "github.com/stretchr/testify/suite" "github.com/cosmos/cosmos-sdk/client/flags" @@ -16,16 +17,16 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" "github.com/cosmos/cosmos-sdk/types/tx/signing" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" - bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" - ibccli "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/client/cli" - - txtypes "github.com/cosmos/cosmos-sdk/types/tx" rest2 "github.com/cosmos/cosmos-sdk/x/auth/client/rest" "github.com/cosmos/cosmos-sdk/x/auth/legacy/legacytx" + bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil" "github.com/cosmos/cosmos-sdk/x/bank/types" + ibccli "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/client/cli" + ibcsolomachinecli "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/client/cli" ) type IntegrationTestSuite struct { @@ -129,51 +130,99 @@ func (s *IntegrationTestSuite) TestBroadcastTxRequest() { s.Require().NotEmpty(txRes.TxHash) } -func (s *IntegrationTestSuite) TestQueryTxByHash() { +// Helper function to test querying txs. We will use it to query StdTx and service `Msg`s. +func (s *IntegrationTestSuite) testQueryTx(txHeight int64, txHash, txRecipient string) { + val0 := s.network.Validators[0] + + testCases := []struct { + desc string + malleate func() *sdk.TxResponse + }{ + { + "Query by hash", + func() *sdk.TxResponse { + txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs/%s", val0.APIAddress, txHash)) + s.Require().NoError(err) + + var txResAmino sdk.TxResponse + s.Require().NoError(val0.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &txResAmino)) + return &txResAmino + }, + }, + { + "Query by height", + func() *sdk.TxResponse { + txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs?limit=10&page=1&tx.height=%d", val0.APIAddress, txHeight)) + s.Require().NoError(err) + + var searchtxResult sdk.SearchTxsResult + s.Require().NoError(val0.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &searchtxResult)) + s.Require().Len(searchtxResult.Txs, 1) + return searchtxResult.Txs[0] + }, + }, + { + "Query by event (transfer.recipient)", + func() *sdk.TxResponse { + txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs?transfer.recipient=%s", val0.APIAddress, txRecipient)) + s.Require().NoError(err) + + var searchtxResult sdk.SearchTxsResult + s.Require().NoError(val0.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &searchtxResult)) + s.Require().Len(searchtxResult.Txs, 1) + return searchtxResult.Txs[0] + }, + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("Case %s", tc.desc), func() { + txResponse := tc.malleate() + + // Check that the height is correct. + s.Require().Equal(txHeight, txResponse.Height) + + // Check that the events are correct. + s.Require().Contains( + txResponse.RawLog, + fmt.Sprintf("{\"key\":\"recipient\",\"value\":\"%s\"}", txRecipient), + ) + + // Check that the Msg is correct. + stdTx, ok := txResponse.Tx.GetCachedValue().(legacytx.StdTx) + s.Require().True(ok) + msgs := stdTx.GetMsgs() + s.Require().Equal(len(msgs), 1) + msg, ok := msgs[0].(*types.MsgSend) + s.Require().True(ok) + s.Require().Equal(txRecipient, msg.ToAddress) + }) + } +} + +func (s *IntegrationTestSuite) TestQueryTxWithStdTx() { val0 := s.network.Validators[0] // We broadcasted a StdTx in SetupSuite. - // we just check for a non-empty TxHash here, the actual hash will depend on the underlying tx configuration + // We just check for a non-empty TxHash here, the actual hash will depend on the underlying tx configuration s.Require().NotEmpty(s.stdTxRes.TxHash) - // We now fetch the tx by hash on the `/tx/{hash}` route. - txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs/%s", val0.APIAddress, s.stdTxRes.TxHash)) - s.Require().NoError(err) - - // txJSON should contain the whole tx, we just make sure that our custom - // memo is there. - s.Require().Contains(string(txJSON), s.stdTx.Memo) + s.testQueryTx(s.stdTxRes.Height, s.stdTxRes.TxHash, val0.Address.String()) } -func (s *IntegrationTestSuite) TestQueryTxByHeight() { - val0 := s.network.Validators[0] - - // We broadcasted a StdTx in SetupSuite. - // we just check for a non-empty height here, as we'll need to for querying. - s.Require().NotEmpty(s.stdTxRes.Height) - - // We now fetch the tx on `/txs` route, filtering by `tx.height` - txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs?limit=10&page=1&tx.height=%d", val0.APIAddress, s.stdTxRes.Height)) - s.Require().NoError(err) - - // txJSON should contain the whole tx, we just make sure that our custom - // memo is there. - s.Require().Contains(string(txJSON), s.stdTx.Memo) -} - -func (s *IntegrationTestSuite) TestQueryTxByHashWithServiceMessage() { +func (s *IntegrationTestSuite) TestQueryTxWithServiceMessage() { val := s.network.Validators[0] sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10) + _, _, addr := testdata.KeyTestPubAddr() - // Right after this line, we're sending a tx. Might need to wait a block - // to refresh sequences. + // Might need to wait a block to refresh sequences from previous setups. s.Require().NoError(s.network.WaitForNextBlock()) out, err := bankcli.ServiceMsgSendExec( val.ClientCtx, val.Address, - val.Address, + addr, sdk.NewCoins(sendTokens), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), @@ -188,17 +237,7 @@ func (s *IntegrationTestSuite) TestQueryTxByHashWithServiceMessage() { s.Require().NoError(s.network.WaitForNextBlock()) - txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs/%s", val.APIAddress, txRes.TxHash)) - s.Require().NoError(err) - - var txResAmino sdk.TxResponse - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &txResAmino)) - stdTx, ok := txResAmino.Tx.GetCachedValue().(legacytx.StdTx) - s.Require().True(ok) - msgs := stdTx.GetMsgs() - s.Require().Equal(len(msgs), 1) - _, ok = msgs[0].(*types.MsgSend) - s.Require().True(ok) + s.testQueryTx(txRes.Height, txRes.TxHash, addr.String()) } func (s *IntegrationTestSuite) TestMultipleSyncBroadcastTxRequests() { @@ -303,42 +342,43 @@ func (s *IntegrationTestSuite) broadcastReq(stdTx legacytx.StdTx, mode string) ( return rest.PostRequest(fmt.Sprintf("%s/txs", val.APIAddress), "application/json", bz) } -func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { +// testQueryIBCTx is a helper function to test querying txs which: +// - show an error message on legacy REST endpoints +// - succeed using gRPC +// In practise, we call this function on IBC txs. +func (s *IntegrationTestSuite) testQueryIBCTx(txRes sdk.TxResponse, cmd *cobra.Command, args []string) { val := s.network.Validators[0] - args := []string{ - "121", // dummy port-id - "channel-0", // dummy channel-id - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), - fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - fmt.Sprintf("--%s=foobar", flags.FlagMemo), + errMsg := "this transaction cannot be displayed via legacy REST endpoints, because it does not support" + + " Amino serialization. Please either use CLI, gRPC, gRPC-gateway, or directly query the Tendermint RPC" + + " endpoint to query this transaction. The new REST endpoint (via gRPC-gateway) is " + + // Test that legacy endpoint return the above error message on IBC txs. + testCases := []struct { + desc string + url string + }{ + { + "Query by hash", + fmt.Sprintf("%s/txs/%s", val.APIAddress, txRes.TxHash), + }, + { + "Query by height", + fmt.Sprintf("%s/txs?tx.height=%d", val.APIAddress, txRes.Height), + }, } - // created a dummy txn for IBC, eventually it fails. Our intension is to test the error message of querying a - // message which is signed with proto, since IBC won't support legacy amino at all we are considering a message from IBC module. - out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, ibccli.NewChannelCloseInitCmd(), args) - s.Require().NoError(err) + for _, tc := range testCases { + s.Run(fmt.Sprintf("Case %s", tc.desc), func() { + txJSON, err := rest.GetRequest(tc.url) + s.Require().NoError(err) - var txRes sdk.TxResponse - s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + var errResp rest.ErrorResponse + s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &errResp)) - s.Require().NoError(s.network.WaitForNextBlock()) - - // try to fetch the txn using legacy rest, this won't work since the ibc module doesn't support amino. - txJSON, err := rest.GetRequest(fmt.Sprintf("%s/txs/%s", val.APIAddress, txRes.TxHash)) - s.Require().NoError(err) - - var errResp rest.ErrorResponse - s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(txJSON, &errResp)) - - errMsg := "This transaction was created with the new SIGN_MODE_DIRECT signing method, " + - "and therefore cannot be displayed via legacy REST handlers, please use CLI or directly query the Tendermint " + - "RPC endpoint to query this transaction." - - s.Require().Contains(errResp.Error, errMsg) + s.Require().Contains(errResp.Error, errMsg) + }) + } // try fetching the txn using gRPC req, it will fetch info since it has proto codec. grpcJSON, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/tx/%s", val.APIAddress, txRes.TxHash)) @@ -350,7 +390,7 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { // generate broadcast only txn. args = append(args, fmt.Sprintf("--%s=true", flags.FlagGenerateOnly)) - out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, ibccli.NewChannelCloseInitCmd(), args) + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args) s.Require().NoError(err) txFile, cleanup := testutil.WriteToNewTempFile(s.T(), string(out.Bytes())) @@ -368,10 +408,80 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { res, err := rest.PostRequest(fmt.Sprintf("%s/txs/decode", val.APIAddress), "application/json", bz) s.Require().NoError(err) + var errResp rest.ErrorResponse s.Require().NoError(val.ClientCtx.LegacyAmino.UnmarshalJSON(res, &errResp)) s.Require().Contains(errResp.Error, errMsg) } +// TestLegacyRestErrMessages creates two IBC txs, one that fails, one that +// succeeds, and make sure we cannot query any of them (with pretty error msg). +// Our intension is to test the error message of querying a message which is +// signed with proto, since IBC won't support legacy amino at all we are +// considering a message from IBC module. +func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { + val := s.network.Validators[0] + + // Write consensus json to temp file, used for an IBC message. + consensusJSON, cleanup := testutil.WriteToNewTempFile( + s.T(), + `{"public_key":{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A/3SXL2ONYaOkxpdR5P8tHTlSlPv1AwQwSFxKRee5JQW"},"diversifier":"diversifier","timestamp":"10"}`, + ) + defer cleanup() + + testCases := []struct { + desc string + cmd *cobra.Command + args []string + code uint32 + }{ + { + "Failing IBC message", + ibccli.NewChannelCloseInitCmd(), + []string{ + "121", // dummy port-id + "channel-0", // dummy channel-id + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=foobar", flags.FlagMemo), + }, + uint32(7), + }, + { + "Successful IBC message", + ibcsolomachinecli.NewCreateClientCmd(), + []string{ + "21212121212", // dummy client-id + "1", // dummy sequence + consensusJSON.Name(), // path to consensus json, + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--gas=%d", flags.DefaultGasLimit), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=foobar", flags.FlagMemo), + }, + uint32(0), + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("Case %s", tc.desc), func() { + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, tc.cmd, tc.args) + s.Require().NoError(err) + var txRes sdk.TxResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &txRes)) + s.Require().Equal(tc.code, txRes.Code) + + s.Require().NoError(s.network.WaitForNextBlock()) + + s.testQueryIBCTx(txRes, tc.cmd, tc.args) + }) + } +} + func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } From c58a8923a0ce8344c249a191af2138a8dfedb105 Mon Sep 17 00:00:00 2001 From: MD Aleem <72057206+aleem1413@users.noreply.github.com> Date: Wed, 25 Nov 2020 21:28:11 +0530 Subject: [PATCH 55/57] gRPC-gateway routes as alternative to legacy tendermint REST endpoints (#7965) * WIP * WIP setup * WIP setup testsuite * add node_info * add GetLatestBlock,GetBlockByHeight grpc endpoints * add GetValidatorSetByHeight, GetLatestValidatorSet * fix lint * fix tests * proto format * Update Makefile * review changes * Makefile format * handle nil pagination * rename query.go to service.go * format Makefile * format Makefile * review changes * review changes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- Makefile | 19 +- client/grpc/tmservice/block.go | 19 + client/grpc/tmservice/service.go | 206 + client/grpc/tmservice/service_test.go | 153 + client/grpc/tmservice/status.go | 17 + .../base/tendermint/v1beta1/query.proto | 135 + server/start.go | 4 +- server/types/app.go | 3 + simapp/app.go | 8 + testutil/network/util.go | 3 + third_party/proto/tendermint/p2p/types.proto | 34 + .../proto/tendermint/types/block.proto | 15 + types/query/pagination.go | 27 + types/query/pagination_test.go | 19 + types/query/query.pb.go | 3934 +++++++++++++++++ types/query/query.pb.gw.go | 566 +++ 16 files changed, 5153 insertions(+), 9 deletions(-) create mode 100644 client/grpc/tmservice/block.go create mode 100644 client/grpc/tmservice/service.go create mode 100644 client/grpc/tmservice/service_test.go create mode 100644 client/grpc/tmservice/status.go create mode 100644 proto/cosmos/base/tendermint/v1beta1/query.proto create mode 100644 third_party/proto/tendermint/p2p/types.proto create mode 100644 third_party/proto/tendermint/types/block.proto create mode 100644 types/query/query.pb.go create mode 100644 types/query/query.pb.gw.go diff --git a/Makefile b/Makefile index 4c94c2d492..baace1ee14 100644 --- a/Makefile +++ b/Makefile @@ -382,16 +382,17 @@ proto-lint: proto-check-breaking: @$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=master -TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc6/proto/tendermint -GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos -COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master -CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.3 +TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc6/proto/tendermint +GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos +COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master +CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.3 TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto TM_ABCI_TYPES = third_party/proto/tendermint/abci -TM_TYPES = third_party/proto/tendermint/types -TM_VERSION = third_party/proto/tendermint/version -TM_LIBS = third_party/proto/tendermint/libs/bits +TM_TYPES = third_party/proto/tendermint/types +TM_VERSION = third_party/proto/tendermint/version +TM_LIBS = third_party/proto/tendermint/libs/bits +TM_P2P = third_party/proto/tendermint/p2p GOGO_PROTO_TYPES = third_party/proto/gogoproto COSMOS_PROTO_TYPES = third_party/proto/cosmos_proto @@ -419,6 +420,7 @@ proto-update-deps: @curl -sSL $(TM_URL)/types/evidence.proto > $(TM_TYPES)/evidence.proto @curl -sSL $(TM_URL)/types/params.proto > $(TM_TYPES)/params.proto @curl -sSL $(TM_URL)/types/validator.proto > $(TM_TYPES)/validator.proto + @curl -sSL $(TM_URL)/types/block.proto > $(TM_TYPES)/block.proto @mkdir -p $(TM_CRYPTO_TYPES) @curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto @@ -427,6 +429,9 @@ proto-update-deps: @mkdir -p $(TM_LIBS) @curl -sSL $(TM_URL)/libs/bits/types.proto > $(TM_LIBS)/types.proto + @mkdir -p $(TM_P2P) + @curl -sSL $(TM_URL)/p2p/types.proto > $(TM_P2P)/types.proto + @mkdir -p $(CONFIO_TYPES) @curl -sSL $(CONFIO_URL)/proofs.proto > $(CONFIO_TYPES)/proofs.proto ## insert go package option into proofs.proto file diff --git a/client/grpc/tmservice/block.go b/client/grpc/tmservice/block.go new file mode 100644 index 0000000000..e92fbec72b --- /dev/null +++ b/client/grpc/tmservice/block.go @@ -0,0 +1,19 @@ +package tmservice + +import ( + "context" + + ctypes "github.com/tendermint/tendermint/rpc/core/types" + + "github.com/cosmos/cosmos-sdk/client" +) + +func getBlock(clientCtx client.Context, height *int64) (*ctypes.ResultBlock, error) { + // get the node + node, err := clientCtx.GetNode() + if err != nil { + return nil, err + } + + return node.Block(context.Background(), height) +} diff --git a/client/grpc/tmservice/service.go b/client/grpc/tmservice/service.go new file mode 100644 index 0000000000..b1198eb673 --- /dev/null +++ b/client/grpc/tmservice/service.go @@ -0,0 +1,206 @@ +package tmservice + +import ( + "context" + + gogogrpc "github.com/gogo/protobuf/grpc" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/rpc" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + qtypes "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/version" +) + +// This is the struct that we will implement all the handlers on. +type queryServer struct { + clientCtx client.Context + interfaceRegistry codectypes.InterfaceRegistry +} + +var _ qtypes.ServiceServer = queryServer{} + +// NewQueryServer creates a new tendermint query server. +func NewQueryServer(clientCtx client.Context, interfaceRegistry codectypes.InterfaceRegistry) qtypes.ServiceServer { + return queryServer{ + clientCtx: clientCtx, + interfaceRegistry: interfaceRegistry, + } +} + +// GetSyncing implements ServiceServer.GetSyncing +func (s queryServer) GetSyncing(_ context.Context, _ *qtypes.GetSyncingRequest) (*qtypes.GetSyncingResponse, error) { + status, err := getNodeStatus(s.clientCtx) + if err != nil { + return nil, err + } + return &qtypes.GetSyncingResponse{ + Syncing: status.SyncInfo.CatchingUp, + }, nil +} + +// GetLatestBlock implements ServiceServer.GetLatestBlock +func (s queryServer) GetLatestBlock(context.Context, *qtypes.GetLatestBlockRequest) (*qtypes.GetLatestBlockResponse, error) { + status, err := getBlock(s.clientCtx, nil) + if err != nil { + return nil, err + } + + protoBlockID := status.BlockID.ToProto() + protoBlock, err := status.Block.ToProto() + if err != nil { + return nil, err + } + + return &qtypes.GetLatestBlockResponse{ + BlockId: &protoBlockID, + Block: protoBlock, + }, nil +} + +// GetBlockByHeight implements ServiceServer.GetBlockByHeight +func (s queryServer) GetBlockByHeight(_ context.Context, req *qtypes.GetBlockByHeightRequest) (*qtypes.GetBlockByHeightResponse, error) { + chainHeight, err := rpc.GetChainHeight(s.clientCtx) + if err != nil { + return nil, err + } + + if req.Height > chainHeight { + return nil, status.Error(codes.InvalidArgument, "requested block height is bigger then the chain length") + } + + res, err := getBlock(s.clientCtx, &req.Height) + if err != nil { + return nil, err + } + protoBlockID := res.BlockID.ToProto() + protoBlock, err := res.Block.ToProto() + if err != nil { + return nil, err + } + return &qtypes.GetBlockByHeightResponse{ + BlockId: &protoBlockID, + Block: protoBlock, + }, nil +} + +// GetLatestValidatorSet implements ServiceServer.GetLatestValidatorSet +func (s queryServer) GetLatestValidatorSet(ctx context.Context, req *qtypes.GetLatestValidatorSetRequest) (*qtypes.GetLatestValidatorSetResponse, error) { + page, limit, err := qtypes.ParsePagination(req.Pagination) + if err != nil { + return nil, err + } + + validatorsRes, err := rpc.GetValidators(s.clientCtx, nil, &page, &limit) + if err != nil { + return nil, err + } + + outputValidatorsRes := &qtypes.GetLatestValidatorSetResponse{ + BlockHeight: validatorsRes.BlockHeight, + Validators: make([]*qtypes.Validator, len(validatorsRes.Validators)), + } + + for i, validator := range validatorsRes.Validators { + outputValidatorsRes.Validators[i] = &qtypes.Validator{ + Address: validator.Address, + ProposerPriority: validator.ProposerPriority, + PubKey: validator.PubKey, + VotingPower: validator.VotingPower, + } + } + return outputValidatorsRes, nil +} + +// GetValidatorSetByHeight implements ServiceServer.GetValidatorSetByHeight +func (s queryServer) GetValidatorSetByHeight(ctx context.Context, req *qtypes.GetValidatorSetByHeightRequest) (*qtypes.GetValidatorSetByHeightResponse, error) { + page, limit, err := qtypes.ParsePagination(req.Pagination) + if err != nil { + return nil, err + } + + chainHeight, err := rpc.GetChainHeight(s.clientCtx) + if err != nil { + return nil, status.Error(codes.Internal, "failed to parse chain height") + } + if req.Height > chainHeight { + return nil, status.Error(codes.InvalidArgument, "requested block height is bigger then the chain length") + } + + validatorsRes, err := rpc.GetValidators(s.clientCtx, &req.Height, &page, &limit) + + if err != nil { + return nil, err + } + + outputValidatorsRes := &qtypes.GetValidatorSetByHeightResponse{ + BlockHeight: validatorsRes.BlockHeight, + Validators: make([]*qtypes.Validator, len(validatorsRes.Validators)), + } + + for i, validator := range validatorsRes.Validators { + outputValidatorsRes.Validators[i] = &qtypes.Validator{ + Address: validator.Address, + ProposerPriority: validator.ProposerPriority, + PubKey: validator.PubKey, + VotingPower: validator.VotingPower, + } + } + return outputValidatorsRes, nil +} + +// GetNodeInfo implements ServiceServer.GetNodeInfo +func (s queryServer) GetNodeInfo(ctx context.Context, req *qtypes.GetNodeInfoRequest) (*qtypes.GetNodeInfoResponse, error) { + status, err := getNodeStatus(s.clientCtx) + if err != nil { + return nil, err + } + + protoNodeInfo := status.NodeInfo.ToProto() + nodeInfo := version.NewInfo() + + deps := make([]*qtypes.Module, len(nodeInfo.BuildDeps)) + + for i, dep := range nodeInfo.BuildDeps { + deps[i] = &qtypes.Module{ + Path: dep.Path, + Sum: dep.Sum, + Version: dep.Version, + } + } + + resp := qtypes.GetNodeInfoResponse{ + DefaultNodeInfo: protoNodeInfo, + ApplicationVersion: &qtypes.VersionInfo{ + AppName: nodeInfo.AppName, + Name: nodeInfo.Name, + GitCommit: nodeInfo.GitCommit, + GoVersion: nodeInfo.GoVersion, + Version: nodeInfo.Version, + BuildTags: nodeInfo.BuildTags, + BuildDeps: deps, + }, + } + return &resp, nil +} + +// RegisterTendermintService registers the tendermint queries on the gRPC router. +func RegisterTendermintService( + qrt gogogrpc.Server, + clientCtx client.Context, + interfaceRegistry codectypes.InterfaceRegistry, +) { + qtypes.RegisterServiceServer( + qrt, + NewQueryServer(clientCtx, interfaceRegistry), + ) +} + +// RegisterGRPCGatewayRoutes mounts the tendermint service's GRPC-gateway routes on the +// given Mux. +func RegisterGRPCGatewayRoutes(clientConn gogogrpc.ClientConn, mux *runtime.ServeMux) { + qtypes.RegisterServiceHandlerClient(context.Background(), mux, qtypes.NewServiceClient(clientConn)) +} diff --git a/client/grpc/tmservice/service_test.go b/client/grpc/tmservice/service_test.go new file mode 100644 index 0000000000..bb145e6e21 --- /dev/null +++ b/client/grpc/tmservice/service_test.go @@ -0,0 +1,153 @@ +package tmservice_test + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/testutil/network" + qtypes "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/types/rest" + "github.com/cosmos/cosmos-sdk/version" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network + + queryClient qtypes.ServiceClient +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + + s.cfg = cfg + s.network = network.New(s.T(), cfg) + + s.Require().NotNil(s.network) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) + + s.queryClient = qtypes.NewServiceClient(s.network.Validators[0].ClientCtx) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s IntegrationTestSuite) TestQueryNodeInfo() { + val := s.network.Validators[0] + + res, err := s.queryClient.GetNodeInfo(context.Background(), &qtypes.GetNodeInfoRequest{}) + s.Require().NoError(err) + s.Require().Equal(res.ApplicationVersion.AppName, version.NewInfo().AppName) + + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.APIAddress)) + s.Require().NoError(err) + var getInfoRes qtypes.GetNodeInfoResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &getInfoRes)) + s.Require().Equal(getInfoRes.ApplicationVersion.AppName, version.NewInfo().AppName) +} + +func (s IntegrationTestSuite) TestQuerySyncing() { + val := s.network.Validators[0] + + _, err := s.queryClient.GetSyncing(context.Background(), &qtypes.GetSyncingRequest{}) + s.Require().NoError(err) + + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.APIAddress)) + s.Require().NoError(err) + var syncingRes qtypes.GetSyncingResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &syncingRes)) +} + +func (s IntegrationTestSuite) TestQueryLatestBlock() { + val := s.network.Validators[0] + + _, err := s.queryClient.GetLatestBlock(context.Background(), &qtypes.GetLatestBlockRequest{}) + s.Require().NoError(err) + + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.APIAddress)) + s.Require().NoError(err) + var blockInfoRes qtypes.GetLatestBlockResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes)) +} + +func (s IntegrationTestSuite) TestQueryBlockByHeight() { + val := s.network.Validators[0] + _, err := s.queryClient.GetBlockByHeight(context.Background(), &qtypes.GetBlockByHeightRequest{Height: 1}) + s.Require().NoError(err) + + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.APIAddress, 1)) + s.Require().NoError(err) + var blockInfoRes qtypes.GetBlockByHeightResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &blockInfoRes)) +} + +func (s IntegrationTestSuite) TestQueryLatestValidatorSet() { + val := s.network.Validators[0] + + // nil pagination + _, err := s.queryClient.GetLatestValidatorSet(context.Background(), &qtypes.GetLatestValidatorSetRequest{ + Pagination: nil, + }) + s.Require().NoError(err) + + //with pagination + _, err = s.queryClient.GetLatestValidatorSet(context.Background(), &qtypes.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{ + Offset: 0, + Limit: 10, + }}) + s.Require().NoError(err) + + // rest request without pagination + _, err = rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/latest", val.APIAddress)) + s.Require().NoError(err) + + // rest request with pagination + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/latest?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 0, 1)) + s.Require().NoError(err) + var validatorSetRes qtypes.GetLatestValidatorSetResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &validatorSetRes)) +} + +func (s IntegrationTestSuite) TestQueryValidatorSetByHeight() { + val := s.network.Validators[0] + + // nil pagination + _, err := s.queryClient.GetValidatorSetByHeight(context.Background(), &qtypes.GetValidatorSetByHeightRequest{ + Height: 1, + Pagination: nil, + }) + s.Require().NoError(err) + + _, err = s.queryClient.GetValidatorSetByHeight(context.Background(), &qtypes.GetValidatorSetByHeightRequest{ + Height: 1, + Pagination: &qtypes.PageRequest{ + Offset: 0, + Limit: 10, + }}) + s.Require().NoError(err) + + // no pagination rest + _, err = rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/%d", val.APIAddress, 1)) + s.Require().NoError(err) + + // rest query with pagination + restRes, err := rest.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validators/%d?pagination.offset=%d&pagination.limit=%d", val.APIAddress, 1, 0, 1)) + var validatorSetRes qtypes.GetValidatorSetByHeightResponse + s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(restRes, &validatorSetRes)) +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/client/grpc/tmservice/status.go b/client/grpc/tmservice/status.go new file mode 100644 index 0000000000..f1a8da8e83 --- /dev/null +++ b/client/grpc/tmservice/status.go @@ -0,0 +1,17 @@ +package tmservice + +import ( + "context" + + ctypes "github.com/tendermint/tendermint/rpc/core/types" + + "github.com/cosmos/cosmos-sdk/client" +) + +func getNodeStatus(clientCtx client.Context) (*ctypes.ResultStatus, error) { + node, err := clientCtx.GetNode() + if err != nil { + return &ctypes.ResultStatus{}, err + } + return node.Status(context.Background()) +} diff --git a/proto/cosmos/base/tendermint/v1beta1/query.proto b/proto/cosmos/base/tendermint/v1beta1/query.proto new file mode 100644 index 0000000000..b5220231ac --- /dev/null +++ b/proto/cosmos/base/tendermint/v1beta1/query.proto @@ -0,0 +1,135 @@ +syntax = "proto3"; +package cosmos.base.tendermint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "tendermint/p2p/types.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/query"; + +// Service defines the gRPC querier service for tendermint queries. +service Service { + // GetNodeInfo queries the current node info. + rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info"; + } + // GetSyncing queries node syncing. + rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing"; + } + // GetLatestBlock returns the latest block. + rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest"; + } + // GetBlockByHeight queries block for given height. + rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}"; + } + + // GetLatestValidatorSet queries latest validator-set. + rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validators/latest"; + } + // GetValidatorSetByHeight queries validator-set at a given height. + rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validators/{height}"; + } +} + +// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightRequest { + int64 height = 1; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetRequest { + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// Validator is the type for the validator-set. +message Validator { + bytes address = 1; + string pub_key = 2; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightRequest { + int64 height = 1; +} + +// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightResponse { + tendermint.types.BlockID block_id = 1; + tendermint.types.Block block = 2; +} + +// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. +message GetLatestBlockRequest {} + +// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. +message GetLatestBlockResponse { + tendermint.types.BlockID block_id = 1; + tendermint.types.Block block = 2; +} + +// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. +message GetSyncingRequest {} + +// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. +message GetSyncingResponse { + bool syncing = 1; +} + +// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoRequest {} + +// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoResponse { + tendermint.p2p.DefaultNodeInfo default_node_info = 1; + VersionInfo application_version = 2; +} + +// VersionInfo is the type for the GetNodeInfoResponse message. +message VersionInfo { + string name = 1; + string app_name = 2; + string version = 3; + string git_commit = 4; + string build_tags = 5; + string go_version = 6; + repeated Module build_deps = 7; +} + +// Module is the type for VersionInfo +message Module { + // module path + string path = 1; + // module version + string version = 2; + // checksum + string sum = 3; +} \ No newline at end of file diff --git a/server/start.go b/server/start.go index b8565a87a3..e4ecd47de6 100644 --- a/server/start.go +++ b/server/start.go @@ -258,10 +258,10 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App // service if API or gRPC is enabled, and avoid doing so in the general // case, because it spawns a new local tendermint RPC client. if config.API.Enable || config.GRPC.Enable { - clientCtx = clientCtx. - WithClient(local.New(tmNode)) + clientCtx = clientCtx.WithClient(local.New(tmNode)) app.RegisterTxService(clientCtx) + app.RegisterTendermintService(clientCtx) } var apiSrv *api.Server diff --git a/server/types/app.go b/server/types/app.go index f6209d94ba..bac7087294 100644 --- a/server/types/app.go +++ b/server/types/app.go @@ -43,6 +43,9 @@ type ( // RegisterTxService registers the gRPC Query service for tx (such as tx // simulation, fetching txs by hash...). RegisterTxService(clientCtx client.Context) + + // RegisterTendermintService registers the gRPC Query service for tendermint queries. + RegisterTendermintService(clientCtx client.Context) } // AppCreator is a function that allows us to lazily initialize an diff --git a/simapp/app.go b/simapp/app.go index 8aaa007327..f8f5b40b48 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -18,6 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" @@ -560,6 +561,8 @@ func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APICon authrest.RegisterTxRoutes(clientCtx, apiSvr.Router) // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter) + // Register new tendermint queries routes from grpc-gateway. + tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCRouter) // Register legacy and grpc-gateway routes for all modules. ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router) @@ -576,6 +579,11 @@ func (app *SimApp) RegisterTxService(clientCtx client.Context) { authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) } +// RegisterTendermintService implements the Application.RegisterTendermintService method. +func (app *SimApp) RegisterTendermintService(clientCtx client.Context) { + tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry) +} + // RegisterSwaggerAPI registers swagger route with API Server func RegisterSwaggerAPI(ctx client.Context, rtr *mux.Router) { statikFS, err := fs.New() diff --git a/testutil/network/util.go b/testutil/network/util.go index d85dafd0a1..8906c929e0 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -66,6 +66,9 @@ func startInProcess(cfg Config, val *Validator) error { // Add the tx service in the gRPC router. app.RegisterTxService(val.ClientCtx) + + // Add the tendermint queries service in the gRPC router. + app.RegisterTendermintService(val.ClientCtx) } if val.APIAddress != "" { diff --git a/third_party/proto/tendermint/p2p/types.proto b/third_party/proto/tendermint/p2p/types.proto new file mode 100644 index 0000000000..0d42ea4002 --- /dev/null +++ b/third_party/proto/tendermint/p2p/types.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package tendermint.p2p; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; + +import "gogoproto/gogo.proto"; + +message NetAddress { + string id = 1 [(gogoproto.customname) = "ID"]; + string ip = 2 [(gogoproto.customname) = "IP"]; + uint32 port = 3; +} + +message ProtocolVersion { + uint64 p2p = 1 [(gogoproto.customname) = "P2P"]; + uint64 block = 2; + uint64 app = 3; +} + +message DefaultNodeInfo { + ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false]; + string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"]; + string listen_addr = 3; + string network = 4; + string version = 5; + bytes channels = 6; + string moniker = 7; + DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false]; +} + +message DefaultNodeInfoOther { + string tx_index = 1; + string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"]; +} diff --git a/third_party/proto/tendermint/types/block.proto b/third_party/proto/tendermint/types/block.proto new file mode 100644 index 0000000000..84e9bb15d8 --- /dev/null +++ b/third_party/proto/tendermint/types/block.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "tendermint/types/types.proto"; +import "tendermint/types/evidence.proto"; + +message Block { + Header header = 1 [(gogoproto.nullable) = false]; + Data data = 2 [(gogoproto.nullable) = false]; + tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false]; + Commit last_commit = 4; +} diff --git a/types/query/pagination.go b/types/query/pagination.go index 3963add364..9a0999fe61 100644 --- a/types/query/pagination.go +++ b/types/query/pagination.go @@ -3,6 +3,9 @@ package query import ( "fmt" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "github.com/cosmos/cosmos-sdk/store/types" ) @@ -10,6 +13,30 @@ import ( // if the `limit` is not supplied, paginate will use `DefaultLimit` const DefaultLimit = 100 +// ParsePagination validate PageRequest and returns page number & limit. +func ParsePagination(pageReq *PageRequest) (page, limit int, err error) { + offset := 0 + limit = DefaultLimit + + if pageReq != nil { + offset = int(pageReq.Offset) + limit = int(pageReq.Limit) + } + if offset < 0 { + return 1, 0, status.Error(codes.InvalidArgument, "offset must greater than 0") + } + + if limit < 0 { + return 1, 0, status.Error(codes.InvalidArgument, "limit must greater than 0") + } else if limit == 0 { + limit = DefaultLimit + } + + page = offset/limit + 1 + + return page, limit, nil +} + // Paginate does pagination of all the results in the PrefixStore based on the // provided PageRequest. onResult should be used to do actual unmarshaling. func Paginate( diff --git a/types/query/pagination_test.go b/types/query/pagination_test.go index 0961bcbd61..e24d7c489d 100644 --- a/types/query/pagination_test.go +++ b/types/query/pagination_test.go @@ -43,6 +43,25 @@ func TestPaginationTestSuite(t *testing.T) { suite.Run(t, new(paginationTestSuite)) } +func (s *paginationTestSuite) TestParsePagination() { + s.T().Log("verify default values for empty page request") + pageReq := &query.PageRequest{} + page, limit, err := query.ParsePagination(pageReq) + s.Require().NoError(err) + s.Require().Equal(limit, query.DefaultLimit) + s.Require().Equal(page, 1) + + s.T().Log("verify with custom values") + pageReq = &query.PageRequest{ + Offset: 0, + Limit: 10, + } + page, limit, err = query.ParsePagination(pageReq) + s.Require().NoError(err) + s.Require().Equal(page, 1) + s.Require().Equal(limit, 10) +} + func (s *paginationTestSuite) TestPagination() { app, ctx, _ := setupTest() queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) diff --git a/types/query/query.pb.go b/types/query/query.pb.go new file mode 100644 index 0000000000..c04a6bde32 --- /dev/null +++ b/types/query/query.pb.go @@ -0,0 +1,3934 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/base/tendermint/v1beta1/query.proto + +package query + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + p2p "github.com/tendermint/tendermint/proto/tendermint/p2p" + types "github.com/tendermint/tendermint/proto/tendermint/types" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +type GetValidatorSetByHeightRequest struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + // pagination defines an pagination for the request. + Pagination *PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *GetValidatorSetByHeightRequest) Reset() { *m = GetValidatorSetByHeightRequest{} } +func (m *GetValidatorSetByHeightRequest) String() string { return proto.CompactTextString(m) } +func (*GetValidatorSetByHeightRequest) ProtoMessage() {} +func (*GetValidatorSetByHeightRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{0} +} +func (m *GetValidatorSetByHeightRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetValidatorSetByHeightRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetValidatorSetByHeightRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetValidatorSetByHeightRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetValidatorSetByHeightRequest.Merge(m, src) +} +func (m *GetValidatorSetByHeightRequest) XXX_Size() int { + return m.Size() +} +func (m *GetValidatorSetByHeightRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetValidatorSetByHeightRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetValidatorSetByHeightRequest proto.InternalMessageInfo + +func (m *GetValidatorSetByHeightRequest) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *GetValidatorSetByHeightRequest) GetPagination() *PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +type GetValidatorSetByHeightResponse struct { + BlockHeight int64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + Validators []*Validator `protobuf:"bytes,2,rep,name=validators,proto3" json:"validators,omitempty"` + // pagination defines an pagination for the response. + Pagination *PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *GetValidatorSetByHeightResponse) Reset() { *m = GetValidatorSetByHeightResponse{} } +func (m *GetValidatorSetByHeightResponse) String() string { return proto.CompactTextString(m) } +func (*GetValidatorSetByHeightResponse) ProtoMessage() {} +func (*GetValidatorSetByHeightResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{1} +} +func (m *GetValidatorSetByHeightResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetValidatorSetByHeightResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetValidatorSetByHeightResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetValidatorSetByHeightResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetValidatorSetByHeightResponse.Merge(m, src) +} +func (m *GetValidatorSetByHeightResponse) XXX_Size() int { + return m.Size() +} +func (m *GetValidatorSetByHeightResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetValidatorSetByHeightResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetValidatorSetByHeightResponse proto.InternalMessageInfo + +func (m *GetValidatorSetByHeightResponse) GetBlockHeight() int64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *GetValidatorSetByHeightResponse) GetValidators() []*Validator { + if m != nil { + return m.Validators + } + return nil +} + +func (m *GetValidatorSetByHeightResponse) GetPagination() *PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +type GetLatestValidatorSetRequest struct { + // pagination defines an pagination for the request. + Pagination *PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *GetLatestValidatorSetRequest) Reset() { *m = GetLatestValidatorSetRequest{} } +func (m *GetLatestValidatorSetRequest) String() string { return proto.CompactTextString(m) } +func (*GetLatestValidatorSetRequest) ProtoMessage() {} +func (*GetLatestValidatorSetRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{2} +} +func (m *GetLatestValidatorSetRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetLatestValidatorSetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetLatestValidatorSetRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetLatestValidatorSetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetLatestValidatorSetRequest.Merge(m, src) +} +func (m *GetLatestValidatorSetRequest) XXX_Size() int { + return m.Size() +} +func (m *GetLatestValidatorSetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetLatestValidatorSetRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetLatestValidatorSetRequest proto.InternalMessageInfo + +func (m *GetLatestValidatorSetRequest) GetPagination() *PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +type GetLatestValidatorSetResponse struct { + BlockHeight int64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + Validators []*Validator `protobuf:"bytes,2,rep,name=validators,proto3" json:"validators,omitempty"` + // pagination defines an pagination for the response. + Pagination *PageResponse `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *GetLatestValidatorSetResponse) Reset() { *m = GetLatestValidatorSetResponse{} } +func (m *GetLatestValidatorSetResponse) String() string { return proto.CompactTextString(m) } +func (*GetLatestValidatorSetResponse) ProtoMessage() {} +func (*GetLatestValidatorSetResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{3} +} +func (m *GetLatestValidatorSetResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetLatestValidatorSetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetLatestValidatorSetResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetLatestValidatorSetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetLatestValidatorSetResponse.Merge(m, src) +} +func (m *GetLatestValidatorSetResponse) XXX_Size() int { + return m.Size() +} +func (m *GetLatestValidatorSetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetLatestValidatorSetResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetLatestValidatorSetResponse proto.InternalMessageInfo + +func (m *GetLatestValidatorSetResponse) GetBlockHeight() int64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *GetLatestValidatorSetResponse) GetValidators() []*Validator { + if m != nil { + return m.Validators + } + return nil +} + +func (m *GetLatestValidatorSetResponse) GetPagination() *PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +// Validator is the type for the validator-set. +type Validator struct { + Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + PubKey string `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` + VotingPower int64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + ProposerPriority int64 `protobuf:"varint,4,opt,name=proposer_priority,json=proposerPriority,proto3" json:"proposer_priority,omitempty"` +} + +func (m *Validator) Reset() { *m = Validator{} } +func (m *Validator) String() string { return proto.CompactTextString(m) } +func (*Validator) ProtoMessage() {} +func (*Validator) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{4} +} +func (m *Validator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Validator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Validator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Validator) XXX_Merge(src proto.Message) { + xxx_messageInfo_Validator.Merge(m, src) +} +func (m *Validator) XXX_Size() int { + return m.Size() +} +func (m *Validator) XXX_DiscardUnknown() { + xxx_messageInfo_Validator.DiscardUnknown(m) +} + +var xxx_messageInfo_Validator proto.InternalMessageInfo + +func (m *Validator) GetAddress() []byte { + if m != nil { + return m.Address + } + return nil +} + +func (m *Validator) GetPubKey() string { + if m != nil { + return m.PubKey + } + return "" +} + +func (m *Validator) GetVotingPower() int64 { + if m != nil { + return m.VotingPower + } + return 0 +} + +func (m *Validator) GetProposerPriority() int64 { + if m != nil { + return m.ProposerPriority + } + return 0 +} + +// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. +type GetBlockByHeightRequest struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *GetBlockByHeightRequest) Reset() { *m = GetBlockByHeightRequest{} } +func (m *GetBlockByHeightRequest) String() string { return proto.CompactTextString(m) } +func (*GetBlockByHeightRequest) ProtoMessage() {} +func (*GetBlockByHeightRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{5} +} +func (m *GetBlockByHeightRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetBlockByHeightRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetBlockByHeightRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetBlockByHeightRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBlockByHeightRequest.Merge(m, src) +} +func (m *GetBlockByHeightRequest) XXX_Size() int { + return m.Size() +} +func (m *GetBlockByHeightRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetBlockByHeightRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBlockByHeightRequest proto.InternalMessageInfo + +func (m *GetBlockByHeightRequest) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. +type GetBlockByHeightResponse struct { + BlockId *types.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"` + Block *types.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` +} + +func (m *GetBlockByHeightResponse) Reset() { *m = GetBlockByHeightResponse{} } +func (m *GetBlockByHeightResponse) String() string { return proto.CompactTextString(m) } +func (*GetBlockByHeightResponse) ProtoMessage() {} +func (*GetBlockByHeightResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{6} +} +func (m *GetBlockByHeightResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetBlockByHeightResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetBlockByHeightResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetBlockByHeightResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBlockByHeightResponse.Merge(m, src) +} +func (m *GetBlockByHeightResponse) XXX_Size() int { + return m.Size() +} +func (m *GetBlockByHeightResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetBlockByHeightResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBlockByHeightResponse proto.InternalMessageInfo + +func (m *GetBlockByHeightResponse) GetBlockId() *types.BlockID { + if m != nil { + return m.BlockId + } + return nil +} + +func (m *GetBlockByHeightResponse) GetBlock() *types.Block { + if m != nil { + return m.Block + } + return nil +} + +// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. +type GetLatestBlockRequest struct { +} + +func (m *GetLatestBlockRequest) Reset() { *m = GetLatestBlockRequest{} } +func (m *GetLatestBlockRequest) String() string { return proto.CompactTextString(m) } +func (*GetLatestBlockRequest) ProtoMessage() {} +func (*GetLatestBlockRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{7} +} +func (m *GetLatestBlockRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetLatestBlockRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetLatestBlockRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetLatestBlockRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetLatestBlockRequest.Merge(m, src) +} +func (m *GetLatestBlockRequest) XXX_Size() int { + return m.Size() +} +func (m *GetLatestBlockRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetLatestBlockRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetLatestBlockRequest proto.InternalMessageInfo + +// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. +type GetLatestBlockResponse struct { + BlockId *types.BlockID `protobuf:"bytes,1,opt,name=block_id,json=blockId,proto3" json:"block_id,omitempty"` + Block *types.Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"` +} + +func (m *GetLatestBlockResponse) Reset() { *m = GetLatestBlockResponse{} } +func (m *GetLatestBlockResponse) String() string { return proto.CompactTextString(m) } +func (*GetLatestBlockResponse) ProtoMessage() {} +func (*GetLatestBlockResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{8} +} +func (m *GetLatestBlockResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetLatestBlockResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetLatestBlockResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetLatestBlockResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetLatestBlockResponse.Merge(m, src) +} +func (m *GetLatestBlockResponse) XXX_Size() int { + return m.Size() +} +func (m *GetLatestBlockResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetLatestBlockResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetLatestBlockResponse proto.InternalMessageInfo + +func (m *GetLatestBlockResponse) GetBlockId() *types.BlockID { + if m != nil { + return m.BlockId + } + return nil +} + +func (m *GetLatestBlockResponse) GetBlock() *types.Block { + if m != nil { + return m.Block + } + return nil +} + +// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. +type GetSyncingRequest struct { +} + +func (m *GetSyncingRequest) Reset() { *m = GetSyncingRequest{} } +func (m *GetSyncingRequest) String() string { return proto.CompactTextString(m) } +func (*GetSyncingRequest) ProtoMessage() {} +func (*GetSyncingRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{9} +} +func (m *GetSyncingRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetSyncingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetSyncingRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetSyncingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSyncingRequest.Merge(m, src) +} +func (m *GetSyncingRequest) XXX_Size() int { + return m.Size() +} +func (m *GetSyncingRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetSyncingRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSyncingRequest proto.InternalMessageInfo + +// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. +type GetSyncingResponse struct { + Syncing bool `protobuf:"varint,1,opt,name=syncing,proto3" json:"syncing,omitempty"` +} + +func (m *GetSyncingResponse) Reset() { *m = GetSyncingResponse{} } +func (m *GetSyncingResponse) String() string { return proto.CompactTextString(m) } +func (*GetSyncingResponse) ProtoMessage() {} +func (*GetSyncingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{10} +} +func (m *GetSyncingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetSyncingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetSyncingResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetSyncingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSyncingResponse.Merge(m, src) +} +func (m *GetSyncingResponse) XXX_Size() int { + return m.Size() +} +func (m *GetSyncingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetSyncingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSyncingResponse proto.InternalMessageInfo + +func (m *GetSyncingResponse) GetSyncing() bool { + if m != nil { + return m.Syncing + } + return false +} + +// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. +type GetNodeInfoRequest struct { +} + +func (m *GetNodeInfoRequest) Reset() { *m = GetNodeInfoRequest{} } +func (m *GetNodeInfoRequest) String() string { return proto.CompactTextString(m) } +func (*GetNodeInfoRequest) ProtoMessage() {} +func (*GetNodeInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{11} +} +func (m *GetNodeInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetNodeInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetNodeInfoRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetNodeInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetNodeInfoRequest.Merge(m, src) +} +func (m *GetNodeInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *GetNodeInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetNodeInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetNodeInfoRequest proto.InternalMessageInfo + +// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. +type GetNodeInfoResponse struct { + DefaultNodeInfo *p2p.DefaultNodeInfo `protobuf:"bytes,1,opt,name=default_node_info,json=defaultNodeInfo,proto3" json:"default_node_info,omitempty"` + ApplicationVersion *VersionInfo `protobuf:"bytes,2,opt,name=application_version,json=applicationVersion,proto3" json:"application_version,omitempty"` +} + +func (m *GetNodeInfoResponse) Reset() { *m = GetNodeInfoResponse{} } +func (m *GetNodeInfoResponse) String() string { return proto.CompactTextString(m) } +func (*GetNodeInfoResponse) ProtoMessage() {} +func (*GetNodeInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{12} +} +func (m *GetNodeInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetNodeInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GetNodeInfoResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GetNodeInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetNodeInfoResponse.Merge(m, src) +} +func (m *GetNodeInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *GetNodeInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetNodeInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetNodeInfoResponse proto.InternalMessageInfo + +func (m *GetNodeInfoResponse) GetDefaultNodeInfo() *p2p.DefaultNodeInfo { + if m != nil { + return m.DefaultNodeInfo + } + return nil +} + +func (m *GetNodeInfoResponse) GetApplicationVersion() *VersionInfo { + if m != nil { + return m.ApplicationVersion + } + return nil +} + +// VersionInfo is the type for the GetNodeInfoResponse message. +type VersionInfo struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AppName string `protobuf:"bytes,2,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + GitCommit string `protobuf:"bytes,4,opt,name=git_commit,json=gitCommit,proto3" json:"git_commit,omitempty"` + BuildTags string `protobuf:"bytes,5,opt,name=build_tags,json=buildTags,proto3" json:"build_tags,omitempty"` + GoVersion string `protobuf:"bytes,6,opt,name=go_version,json=goVersion,proto3" json:"go_version,omitempty"` + BuildDeps []*Module `protobuf:"bytes,7,rep,name=build_deps,json=buildDeps,proto3" json:"build_deps,omitempty"` +} + +func (m *VersionInfo) Reset() { *m = VersionInfo{} } +func (m *VersionInfo) String() string { return proto.CompactTextString(m) } +func (*VersionInfo) ProtoMessage() {} +func (*VersionInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{13} +} +func (m *VersionInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VersionInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VersionInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *VersionInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_VersionInfo.Merge(m, src) +} +func (m *VersionInfo) XXX_Size() int { + return m.Size() +} +func (m *VersionInfo) XXX_DiscardUnknown() { + xxx_messageInfo_VersionInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_VersionInfo proto.InternalMessageInfo + +func (m *VersionInfo) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *VersionInfo) GetAppName() string { + if m != nil { + return m.AppName + } + return "" +} + +func (m *VersionInfo) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *VersionInfo) GetGitCommit() string { + if m != nil { + return m.GitCommit + } + return "" +} + +func (m *VersionInfo) GetBuildTags() string { + if m != nil { + return m.BuildTags + } + return "" +} + +func (m *VersionInfo) GetGoVersion() string { + if m != nil { + return m.GoVersion + } + return "" +} + +func (m *VersionInfo) GetBuildDeps() []*Module { + if m != nil { + return m.BuildDeps + } + return nil +} + +// Module is the type for VersionInfo +type Module struct { + // module path + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // module version + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + //checksum + Sum string `protobuf:"bytes,3,opt,name=sum,proto3" json:"sum,omitempty"` +} + +func (m *Module) Reset() { *m = Module{} } +func (m *Module) String() string { return proto.CompactTextString(m) } +func (*Module) ProtoMessage() {} +func (*Module) Descriptor() ([]byte, []int) { + return fileDescriptor_40c93fb3ef485c5d, []int{14} +} +func (m *Module) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Module) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Module.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Module) XXX_Merge(src proto.Message) { + xxx_messageInfo_Module.Merge(m, src) +} +func (m *Module) XXX_Size() int { + return m.Size() +} +func (m *Module) XXX_DiscardUnknown() { + xxx_messageInfo_Module.DiscardUnknown(m) +} + +var xxx_messageInfo_Module proto.InternalMessageInfo + +func (m *Module) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *Module) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *Module) GetSum() string { + if m != nil { + return m.Sum + } + return "" +} + +func init() { + proto.RegisterType((*GetValidatorSetByHeightRequest)(nil), "cosmos.base.tendermint.v1beta1.GetValidatorSetByHeightRequest") + proto.RegisterType((*GetValidatorSetByHeightResponse)(nil), "cosmos.base.tendermint.v1beta1.GetValidatorSetByHeightResponse") + proto.RegisterType((*GetLatestValidatorSetRequest)(nil), "cosmos.base.tendermint.v1beta1.GetLatestValidatorSetRequest") + proto.RegisterType((*GetLatestValidatorSetResponse)(nil), "cosmos.base.tendermint.v1beta1.GetLatestValidatorSetResponse") + proto.RegisterType((*Validator)(nil), "cosmos.base.tendermint.v1beta1.Validator") + proto.RegisterType((*GetBlockByHeightRequest)(nil), "cosmos.base.tendermint.v1beta1.GetBlockByHeightRequest") + proto.RegisterType((*GetBlockByHeightResponse)(nil), "cosmos.base.tendermint.v1beta1.GetBlockByHeightResponse") + proto.RegisterType((*GetLatestBlockRequest)(nil), "cosmos.base.tendermint.v1beta1.GetLatestBlockRequest") + proto.RegisterType((*GetLatestBlockResponse)(nil), "cosmos.base.tendermint.v1beta1.GetLatestBlockResponse") + proto.RegisterType((*GetSyncingRequest)(nil), "cosmos.base.tendermint.v1beta1.GetSyncingRequest") + proto.RegisterType((*GetSyncingResponse)(nil), "cosmos.base.tendermint.v1beta1.GetSyncingResponse") + proto.RegisterType((*GetNodeInfoRequest)(nil), "cosmos.base.tendermint.v1beta1.GetNodeInfoRequest") + proto.RegisterType((*GetNodeInfoResponse)(nil), "cosmos.base.tendermint.v1beta1.GetNodeInfoResponse") + proto.RegisterType((*VersionInfo)(nil), "cosmos.base.tendermint.v1beta1.VersionInfo") + proto.RegisterType((*Module)(nil), "cosmos.base.tendermint.v1beta1.Module") +} + +func init() { + proto.RegisterFile("cosmos/base/tendermint/v1beta1/query.proto", fileDescriptor_40c93fb3ef485c5d) +} + +var fileDescriptor_40c93fb3ef485c5d = []byte{ + // 1031 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xcf, 0xc6, 0x6d, 0x1c, 0x3f, 0x57, 0x90, 0x4c, 0x4a, 0xb3, 0xb5, 0x52, 0x37, 0xec, 0xa1, + 0x4d, 0x88, 0xb2, 0x2b, 0x3b, 0x84, 0x82, 0xf8, 0x27, 0x85, 0x40, 0x1a, 0x15, 0xaa, 0x68, 0x83, + 0x38, 0x20, 0xa4, 0xd5, 0xd8, 0x3b, 0xd9, 0x8c, 0x62, 0xef, 0x4c, 0x77, 0xc6, 0x41, 0x16, 0xaa, + 0x40, 0xfd, 0x00, 0x08, 0x89, 0xaf, 0xc0, 0x85, 0x2f, 0xc0, 0x11, 0x71, 0xe4, 0x46, 0x25, 0x24, + 0xe8, 0x11, 0x25, 0x7c, 0x0a, 0x4e, 0x68, 0x67, 0x66, 0xed, 0xdd, 0x26, 0xa9, 0xed, 0x1c, 0x90, + 0x38, 0x79, 0xf6, 0xbd, 0xf7, 0x7b, 0xf3, 0xfb, 0xbd, 0x79, 0x33, 0x7e, 0xf0, 0x5a, 0x9b, 0x89, + 0x2e, 0x13, 0x5e, 0x0b, 0x0b, 0xe2, 0x49, 0x12, 0x87, 0x24, 0xe9, 0xd2, 0x58, 0x7a, 0xc7, 0x8d, + 0x16, 0x91, 0xb8, 0xe1, 0x3d, 0xea, 0x91, 0xa4, 0xef, 0xf2, 0x84, 0x49, 0x86, 0xea, 0x3a, 0xd6, + 0x4d, 0x63, 0xdd, 0x61, 0xac, 0x6b, 0x62, 0x6b, 0xd7, 0x23, 0x16, 0x31, 0x15, 0xea, 0xa5, 0x2b, + 0x8d, 0xaa, 0x2d, 0x45, 0x8c, 0x45, 0x1d, 0xe2, 0x61, 0x4e, 0x3d, 0x1c, 0xc7, 0x4c, 0x62, 0x49, + 0x59, 0x2c, 0x8c, 0xb7, 0x96, 0xdb, 0x93, 0x37, 0xb9, 0x27, 0xfb, 0x9c, 0x64, 0xbe, 0xa5, 0x9c, + 0x4f, 0xd9, 0xbd, 0x56, 0x87, 0xb5, 0x8f, 0x2e, 0xf4, 0xe6, 0xb1, 0x05, 0x5d, 0x4a, 0xc4, 0x40, + 0x12, 0xc7, 0x11, 0x8d, 0x15, 0x09, 0x1d, 0xeb, 0x7c, 0x63, 0x41, 0x7d, 0x87, 0xc8, 0xcf, 0x70, + 0x87, 0x86, 0x58, 0xb2, 0x64, 0x9f, 0xc8, 0xad, 0xfe, 0x7d, 0x42, 0xa3, 0x43, 0xe9, 0x93, 0x47, + 0x3d, 0x22, 0x24, 0xba, 0x01, 0x33, 0x87, 0xca, 0x60, 0x5b, 0xcb, 0xd6, 0x4a, 0xc9, 0x37, 0x5f, + 0xe8, 0x23, 0x80, 0x61, 0x3a, 0x7b, 0x7a, 0xd9, 0x5a, 0xa9, 0x36, 0xef, 0xb8, 0xf9, 0x3a, 0xe9, + 0x02, 0x9a, 0xbd, 0xdd, 0x3d, 0x1c, 0x11, 0x93, 0xd3, 0xcf, 0x21, 0x9d, 0x67, 0x16, 0xdc, 0xbe, + 0x90, 0x82, 0xe0, 0x2c, 0x16, 0x04, 0xbd, 0x0a, 0xd7, 0x94, 0xfe, 0xa0, 0xc0, 0xa4, 0xaa, 0x6c, + 0x3a, 0x14, 0xed, 0x02, 0x1c, 0x67, 0x29, 0x84, 0x3d, 0xbd, 0x5c, 0x5a, 0xa9, 0x36, 0x57, 0xdd, + 0x17, 0x1f, 0x9b, 0x3b, 0xd8, 0xd4, 0xcf, 0x81, 0xd1, 0x4e, 0x41, 0x59, 0x49, 0x29, 0xbb, 0x3b, + 0x52, 0x99, 0xa6, 0x5a, 0x90, 0x76, 0x00, 0x4b, 0x3b, 0x44, 0x7e, 0x8c, 0x25, 0x11, 0x05, 0x7d, + 0x59, 0x69, 0x8b, 0x25, 0xb4, 0x2e, 0x5d, 0xc2, 0x3f, 0x2c, 0xb8, 0x75, 0xc1, 0x46, 0xff, 0xef, + 0x02, 0x7e, 0x6b, 0x41, 0x65, 0xb0, 0x05, 0xb2, 0xa1, 0x8c, 0xc3, 0x30, 0x21, 0x42, 0x28, 0xfe, + 0xd7, 0xfc, 0xec, 0x13, 0x2d, 0x42, 0x99, 0xf7, 0x5a, 0xc1, 0x11, 0xe9, 0xab, 0x46, 0xac, 0xf8, + 0x33, 0xbc, 0xd7, 0x7a, 0x40, 0xfa, 0xa9, 0xee, 0x63, 0x26, 0x69, 0x1c, 0x05, 0x9c, 0x7d, 0x49, + 0x12, 0xc5, 0xa5, 0xe4, 0x57, 0xb5, 0x6d, 0x2f, 0x35, 0xa1, 0x35, 0x98, 0xe7, 0x09, 0xe3, 0x4c, + 0x90, 0x24, 0xe0, 0x09, 0x65, 0x09, 0x95, 0x7d, 0xfb, 0x8a, 0x8a, 0x9b, 0xcb, 0x1c, 0x7b, 0xc6, + 0xee, 0x34, 0x60, 0x71, 0x87, 0xc8, 0xad, 0xb4, 0x6c, 0x63, 0xde, 0x13, 0xe7, 0x6b, 0xb0, 0xcf, + 0x42, 0xcc, 0xb1, 0xbc, 0x0e, 0xb3, 0xfa, 0x58, 0x68, 0x68, 0x8e, 0xff, 0x66, 0xbe, 0xca, 0xfa, + 0x56, 0x2b, 0xe8, 0xee, 0xb6, 0x5f, 0x56, 0xa1, 0xbb, 0x21, 0x5a, 0x87, 0xab, 0x6a, 0x69, 0x2e, + 0xdd, 0xe2, 0x05, 0x10, 0x5f, 0x47, 0x39, 0x8b, 0xf0, 0xca, 0xa0, 0x39, 0xb4, 0x43, 0x33, 0x76, + 0x1e, 0xc3, 0x8d, 0xe7, 0x1d, 0xff, 0x25, 0xaf, 0x05, 0x98, 0xdf, 0x21, 0x72, 0xbf, 0x1f, 0xb7, + 0x69, 0x1c, 0x65, 0x9c, 0x5c, 0x40, 0x79, 0xa3, 0xe1, 0x63, 0x43, 0x59, 0x68, 0x93, 0xa2, 0x33, + 0xeb, 0x67, 0x9f, 0xce, 0x75, 0x15, 0xff, 0x90, 0x85, 0x64, 0x37, 0x3e, 0x60, 0x59, 0x96, 0x5f, + 0x2c, 0x58, 0x28, 0x98, 0x4d, 0x9e, 0x07, 0x30, 0x1f, 0x92, 0x03, 0xdc, 0xeb, 0xc8, 0x20, 0x66, + 0x21, 0x09, 0x68, 0x7c, 0xc0, 0x8c, 0xc0, 0xdb, 0x79, 0xb6, 0xbc, 0xc9, 0xdd, 0x6d, 0x1d, 0x38, + 0xc8, 0xf1, 0x72, 0x58, 0x34, 0xa0, 0x2f, 0x60, 0x01, 0x73, 0xde, 0xa1, 0x6d, 0xd5, 0xab, 0xc1, + 0x31, 0x49, 0xc4, 0xf0, 0x25, 0x5c, 0x1b, 0x79, 0x73, 0x74, 0xb8, 0x4a, 0x8d, 0x72, 0x79, 0x8c, + 0xdd, 0xf9, 0xc7, 0x82, 0x6a, 0x2e, 0x06, 0x21, 0xb8, 0x12, 0xe3, 0x2e, 0x51, 0x6c, 0x2b, 0xbe, + 0x5a, 0xa3, 0x9b, 0x30, 0x8b, 0x39, 0x0f, 0x94, 0x5d, 0xf7, 0x7d, 0x19, 0x73, 0xfe, 0x30, 0x75, + 0xd9, 0x50, 0xce, 0x08, 0x95, 0xb4, 0xc7, 0x7c, 0xa2, 0x5b, 0x00, 0x11, 0x95, 0x41, 0x9b, 0x75, + 0xbb, 0x54, 0xaa, 0x46, 0xaf, 0xf8, 0x95, 0x88, 0xca, 0x0f, 0x94, 0x21, 0x75, 0xb7, 0x7a, 0xb4, + 0x13, 0x06, 0x12, 0x47, 0xc2, 0xbe, 0xaa, 0xdd, 0xca, 0xf2, 0x29, 0x8e, 0x84, 0x42, 0xb3, 0x81, + 0xd6, 0x19, 0x83, 0x66, 0x86, 0x29, 0xfa, 0x30, 0x43, 0x87, 0x84, 0x0b, 0xbb, 0xac, 0x1e, 0x91, + 0x3b, 0xa3, 0x4a, 0xf1, 0x09, 0x0b, 0x7b, 0x1d, 0x62, 0x76, 0xd9, 0x26, 0x5c, 0x38, 0xf7, 0x61, + 0x46, 0x1b, 0x53, 0xd9, 0x1c, 0xcb, 0xc3, 0x4c, 0x76, 0xba, 0xce, 0x6b, 0x9b, 0x2e, 0x6a, 0x9b, + 0x83, 0x92, 0xe8, 0x75, 0x8d, 0xe2, 0x74, 0xd9, 0x7c, 0x52, 0x81, 0xf2, 0x3e, 0x49, 0x8e, 0x69, + 0x9b, 0xa0, 0x1f, 0x2d, 0xa8, 0xe6, 0xba, 0x02, 0x35, 0x47, 0x11, 0x3b, 0xdb, 0x59, 0xb5, 0x8d, + 0x89, 0x30, 0xba, 0xed, 0x9c, 0xc6, 0x93, 0xdf, 0xff, 0xfe, 0x7e, 0x7a, 0x0d, 0xad, 0x7a, 0x23, + 0x46, 0x8e, 0x41, 0x53, 0xa2, 0x1f, 0x2c, 0x80, 0xe1, 0x45, 0x40, 0x8d, 0x31, 0xb6, 0x2d, 0xde, + 0xa4, 0x5a, 0x73, 0x12, 0x88, 0x21, 0xea, 0x29, 0xa2, 0xab, 0xe8, 0xee, 0x28, 0xa2, 0xe6, 0xfa, + 0xa1, 0x9f, 0x2c, 0x78, 0xa9, 0xf8, 0x86, 0xa0, 0xcd, 0x31, 0xf6, 0x3d, 0xfb, 0x18, 0xd5, 0xde, + 0x98, 0x14, 0x66, 0x28, 0x6f, 0x2a, 0xca, 0x1e, 0x5a, 0x1f, 0x45, 0x59, 0x3d, 0x3a, 0xc2, 0xeb, + 0xa8, 0x1c, 0xe8, 0x67, 0x0b, 0xe6, 0x9e, 0x7f, 0x96, 0xd1, 0xbd, 0x31, 0x38, 0x9c, 0xf7, 0xf6, + 0xd7, 0xde, 0x9c, 0x1c, 0x68, 0xe8, 0xdf, 0x53, 0xf4, 0x1b, 0xc8, 0x1b, 0x93, 0xfe, 0x57, 0xfa, + 0x5f, 0xe5, 0x31, 0xfa, 0xcd, 0xca, 0x3d, 0xeb, 0xf9, 0xff, 0x7c, 0xf4, 0xce, 0xd8, 0x95, 0x3c, + 0x67, 0x26, 0xa9, 0xbd, 0x7b, 0x49, 0xb4, 0xd1, 0xf3, 0x96, 0xd2, 0xb3, 0x81, 0x1a, 0xa3, 0xf4, + 0x0c, 0xc7, 0x85, 0xec, 0x48, 0xfe, 0xb4, 0xd4, 0x9f, 0xeb, 0x79, 0x83, 0x20, 0x7a, 0x6f, 0x0c, + 0x56, 0x2f, 0x18, 0x62, 0x6b, 0xef, 0x5f, 0x1a, 0x6f, 0x74, 0xbd, 0xad, 0x74, 0x6d, 0xa2, 0x8d, + 0x09, 0x74, 0x65, 0x67, 0xb5, 0xb5, 0xf5, 0xeb, 0x49, 0xdd, 0x7a, 0x7a, 0x52, 0xb7, 0xfe, 0x3a, + 0xa9, 0x5b, 0xdf, 0x9d, 0xd6, 0xa7, 0x9e, 0x9e, 0xd6, 0xa7, 0x9e, 0x9d, 0xd6, 0xa7, 0x3e, 0x5f, + 0x89, 0xa8, 0x3c, 0xec, 0xb5, 0xdc, 0x36, 0xeb, 0x66, 0x89, 0xf5, 0xcf, 0xba, 0x08, 0x8f, 0xcc, + 0x6c, 0xaf, 0x66, 0xa5, 0xd6, 0x8c, 0x1a, 0xd8, 0x37, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x20, + 0x61, 0xbc, 0x54, 0xb6, 0x0c, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ServiceClient is the client API for Service service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ServiceClient interface { + // GetNodeInfo queries the current node info. + GetNodeInfo(ctx context.Context, in *GetNodeInfoRequest, opts ...grpc.CallOption) (*GetNodeInfoResponse, error) + // GetSyncing queries node syncing. + GetSyncing(ctx context.Context, in *GetSyncingRequest, opts ...grpc.CallOption) (*GetSyncingResponse, error) + // GetLatestBlock returns the latest block. + GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*GetLatestBlockResponse, error) + // GetBlockByHeight queries block for given height. + GetBlockByHeight(ctx context.Context, in *GetBlockByHeightRequest, opts ...grpc.CallOption) (*GetBlockByHeightResponse, error) + // GetLatestValidatorSet queries latest validator-set. + GetLatestValidatorSet(ctx context.Context, in *GetLatestValidatorSetRequest, opts ...grpc.CallOption) (*GetLatestValidatorSetResponse, error) + // GetValidatorSetByHeight queries validator-set at a given height. + GetValidatorSetByHeight(ctx context.Context, in *GetValidatorSetByHeightRequest, opts ...grpc.CallOption) (*GetValidatorSetByHeightResponse, error) +} + +type serviceClient struct { + cc grpc1.ClientConn +} + +func NewServiceClient(cc grpc1.ClientConn) ServiceClient { + return &serviceClient{cc} +} + +func (c *serviceClient) GetNodeInfo(ctx context.Context, in *GetNodeInfoRequest, opts ...grpc.CallOption) (*GetNodeInfoResponse, error) { + out := new(GetNodeInfoResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetNodeInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetSyncing(ctx context.Context, in *GetSyncingRequest, opts ...grpc.CallOption) (*GetSyncingResponse, error) { + out := new(GetSyncingResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetSyncing", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetLatestBlock(ctx context.Context, in *GetLatestBlockRequest, opts ...grpc.CallOption) (*GetLatestBlockResponse, error) { + out := new(GetLatestBlockResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetLatestBlock", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetBlockByHeight(ctx context.Context, in *GetBlockByHeightRequest, opts ...grpc.CallOption) (*GetBlockByHeightResponse, error) { + out := new(GetBlockByHeightResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetBlockByHeight", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetLatestValidatorSet(ctx context.Context, in *GetLatestValidatorSetRequest, opts ...grpc.CallOption) (*GetLatestValidatorSetResponse, error) { + out := new(GetLatestValidatorSetResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetLatestValidatorSet", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *serviceClient) GetValidatorSetByHeight(ctx context.Context, in *GetValidatorSetByHeightRequest, opts ...grpc.CallOption) (*GetValidatorSetByHeightResponse, error) { + out := new(GetValidatorSetByHeightResponse) + err := c.cc.Invoke(ctx, "/cosmos.base.tendermint.v1beta1.Service/GetValidatorSetByHeight", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ServiceServer is the server API for Service service. +type ServiceServer interface { + // GetNodeInfo queries the current node info. + GetNodeInfo(context.Context, *GetNodeInfoRequest) (*GetNodeInfoResponse, error) + // GetSyncing queries node syncing. + GetSyncing(context.Context, *GetSyncingRequest) (*GetSyncingResponse, error) + // GetLatestBlock returns the latest block. + GetLatestBlock(context.Context, *GetLatestBlockRequest) (*GetLatestBlockResponse, error) + // GetBlockByHeight queries block for given height. + GetBlockByHeight(context.Context, *GetBlockByHeightRequest) (*GetBlockByHeightResponse, error) + // GetLatestValidatorSet queries latest validator-set. + GetLatestValidatorSet(context.Context, *GetLatestValidatorSetRequest) (*GetLatestValidatorSetResponse, error) + // GetValidatorSetByHeight queries validator-set at a given height. + GetValidatorSetByHeight(context.Context, *GetValidatorSetByHeightRequest) (*GetValidatorSetByHeightResponse, error) +} + +// UnimplementedServiceServer can be embedded to have forward compatible implementations. +type UnimplementedServiceServer struct { +} + +func (*UnimplementedServiceServer) GetNodeInfo(ctx context.Context, req *GetNodeInfoRequest) (*GetNodeInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetNodeInfo not implemented") +} +func (*UnimplementedServiceServer) GetSyncing(ctx context.Context, req *GetSyncingRequest) (*GetSyncingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSyncing not implemented") +} +func (*UnimplementedServiceServer) GetLatestBlock(ctx context.Context, req *GetLatestBlockRequest) (*GetLatestBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLatestBlock not implemented") +} +func (*UnimplementedServiceServer) GetBlockByHeight(ctx context.Context, req *GetBlockByHeightRequest) (*GetBlockByHeightResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlockByHeight not implemented") +} +func (*UnimplementedServiceServer) GetLatestValidatorSet(ctx context.Context, req *GetLatestValidatorSetRequest) (*GetLatestValidatorSetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLatestValidatorSet not implemented") +} +func (*UnimplementedServiceServer) GetValidatorSetByHeight(ctx context.Context, req *GetValidatorSetByHeightRequest) (*GetValidatorSetByHeightResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetValidatorSetByHeight not implemented") +} + +func RegisterServiceServer(s grpc1.Server, srv ServiceServer) { + s.RegisterService(&_Service_serviceDesc, srv) +} + +func _Service_GetNodeInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNodeInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetNodeInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetNodeInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetNodeInfo(ctx, req.(*GetNodeInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetSyncing_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSyncingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetSyncing(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetSyncing", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetSyncing(ctx, req.(*GetSyncingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetLatestBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLatestBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetLatestBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetLatestBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetLatestBlock(ctx, req.(*GetLatestBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetBlockByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockByHeightRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetBlockByHeight(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetBlockByHeight", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetBlockByHeight(ctx, req.(*GetBlockByHeightRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetLatestValidatorSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLatestValidatorSetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetLatestValidatorSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetLatestValidatorSet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetLatestValidatorSet(ctx, req.(*GetLatestValidatorSetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Service_GetValidatorSetByHeight_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetValidatorSetByHeightRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ServiceServer).GetValidatorSetByHeight(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.base.tendermint.v1beta1.Service/GetValidatorSetByHeight", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ServiceServer).GetValidatorSetByHeight(ctx, req.(*GetValidatorSetByHeightRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Service_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.base.tendermint.v1beta1.Service", + HandlerType: (*ServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetNodeInfo", + Handler: _Service_GetNodeInfo_Handler, + }, + { + MethodName: "GetSyncing", + Handler: _Service_GetSyncing_Handler, + }, + { + MethodName: "GetLatestBlock", + Handler: _Service_GetLatestBlock_Handler, + }, + { + MethodName: "GetBlockByHeight", + Handler: _Service_GetBlockByHeight_Handler, + }, + { + MethodName: "GetLatestValidatorSet", + Handler: _Service_GetLatestValidatorSet_Handler, + }, + { + MethodName: "GetValidatorSetByHeight", + Handler: _Service_GetValidatorSetByHeight_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/base/tendermint/v1beta1/query.proto", +} + +func (m *GetValidatorSetByHeightRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetValidatorSetByHeightRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetValidatorSetByHeightRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *GetValidatorSetByHeightResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetValidatorSetByHeightResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetValidatorSetByHeightResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.Validators) > 0 { + for iNdEx := len(m.Validators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Validators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.BlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *GetLatestValidatorSetRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetLatestValidatorSetRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetLatestValidatorSetRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetLatestValidatorSetResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetLatestValidatorSetResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetLatestValidatorSetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.Validators) > 0 { + for iNdEx := len(m.Validators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Validators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.BlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Validator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Validator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ProposerPriority != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ProposerPriority)) + i-- + dAtA[i] = 0x20 + } + if m.VotingPower != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) + i-- + dAtA[i] = 0x18 + } + if len(m.PubKey) > 0 { + i -= len(m.PubKey) + copy(dAtA[i:], m.PubKey) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PubKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetBlockByHeightRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetBlockByHeightRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetBlockByHeightRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *GetBlockByHeightResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetBlockByHeightResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetBlockByHeightResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Block != nil { + { + size, err := m.Block.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockId != nil { + { + size, err := m.BlockId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetLatestBlockRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetLatestBlockRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetLatestBlockRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *GetLatestBlockResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetLatestBlockResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetLatestBlockResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Block != nil { + { + size, err := m.Block.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockId != nil { + { + size, err := m.BlockId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *GetSyncingRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetSyncingRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetSyncingRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *GetSyncingResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetSyncingResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetSyncingResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Syncing { + i-- + if m.Syncing { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *GetNodeInfoRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetNodeInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetNodeInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *GetNodeInfoResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetNodeInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetNodeInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ApplicationVersion != nil { + { + size, err := m.ApplicationVersion.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.DefaultNodeInfo != nil { + { + size, err := m.DefaultNodeInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *VersionInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VersionInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VersionInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BuildDeps) > 0 { + for iNdEx := len(m.BuildDeps) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BuildDeps[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.GoVersion) > 0 { + i -= len(m.GoVersion) + copy(dAtA[i:], m.GoVersion) + i = encodeVarintQuery(dAtA, i, uint64(len(m.GoVersion))) + i-- + dAtA[i] = 0x32 + } + if len(m.BuildTags) > 0 { + i -= len(m.BuildTags) + copy(dAtA[i:], m.BuildTags) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BuildTags))) + i-- + dAtA[i] = 0x2a + } + if len(m.GitCommit) > 0 { + i -= len(m.GitCommit) + copy(dAtA[i:], m.GitCommit) + i = encodeVarintQuery(dAtA, i, uint64(len(m.GitCommit))) + i-- + dAtA[i] = 0x22 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x1a + } + if len(m.AppName) > 0 { + i -= len(m.AppName) + copy(dAtA[i:], m.AppName) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AppName))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Module) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Module) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Module) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Sum) > 0 { + i -= len(m.Sum) + copy(dAtA[i:], m.Sum) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Sum))) + i-- + dAtA[i] = 0x1a + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GetValidatorSetByHeightRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *GetValidatorSetByHeightResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BlockHeight)) + } + if len(m.Validators) > 0 { + for _, e := range m.Validators { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *GetLatestValidatorSetRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *GetLatestValidatorSetResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BlockHeight)) + } + if len(m.Validators) > 0 { + for _, e := range m.Validators { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *Validator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PubKey) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.VotingPower != 0 { + n += 1 + sovQuery(uint64(m.VotingPower)) + } + if m.ProposerPriority != 0 { + n += 1 + sovQuery(uint64(m.ProposerPriority)) + } + return n +} + +func (m *GetBlockByHeightRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + return n +} + +func (m *GetBlockByHeightResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockId != nil { + l = m.BlockId.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Block != nil { + l = m.Block.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *GetLatestBlockRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *GetLatestBlockResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockId != nil { + l = m.BlockId.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Block != nil { + l = m.Block.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *GetSyncingRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *GetSyncingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Syncing { + n += 2 + } + return n +} + +func (m *GetNodeInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *GetNodeInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.DefaultNodeInfo != nil { + l = m.DefaultNodeInfo.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.ApplicationVersion != nil { + l = m.ApplicationVersion.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *VersionInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AppName) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.GitCommit) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.BuildTags) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.GoVersion) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.BuildDeps) > 0 { + for _, e := range m.BuildDeps { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *Module) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Path) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Sum) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GetValidatorSetByHeightRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetValidatorSetByHeightRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetValidatorSetByHeightRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetValidatorSetByHeightResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetValidatorSetByHeightResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetValidatorSetByHeightResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validators = append(m.Validators, &Validator{}) + if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetLatestValidatorSetRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetLatestValidatorSetRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetLatestValidatorSetRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetLatestValidatorSetResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetLatestValidatorSetResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetLatestValidatorSetResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validators = append(m.Validators, &Validator{}) + if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Validator) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Validator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Validator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) + if m.Address == nil { + m.Address = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) + } + m.VotingPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotingPower |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposerPriority", wireType) + } + m.ProposerPriority = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProposerPriority |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetBlockByHeightRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetBlockByHeightRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetBlockByHeightRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetBlockByHeightResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetBlockByHeightResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetBlockByHeightResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockId == nil { + m.BlockId = &types.BlockID{} + } + if err := m.BlockId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Block", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Block == nil { + m.Block = &types.Block{} + } + if err := m.Block.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetLatestBlockRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetLatestBlockRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetLatestBlockRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetLatestBlockResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetLatestBlockResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetLatestBlockResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockId == nil { + m.BlockId = &types.BlockID{} + } + if err := m.BlockId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Block", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Block == nil { + m.Block = &types.Block{} + } + if err := m.Block.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetSyncingRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetSyncingRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetSyncingRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetSyncingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetSyncingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetSyncingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Syncing", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Syncing = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetNodeInfoRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetNodeInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetNodeInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetNodeInfoResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetNodeInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetNodeInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultNodeInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DefaultNodeInfo == nil { + m.DefaultNodeInfo = &p2p.DefaultNodeInfo{} + } + if err := m.DefaultNodeInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ApplicationVersion", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ApplicationVersion == nil { + m.ApplicationVersion = &VersionInfo{} + } + if err := m.ApplicationVersion.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VersionInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VersionInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VersionInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GitCommit", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GitCommit = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BuildTags", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BuildTags = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GoVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GoVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BuildDeps", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BuildDeps = append(m.BuildDeps, &Module{}) + if err := m.BuildDeps[len(m.BuildDeps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Module) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sum", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sum = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/types/query/query.pb.gw.go b/types/query/query.pb.gw.go new file mode 100644 index 0000000000..01b943030d --- /dev/null +++ b/types/query/query.pb.gw.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: cosmos/base/tendermint/v1beta1/query.proto + +/* +Package query is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package query + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_Service_GetNodeInfo_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetNodeInfoRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetNodeInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetNodeInfo_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetNodeInfoRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetNodeInfo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Service_GetSyncing_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetSyncingRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetSyncing(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetSyncing_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetSyncingRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetSyncing(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Service_GetLatestBlock_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLatestBlockRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetLatestBlock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetLatestBlock_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLatestBlockRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetLatestBlock(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Service_GetBlockByHeight_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetBlockByHeightRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := client.GetBlockByHeight(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetBlockByHeight_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetBlockByHeightRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := server.GetBlockByHeight(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Service_GetLatestValidatorSet_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Service_GetLatestValidatorSet_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLatestValidatorSetRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_GetLatestValidatorSet_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetLatestValidatorSet(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetLatestValidatorSet_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLatestValidatorSetRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_GetLatestValidatorSet_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetLatestValidatorSet(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Service_GetValidatorSetByHeight_0 = &utilities.DoubleArray{Encoding: map[string]int{"height": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Service_GetValidatorSetByHeight_0(ctx context.Context, marshaler runtime.Marshaler, client ServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetValidatorSetByHeightRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_GetValidatorSetByHeight_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetValidatorSetByHeight(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Service_GetValidatorSetByHeight_0(ctx context.Context, marshaler runtime.Marshaler, server ServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetValidatorSetByHeightRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Service_GetValidatorSetByHeight_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetValidatorSetByHeight(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterServiceHandlerServer registers the http handlers for service Service to "mux". +// UnaryRPC :call ServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterServiceHandlerFromEndpoint instead. +func RegisterServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ServiceServer) error { + + mux.Handle("GET", pattern_Service_GetNodeInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetNodeInfo_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetNodeInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetSyncing_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetSyncing_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetSyncing_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetLatestBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetLatestBlock_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetLatestBlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetBlockByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetBlockByHeight_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetBlockByHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetLatestValidatorSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetLatestValidatorSet_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetLatestValidatorSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetValidatorSetByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Service_GetValidatorSetByHeight_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetValidatorSetByHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterServiceHandlerFromEndpoint is same as RegisterServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterServiceHandler(ctx, mux, conn) +} + +// RegisterServiceHandler registers the http handlers for service Service to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterServiceHandlerClient(ctx, mux, NewServiceClient(conn)) +} + +// RegisterServiceHandlerClient registers the http handlers for service Service +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ServiceClient" to call the correct interceptors. +func RegisterServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ServiceClient) error { + + mux.Handle("GET", pattern_Service_GetNodeInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetNodeInfo_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetNodeInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetSyncing_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetSyncing_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetSyncing_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetLatestBlock_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetLatestBlock_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetLatestBlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetBlockByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetBlockByHeight_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetBlockByHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetLatestValidatorSet_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetLatestValidatorSet_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetLatestValidatorSet_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Service_GetValidatorSetByHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Service_GetValidatorSetByHeight_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Service_GetValidatorSetByHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Service_GetNodeInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "base", "tendermint", "v1beta1", "node_info"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetSyncing_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "base", "tendermint", "v1beta1", "syncing"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetLatestBlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"cosmos", "base", "tendermint", "v1beta1", "blocks", "latest"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetBlockByHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmos", "base", "tendermint", "v1beta1", "blocks", "height"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetLatestValidatorSet_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5}, []string{"cosmos", "base", "tendermint", "v1beta1", "validators", "latest"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Service_GetValidatorSetByHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"cosmos", "base", "tendermint", "v1beta1", "validators", "height"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Service_GetNodeInfo_0 = runtime.ForwardResponseMessage + + forward_Service_GetSyncing_0 = runtime.ForwardResponseMessage + + forward_Service_GetLatestBlock_0 = runtime.ForwardResponseMessage + + forward_Service_GetBlockByHeight_0 = runtime.ForwardResponseMessage + + forward_Service_GetLatestValidatorSet_0 = runtime.ForwardResponseMessage + + forward_Service_GetValidatorSetByHeight_0 = runtime.ForwardResponseMessage +) From 512b533242d34926972a8fc2f5639e8cf182f5bd Mon Sep 17 00:00:00 2001 From: yihuang Date: Thu, 26 Nov 2020 02:02:10 +0800 Subject: [PATCH 56/57] cli: ParseCoin doesn't do normalize (#7954) follow up on https://github.com/cosmos/cosmos-sdk/pull/7777 ParseCoin need to be treated similarly. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- types/bench_test.go | 2 +- types/coin.go | 27 +++++--------------- x/ibc/applications/transfer/client/cli/tx.go | 2 +- x/staking/client/cli/cli_test.go | 2 +- x/staking/client/cli/tx.go | 10 ++++---- x/staking/client/rest/grpc_query_test.go | 2 +- 6 files changed, 15 insertions(+), 30 deletions(-) diff --git a/types/bench_test.go b/types/bench_test.go index be7e0c7f4b..6c1cbc88cb 100644 --- a/types/bench_test.go +++ b/types/bench_test.go @@ -18,7 +18,7 @@ func BenchmarkParseCoin(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { for _, coinStr := range coinStrs { - coin, err := types.ParseCoin(coinStr) + coin, err := types.ParseCoinNormalized(coinStr) if err != nil { b.Fatal(err) } diff --git a/types/coin.go b/types/coin.go index da2e3c398a..b86cff5186 100644 --- a/types/coin.go +++ b/types/coin.go @@ -599,11 +599,9 @@ var ( // Denominations can be 3 ~ 128 characters long and support letters, followed by either // a letter, a number or a separator ('/'). reDnmString = `[a-zA-Z][a-zA-Z0-9/]{2,127}` - reAmt = `[[:digit:]]+` reDecAmt = `[[:digit:]]+(?:\.[[:digit:]]+)?|\.[[:digit:]]+` reSpc = `[[:space:]]*` reDnm *regexp.Regexp - reCoin *regexp.Regexp reDecCoin *regexp.Regexp ) @@ -625,7 +623,6 @@ func SetCoinDenomRegex(reFn func() string) { coinDenomRegex = reFn reDnm = regexp.MustCompile(fmt.Sprintf(`^%s$`, coinDenomRegex())) - reCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reAmt, reSpc, coinDenomRegex())) reDecCoin = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)$`, reDecAmt, reSpc, coinDenomRegex())) } @@ -643,29 +640,17 @@ func mustValidateDenom(denom string) { } } -// ParseCoin parses a cli input for one coin type, returning errors if invalid or on an empty string +// ParseCoinNormalized parses and normalize a cli input for one coin type, returning errors if invalid or on an empty string // as well. // Expected format: "{amount}{denomination}" -func ParseCoin(coinStr string) (coin Coin, err error) { - coinStr = strings.TrimSpace(coinStr) - - matches := reCoin.FindStringSubmatch(coinStr) - if matches == nil { - return Coin{}, fmt.Errorf("invalid coin expression: %s", coinStr) - } - - denomStr, amountStr := matches[2], matches[1] - - amount, ok := NewIntFromString(amountStr) - if !ok { - return Coin{}, fmt.Errorf("failed to parse coin amount: %s", amountStr) - } - - if err := ValidateDenom(denomStr); err != nil { +func ParseCoinNormalized(coinStr string) (coin Coin, err error) { + decCoin, err := ParseDecCoin(coinStr) + if err != nil { return Coin{}, err } - return NewCoin(denomStr, amount), nil + coin, _ = NormalizeDecCoin(decCoin).TruncateDecimal() + return coin, nil } // ParseCoinsNormalized will parse out a list of coins separated by commas, and normalize them by converting to smallest diff --git a/x/ibc/applications/transfer/client/cli/tx.go b/x/ibc/applications/transfer/client/cli/tx.go index 1c4fa4e613..507840a582 100644 --- a/x/ibc/applications/transfer/client/cli/tx.go +++ b/x/ibc/applications/transfer/client/cli/tx.go @@ -46,7 +46,7 @@ to the counterparty channel. Any timeout set to 0 is disabled.`), srcChannel := args[1] receiver := args[2] - coin, err := sdk.ParseCoin(args[3]) + coin, err := sdk.ParseCoinNormalized(args[3]) if err != nil { return err } diff --git a/x/staking/client/cli/cli_test.go b/x/staking/client/cli/cli_test.go index 12b4084a4e..40c051bf25 100644 --- a/x/staking/client/cli/cli_test.go +++ b/x/staking/client/cli/cli_test.go @@ -51,7 +51,7 @@ func (s *IntegrationTestSuite) SetupSuite() { _, err := s.network.WaitForHeight(1) s.Require().NoError(err) - unbond, err := sdk.ParseCoin("10stake") + unbond, err := sdk.ParseCoinNormalized("10stake") s.Require().NoError(err) val := s.network.Validators[0] diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 45bc2f8abc..72938ce0a0 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -172,7 +172,7 @@ $ %s tx staking delegate %s1l2rsakp388kuv9k8qzq6lrm9taddae7fpx59wm 1000stake --f return err } - amount, err := sdk.ParseCoin(args[1]) + amount, err := sdk.ParseCoinNormalized(args[1]) if err != nil { return err } @@ -231,7 +231,7 @@ $ %s tx staking redelegate %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj %s1l2rsakp3 return err } - amount, err := sdk.ParseCoin(args[2]) + amount, err := sdk.ParseCoinNormalized(args[2]) if err != nil { return err } @@ -279,7 +279,7 @@ $ %s tx staking unbond %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from return err } - amount, err := sdk.ParseCoin(args[1]) + amount, err := sdk.ParseCoinNormalized(args[1]) if err != nil { return err } @@ -300,7 +300,7 @@ $ %s tx staking unbond %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj 100stake --from func NewBuildCreateValidatorMsg(clientCtx client.Context, txf tx.Factory, fs *flag.FlagSet) (tx.Factory, sdk.Msg, error) { fAmount, _ := fs.GetString(FlagAmount) - amount, err := sdk.ParseCoin(fAmount) + amount, err := sdk.ParseCoinNormalized(fAmount) if err != nil { return txf, nil, err } @@ -514,7 +514,7 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c // BuildCreateValidatorMsg makes a new MsgCreateValidator. func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorConfig, txBldr tx.Factory, generateOnly bool) (tx.Factory, sdk.Msg, error) { amounstStr := config.Amount - amount, err := sdk.ParseCoin(amounstStr) + amount, err := sdk.ParseCoinNormalized(amounstStr) if err != nil { return txBldr, nil, err diff --git a/x/staking/client/rest/grpc_query_test.go b/x/staking/client/rest/grpc_query_test.go index 3aa4afdcfe..696a55ff9b 100644 --- a/x/staking/client/rest/grpc_query_test.go +++ b/x/staking/client/rest/grpc_query_test.go @@ -39,7 +39,7 @@ func (s *IntegrationTestSuite) SetupSuite() { _, err := s.network.WaitForHeight(1) s.Require().NoError(err) - unbond, err := sdk.ParseCoin("10stake") + unbond, err := sdk.ParseCoinNormalized("10stake") s.Require().NoError(err) val := s.network.Validators[0] From ed9fc058f19b00bc93b1d9c94296b1ebce5446e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Thu, 26 Nov 2020 14:44:54 +0100 Subject: [PATCH 57/57] Add an IBC prefix to transfer escrow addresses (#7967) * add IBC prefix to escrow addresses * use ADR 028 AddressHash construction * remove extra space * apply @AdityaSripal suggestion; prefix from ibc -> ibc-transfer-escrow-prefix * Use alternative 1 proposed by @andrey-kuprianov * anticpate necessary build fix * add escrow address issue link into module.go * Update x/ibc/applications/transfer/types/keys.go Co-authored-by: Andrey Kuprianov <59489470+andrey-kuprianov@users.noreply.github.com> * Update x/ibc/applications/transfer/types/keys.go Co-authored-by: Andrey Kuprianov <59489470+andrey-kuprianov@users.noreply.github.com> * apply @andrey-kuprianov review suggestions Deduplicate code into a helper function as suggested. Add unit tests for max transfer channels test. Co-authored-by: Andrey Kuprianov <59489470+andrey-kuprianov@users.noreply.github.com> --- x/ibc/applications/transfer/module.go | 65 +++++++++++++-------- x/ibc/applications/transfer/module_test.go | 12 ++++ x/ibc/applications/transfer/types/errors.go | 1 + x/ibc/applications/transfer/types/keys.go | 22 ++++--- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/x/ibc/applications/transfer/module.go b/x/ibc/applications/transfer/module.go index d14637614b..bf324e2c9b 100644 --- a/x/ibc/applications/transfer/module.go +++ b/x/ibc/applications/transfer/module.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "math" "math/rand" "github.com/grpc-ecosystem/grpc-gateway/runtime" @@ -182,6 +183,42 @@ func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.Weig //____________________________________________________________________________ +// ValidateTransferChannelParams does validation of a newly created transfer channel. A transfer +// channel must be UNORDERED, use the correct port (by default 'transfer'), and use the current +// supported version. Only 2^32 channels are allowed to be created. +func ValidateTransferChannelParams( + ctx sdk.Context, + keeper keeper.Keeper, + order channeltypes.Order, + portID string, + channelID string, + version string, +) error { + // NOTE: for escrow address security only 2^32 channels are allowed to be created + // Issue: https://github.com/cosmos/cosmos-sdk/issues/7737 + channelSequence, err := channeltypes.ParseChannelSequence(channelID) + if err != nil { + return err + } + if channelSequence > math.MaxUint32 { + return sdkerrors.Wrapf(types.ErrMaxTransferChannels, "channel sequence %d is greater than max allowed transfer channels %d", channelSequence, math.MaxUint32) + } + if order != channeltypes.UNORDERED { + return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) + } + + // Require portID is the portID transfer module is bound to + boundPort := keeper.GetPort(ctx) + if boundPort != portID { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) + } + + if version != types.Version { + return sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) + } + return nil +} + // OnChanOpenInit implements the IBCModule interface func (am AppModule) OnChanOpenInit( ctx sdk.Context, @@ -193,18 +230,8 @@ func (am AppModule) OnChanOpenInit( counterparty channeltypes.Counterparty, version string, ) error { - if order != channeltypes.UNORDERED { - return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) - } - - // Require portID is the portID transfer module is bound to - boundPort := am.keeper.GetPort(ctx) - if boundPort != portID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) - } - - if version != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version) + if err := ValidateTransferChannelParams(ctx, am.keeper, order, portID, channelID, version); err != nil { + return err } // Claim channel capability passed back by IBC module @@ -227,18 +254,8 @@ func (am AppModule) OnChanOpenTry( version, counterpartyVersion string, ) error { - if order != channeltypes.UNORDERED { - return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s ", channeltypes.UNORDERED, order) - } - - // Require portID is the portID transfer module is bound to - boundPort := am.keeper.GetPort(ctx) - if boundPort != portID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", portID, boundPort) - } - - if version != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "got: %s, expected %s", version, types.Version) + if err := ValidateTransferChannelParams(ctx, am.keeper, order, portID, channelID, version); err != nil { + return err } if counterpartyVersion != types.Version { diff --git a/x/ibc/applications/transfer/module_test.go b/x/ibc/applications/transfer/module_test.go index b6ce1077c6..d2acfb4043 100644 --- a/x/ibc/applications/transfer/module_test.go +++ b/x/ibc/applications/transfer/module_test.go @@ -1,6 +1,8 @@ package transfer_test import ( + "math" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" @@ -26,6 +28,11 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { { "success", func() {}, true, }, + { + "max channels reached", func() { + testChannel.ID = channeltypes.FormatChannelIdentifier(math.MaxUint32 + 1) + }, false, + }, { "invalid order - ORDERED", func() { channel.Ordering = channeltypes.ORDERED @@ -109,6 +116,11 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { { "success", func() {}, true, }, + { + "max channels reached", func() { + testChannel.ID = channeltypes.FormatChannelIdentifier(math.MaxUint32 + 1) + }, false, + }, { "capability already claimed in INIT should pass", func() { err := suite.chainA.App.ScopedTransferKeeper.ClaimCapability(suite.chainA.GetContext(), chanCap, host.ChannelCapabilityPath(testChannel.PortID, testChannel.ID)) diff --git a/x/ibc/applications/transfer/types/errors.go b/x/ibc/applications/transfer/types/errors.go index e3311bed31..07cba19491 100644 --- a/x/ibc/applications/transfer/types/errors.go +++ b/x/ibc/applications/transfer/types/errors.go @@ -13,4 +13,5 @@ var ( ErrTraceNotFound = sdkerrors.Register(ModuleName, 6, "denomination trace not found") ErrSendDisabled = sdkerrors.Register(ModuleName, 7, "fungible token transfers from this chain are disabled") ErrReceiveDisabled = sdkerrors.Register(ModuleName, 8, "fungible token transfers to this chain are disabled") + ErrMaxTransferChannels = sdkerrors.Register(ModuleName, 9, "max transfer channels") ) diff --git a/x/ibc/applications/transfer/types/keys.go b/x/ibc/applications/transfer/types/keys.go index 1b0e45b9c7..c156af3fd8 100644 --- a/x/ibc/applications/transfer/types/keys.go +++ b/x/ibc/applications/transfer/types/keys.go @@ -1,10 +1,9 @@ package types import ( + "crypto/sha256" "fmt" - "github.com/tendermint/tendermint/crypto" - sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -39,11 +38,18 @@ var ( DenomTraceKey = []byte{0x02} ) -// GetEscrowAddress returns the escrow address for the specified channel -// -// CONTRACT: this assumes that there's only one bank bridge module that owns the -// port associated with the channel ID so that the address created is actually -// unique. +// GetEscrowAddress returns the escrow address for the specified channel. +// The escrow address follows the format as outlined in ADR 028: +// https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-028-public-key-addresses.md func GetEscrowAddress(portID, channelID string) sdk.AccAddress { - return sdk.AccAddress(crypto.AddressHash([]byte(fmt.Sprintf("%s/%s", portID, channelID)))) + // a slash is used to create domain separation between port and channel identifiers to + // prevent address collisions between escrow addresses created for different channels + contents := fmt.Sprintf("%s/%s", portID, channelID) + + // ADR 028 AddressHash construction + preImage := []byte(Version) + preImage = append(preImage, 0) + preImage = append(preImage, contents...) + hash := sha256.Sum256(preImage) + return hash[:20] }