Merge PR #1115: Update SDK to ABCI v11

This commit is contained in:
Christopher Goes 2018-06-05 01:42:01 +02:00 committed by GitHub
parent f0a53e26bb
commit be7ec5bc07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 149 additions and 72 deletions

10
Gopkg.lock generated
View File

@ -267,8 +267,8 @@
"server",
"types"
]
revision = "f9dce537281ffba5d1e047e6729429f7e5fb90c9"
version = "v0.11.0-rc0"
revision = "9af8b7a7c87478869f8c280ed9539470b8f470b4"
version = "v0.11.0-rc4"
[[projects]]
branch = "master"
@ -347,8 +347,8 @@
"types/priv_validator",
"version"
]
revision = "73de99ecab464208f6ea3a96525f4e4b78425e61"
version = "v0.20.0-rc0"
revision = "b5baab0238c9ec26e3b2d229b0243f9ff9220bdb"
version = "v0.20.0-rc3"
[[projects]]
branch = "develop"
@ -463,6 +463,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "c8d0282dfa5b2bb7a0eb54fc24f42021e63f282265332678593658119bf5023b"
inputs-digest = "ccb2ab7644a38c2d0326280582f758256e37fc98c3ef0403581e3b85cff42188"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -54,7 +54,7 @@
[[constraint]]
name = "github.com/tendermint/abci"
version = "0.11.0-rc0"
version = "=0.11.0-rc4"
[[constraint]]
name = "github.com/tendermint/go-crypto"
@ -70,7 +70,7 @@
[[constraint]]
name = "github.com/tendermint/tendermint"
version = "0.20.0-rc0"
version = "=0.20.0-rc3"
[[override]]
name = "github.com/tendermint/tmlibs"

View File

@ -65,10 +65,10 @@ type BaseApp struct {
// See methods setCheckState and setDeliverState.
// .valUpdates accumulate in DeliverTx and are reset in BeginBlock.
// QUESTION: should we put valUpdates in the deliverState.ctx?
checkState *state // for CheckTx
deliverState *state // for DeliverTx
valUpdates []abci.Validator // cached validator changes from DeliverTx
absentValidators [][]byte // absent validators from begin block
checkState *state // for CheckTx
deliverState *state // for DeliverTx
valUpdates []abci.Validator // cached validator changes from DeliverTx
signedValidators []abci.SigningValidator // absent validators from begin block
}
var _ abci.Application = (*BaseApp)(nil)
@ -385,8 +385,8 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg
if app.beginBlocker != nil {
res = app.beginBlocker(app.deliverState.ctx, req)
}
// set the absent validators for addition to context in deliverTx
app.absentValidators = req.AbsentValidators
// set the signed validators for addition to context in deliverTx
app.signedValidators = req.Validators
return
}
@ -496,7 +496,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
ctx = app.checkState.ctx.WithTxBytes(txBytes)
} else {
ctx = app.deliverState.ctx.WithTxBytes(txBytes)
ctx = ctx.WithAbsentValidators(app.absentValidators)
ctx = ctx.WithSigningValidators(app.signedValidators)
}
// Simulate a DeliverTx for gas calculation

View File

@ -1,7 +1,6 @@
package baseapp
import (
"bytes"
"encoding/json"
"fmt"
"os"
@ -12,6 +11,7 @@ import (
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
@ -183,7 +183,7 @@ func TestInitChainer(t *testing.T) {
// set initChainer and try again - should see the value
app.SetInitChainer(initChainer)
app.InitChain(abci.RequestInitChain{GenesisBytes: []byte("{}")}) // must have valid JSON genesis file, even if empty
app.InitChain(abci.RequestInitChain{AppStateBytes: []byte("{}")}) // must have valid JSON genesis file, even if empty
app.Commit()
res = app.Query(query)
assert.Equal(t, value, res.Value)
@ -510,15 +510,20 @@ func TestValidatorChange(t *testing.T) {
// Assert that validator updates are correct.
for _, val := range valSet {
pubkey, err := tmtypes.PB2TM.PubKey(val.PubKey)
// Sanity
assert.NotEqual(t, len(val.PubKey), 0)
assert.Nil(t, err)
// Find matching update and splice it out.
for j := 0; j < len(valUpdates); {
for j := 0; j < len(valUpdates); j++ {
valUpdate := valUpdates[j]
updatePubkey, err := tmtypes.PB2TM.PubKey(valUpdate.PubKey)
assert.Nil(t, err)
// Matched.
if bytes.Equal(valUpdate.PubKey, val.PubKey) {
if updatePubkey.Equals(pubkey) {
assert.Equal(t, valUpdate.Power, val.Power+1)
if j < len(valUpdates)-1 {
// Splice it out.
@ -528,7 +533,6 @@ func TestValidatorChange(t *testing.T) {
}
// Not matched.
j++
}
}
assert.Equal(t, len(valUpdates), 0, "Some validator updates were unexpected")
@ -542,7 +546,7 @@ func randPower() int64 {
func makeVal(secret string) abci.Validator {
return abci.Validator{
PubKey: makePubKey(secret).Bytes(),
PubKey: tmtypes.TM2PB.PubKey(makePubKey(secret)),
Power: randPower(),
}
}

View File

@ -130,7 +130,7 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
// custom logic for gaia initialization
func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.GenesisBytes
stateJSON := req.AppStateBytes
// TODO is this now the whole genesis file?
var genesisState GenesisState

View File

@ -114,7 +114,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
// Initialize the chain
vals := []abci.Validator{}
gapp.InitChain(abci.RequestInitChain{vals, stateBytes})
gapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
gapp.Commit()
return nil

View File

@ -130,7 +130,7 @@ func (app *BasecoinApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) ab
// Custom logic for basecoin initialization
func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.GenesisBytes
stateJSON := req.AppStateBytes
genesisState := new(types.GenesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)

View File

@ -105,7 +105,7 @@ func setGenesis(bapp *BasecoinApp, accs ...auth.BaseAccount) error {
// Initialize the chain
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
return nil
@ -165,7 +165,7 @@ func TestSortGenesis(t *testing.T) {
// Initialize the chain
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, []byte(genState)})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: []byte(genState)})
bapp.Commit()
// Unsorted coins means invalid
@ -427,7 +427,7 @@ func TestMsgQuiz(t *testing.T) {
// Initialize the chain (nil)
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context (true)

View File

@ -118,7 +118,7 @@ func MakeCodec() *wire.Codec {
// custom logic for democoin initialization
func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keeper) sdk.InitChainer {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.GenesisBytes
stateJSON := req.AppStateBytes
genesisState := new(types.GenesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)

View File

@ -142,7 +142,7 @@ func TestGenesis(t *testing.T) {
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context
@ -184,7 +184,7 @@ func TestMsgSendWithAccounts(t *testing.T) {
// Initialize the chain
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context (true)
@ -262,7 +262,7 @@ func TestMsgMine(t *testing.T) {
// Initialize the chain (nil)
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context (true)
@ -309,7 +309,7 @@ func TestMsgQuiz(t *testing.T) {
// Initialize the chain (nil)
vals := []abci.Validator{}
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context (true)
@ -356,7 +356,7 @@ func TestHandler(t *testing.T) {
}
stateBytes, err := json.MarshalIndent(genesisState, "", "\t")
require.Nil(t, err)
bapp.InitChain(abci.RequestInitChain{vals, stateBytes})
bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes})
bapp.Commit()
// A checkTx context (true)

View File

@ -2,6 +2,7 @@ package simplestake
import (
abci "github.com/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -27,7 +28,7 @@ func handleMsgBond(ctx sdk.Context, k Keeper, msg MsgBond) sdk.Result {
}
valSet := abci.Validator{
PubKey: msg.PubKey.Bytes(),
PubKey: tmtypes.TM2PB.PubKey(msg.PubKey),
Power: power,
}
@ -44,7 +45,7 @@ func handleMsgUnbond(ctx sdk.Context, k Keeper, msg MsgUnbond) sdk.Result {
}
valSet := abci.Validator{
PubKey: pubKey.Bytes(),
PubKey: tmtypes.TM2PB.PubKey(pubKey),
Power: int64(0),
}

View File

@ -88,7 +88,7 @@ type GenesisJSON struct {
// with key/value pairs
func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci.ResponseInitChain {
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.GenesisBytes
stateJSON := req.AppStateBytes
genesisState := new(GenesisJSON)
err := json.Unmarshal(stateJSON, genesisState)

View File

@ -26,7 +26,7 @@ func TestInitApp(t *testing.T) {
//TODO test validators in the init chain?
req := abci.RequestInitChain{
GenesisBytes: appState,
AppStateBytes: appState,
}
app.InitChain(req)
app.Commit()

View File

@ -44,7 +44,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, txBytes []byt
c = c.WithIsCheckTx(isCheckTx)
c = c.WithTxBytes(txBytes)
c = c.WithLogger(logger)
c = c.WithAbsentValidators(nil)
c = c.WithSigningValidators(nil)
c = c.WithGasMeter(NewInfiniteGasMeter())
return c
}
@ -130,7 +130,7 @@ const (
contextKeyIsCheckTx
contextKeyTxBytes
contextKeyLogger
contextKeyAbsentValidators
contextKeySigningValidators
contextKeyGasMeter
)
@ -160,8 +160,8 @@ func (c Context) TxBytes() []byte {
func (c Context) Logger() log.Logger {
return c.Value(contextKeyLogger).(log.Logger)
}
func (c Context) AbsentValidators() [][]byte {
return c.Value(contextKeyAbsentValidators).([][]byte)
func (c Context) SigningValidators() []abci.SigningValidator {
return c.Value(contextKeySigningValidators).([]abci.SigningValidator)
}
func (c Context) GasMeter() GasMeter {
return c.Value(contextKeyGasMeter).(GasMeter)
@ -188,8 +188,8 @@ func (c Context) WithTxBytes(txBytes []byte) Context {
func (c Context) WithLogger(logger log.Logger) Context {
return c.withValue(contextKeyLogger, logger)
}
func (c Context) WithAbsentValidators(AbsentValidators [][]byte) Context {
return c.withValue(contextKeyAbsentValidators, AbsentValidators)
func (c Context) WithSigningValidators(SigningValidators []abci.SigningValidator) Context {
return c.withValue(contextKeySigningValidators, SigningValidators)
}
func (c Context) WithGasMeter(meter GasMeter) Context {
return c.withValue(contextKeyGasMeter, meter)

View File

@ -3,6 +3,7 @@ package types
import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
)
// status of a validator
@ -41,7 +42,7 @@ type Validator interface {
// validator which fulfills abci validator interface for use in Tendermint
func ABCIValidator(v Validator) abci.Validator {
return abci.Validator{
PubKey: v.GetPubKey().Bytes(),
PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()),
Power: v.GetPower().Evaluate(),
}
}

View File

@ -24,10 +24,12 @@ var (
addrs = []sdk.Address{
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"),
testAddr("A58856F0FD53BF058B4909A21AEC019107BA6162"),
}
pks = []crypto.PubKey{
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"),
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"),
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB52"),
}
initCoins int64 = 200
)

View File

@ -6,49 +6,39 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
)
// slash begin blocker functionality
// slashing begin block functionality
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags sdk.Tags) {
// Tag the height
heightBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(heightBytes, uint64(req.Header.Height))
// TODO Add some more tags so clients can track slashing events
tags = sdk.NewTags("height", heightBytes)
// Deal with any equivocation evidence
for _, evidence := range req.ByzantineValidators {
var pk crypto.PubKey
sk.cdc.MustUnmarshalBinaryBare(evidence.PubKey, &pk)
pk, err := tmtypes.PB2TM.PubKey(evidence.Validator.PubKey)
if err != nil {
panic(err)
}
switch string(evidence.Type) {
case tmtypes.DUPLICATE_VOTE:
case tmtypes.ABCIEvidenceTypeDuplicateVote:
sk.handleDoubleSign(ctx, evidence.Height, evidence.Time, pk)
default:
ctx.Logger().With("module", "x/slashing").Error(fmt.Sprintf("Ignored unknown evidence type: %s", string(evidence.Type)))
}
}
// Figure out which validators were absent
absent := make(map[crypto.PubKey]struct{})
for _, pubkey := range req.AbsentValidators {
var pk crypto.PubKey
sk.cdc.MustUnmarshalBinaryBare(pubkey, &pk)
absent[pk] = struct{}{}
}
// Iterate over all the validators which *should* have signed this block
sk.validatorSet.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) (stop bool) {
pubkey := validator.GetPubKey()
present := true
if _, ok := absent[pubkey]; ok {
present = false
// Iterate over all the validators which *should* have signed this block
for _, validator := range req.Validators {
present := validator.SignedLastBlock
pubkey, err := tmtypes.PB2TM.PubKey(validator.Validator.PubKey)
if err != nil {
panic(err)
}
sk.handleValidatorSignature(ctx, pubkey, present)
return false
})
}
return
}

77
x/slashing/tick_test.go Normal file
View File

@ -0,0 +1,77 @@
package slashing
import (
"testing"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/stake"
)
func TestBeginBlocker(t *testing.T) {
ctx, ck, sk, keeper := createTestInput(t)
addr, pk, amt := addrs[2], pks[2], int64(100)
// bond the validator
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, pk, amt))
require.True(t, got.IsOK())
stake.EndBlocker(ctx, sk)
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}})
require.Equal(t, sdk.NewRat(amt), sk.Validator(ctx, addr).GetPower())
val := abci.Validator{
PubKey: tmtypes.TM2PB.PubKey(pk),
Power: amt,
}
// mark the validator as having signed
req := abci.RequestBeginBlock{
Validators: []abci.SigningValidator{{
Validator: val,
SignedLastBlock: true,
}},
}
BeginBlocker(ctx, req, keeper)
info, found := keeper.getValidatorSigningInfo(ctx, pk.Address())
require.True(t, found)
require.Equal(t, ctx.BlockHeight(), info.StartHeight)
require.Equal(t, int64(1), info.IndexOffset)
require.Equal(t, int64(0), info.JailedUntil)
require.Equal(t, int64(1), info.SignedBlocksCounter)
height := int64(0)
// for 50 blocks, mark the validator as having signed
for ; height < 50; height++ {
ctx = ctx.WithBlockHeight(height)
req = abci.RequestBeginBlock{
Validators: []abci.SigningValidator{{
Validator: val,
SignedLastBlock: true,
}},
}
BeginBlocker(ctx, req, keeper)
}
// for 51 blocks, mark the validator as having not signed
for ; height < 102; height++ {
ctx = ctx.WithBlockHeight(height)
req = abci.RequestBeginBlock{
Validators: []abci.SigningValidator{{
Validator: val,
SignedLastBlock: false,
}},
}
BeginBlocker(ctx, req, keeper)
}
// validator should be revoked
validator, found := sk.GetValidatorByPubKey(ctx, pk)
require.True(t, found)
require.Equal(t, sdk.Unbonded, validator.GetStatus())
}

View File

@ -4,6 +4,7 @@ import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -463,8 +464,8 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) {
updates = keeper.getTendermintUpdates(ctx)
require.Equal(t, 2, len(updates))
assert.Equal(t, validators[0].PubKey.Bytes(), updates[0].PubKey)
assert.Equal(t, validators[1].PubKey.Bytes(), updates[1].PubKey)
assert.Equal(t, tmtypes.TM2PB.PubKey(validators[0].PubKey), updates[0].PubKey)
assert.Equal(t, tmtypes.TM2PB.PubKey(validators[1].PubKey), updates[1].PubKey)
assert.Equal(t, int64(0), updates[0].Power)
assert.Equal(t, int64(0), updates[1].Power)
}

View File

@ -8,6 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/wire"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
)
// Validator defines the total amount of bond shares and their exchange rate to
@ -101,7 +102,7 @@ func NewDescription(moniker, identity, website, details string) Description {
// abci validator from stake validator type
func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
return abci.Validator{
PubKey: v.PubKey.Bytes(),
PubKey: tmtypes.TM2PB.PubKey(v.PubKey),
Power: v.PoolShares.Bonded().Evaluate(),
}
}
@ -110,7 +111,7 @@ func (v Validator) abciValidator(cdc *wire.Codec) abci.Validator {
// with zero power used for validator updates
func (v Validator) abciValidatorZero(cdc *wire.Codec) abci.Validator {
return abci.Validator{
PubKey: v.PubKey.Bytes(),
PubKey: tmtypes.TM2PB.PubKey(v.PubKey),
Power: 0,
}
}