Permalink
Browse files

Update against breaking Tendermint changes

Signed-off-by: Silas Davis <silas@monax.io>
  • Loading branch information...
silasdavis committed Aug 21, 2018
1 parent 6db9132 commit 6bba3d12c5a22840beb239b7a7370e4ec4f9678d
View
@@ -50,15 +50,15 @@ func NewRing(initialSet Iterable, windowSize int) *Ring {
// Implement Reader
// Get power at index from the delta bucket then falling through to the cumulative
func (vc *Ring) PowerAt(index int64, id crypto.PublicKey) *big.Int {
func (vc *Ring) PowerAt(index int64, id crypto.Address) *big.Int {
power := vc.Head().MaybePower(id)
if power != nil {
return power
}
return vc.Cum().Power(id)
}
func (vc *Ring) Power(id crypto.PublicKey) *big.Int {
func (vc *Ring) Power(id crypto.Address) *big.Int {
return vc.PowerAt(vc.head, id)
}
@@ -87,29 +87,29 @@ func (vc *Ring) AlterPower(id crypto.PublicKey, power *big.Int) (*big.Int, error
"does not", power)
}
// if flow > maxflow then we cannot alter the power
flow := vc.Flow(id, power)
flow := vc.Flow(id.Address(), power)
maxFlow := vc.MaxFlow()
// Set flow for this id to update flow.totalPower (total flow) for comparison below, keep track of flow for each id
// so that we only count flow once for each id
vc.flow.ChangePower(id, flow)
// The totalPower of the Flow Set is the absolute value of all power changes made so far
if vc.flow.totalPower.Cmp(maxFlow) == 1 {
// Reset flow to previous value to undo update above
prevFlow := vc.Flow(id, vc.Head().Power(id))
prevFlow := vc.Flow(id.Address(), vc.Head().Power(id.Address()))
vc.flow.ChangePower(id, prevFlow)
allowable := new(big.Int).Sub(maxFlow, vc.flow.totalPower)
return nil, fmt.Errorf("cannot change validator power of %v from %v to %v because that would result in a flow "+
"greater than or equal to 1/3 of total power for the next commit: flow induced by change: %v, "+
"current total flow: %v/%v (cumulative/max), remaining allowable flow: %v",
id.Address(), vc.Cum().Power(id), power, flow, vc.flow.totalPower, maxFlow, allowable)
id.Address(), vc.Cum().Power(id.Address()), power, flow, vc.flow.totalPower, maxFlow, allowable)
}
// Add to total power
vc.Head().ChangePower(id, power)
return flow, nil
}
// Returns the flow that would be induced by a validator change by comparing the head accumulater with the current set
func (vc *Ring) Flow(id crypto.PublicKey, power *big.Int) *big.Int {
func (vc *Ring) Flow(id crypto.Address, power *big.Int) *big.Int {
flow := new(big.Int)
return flow.Abs(flow.Sub(power, vc.Cum().Power(id)))
}
View
@@ -49,7 +49,7 @@ func (vs *Set) AlterPower(id crypto.PublicKey, power *big.Int) (flow *big.Int, e
func (vs *Set) ChangePower(id crypto.PublicKey, power *big.Int) *big.Int {
address := id.Address()
// Calculcate flow into this validator (postive means in, negative means out)
flow := new(big.Int).Sub(power, vs.Power(id))
flow := new(big.Int).Sub(power, vs.Power(id.Address()))
vs.totalPower.Add(vs.totalPower, flow)
if vs.trim && power.Sign() == 0 {
@@ -67,18 +67,18 @@ func (vs *Set) TotalPower() *big.Int {
}
// Returns the power of id but only if it is set
func (vs *Set) MaybePower(id crypto.PublicKey) *big.Int {
if vs.powers[id.Address()] == nil {
func (vs *Set) MaybePower(id crypto.Address) *big.Int {
if vs.powers[id] == nil {
return nil
}
return new(big.Int).Set(vs.powers[id.Address()])
return new(big.Int).Set(vs.powers[id])
}
func (vs *Set) Power(id crypto.PublicKey) *big.Int {
if vs.powers[id.Address()] == nil {
func (vs *Set) Power(id crypto.Address) *big.Int {
if vs.powers[id] == nil {
return new(big.Int)
}
return new(big.Int).Set(vs.powers[id.Address()])
return new(big.Int).Set(vs.powers[id])
}
func (vs *Set) Equal(vsOther *Set) bool {
@@ -87,7 +87,7 @@ func (vs *Set) Equal(vsOther *Set) bool {
}
// Stop iteration IFF we find a non-matching validator
return !vs.Iterate(func(id crypto.Addressable, power *big.Int) (stop bool) {
otherPower := vsOther.Power(id.PublicKey())
otherPower := vsOther.Power(id.Address())
if otherPower.Cmp(power) != 0 {
return true
}
@@ -13,7 +13,7 @@ type Writer interface {
}
type Reader interface {
Power(id crypto.PublicKey) *big.Int
Power(id crypto.Address) *big.Int
}
type Iterable interface {
@@ -51,12 +51,12 @@ func (wf WriterFunc) AlterPower(id crypto.PublicKey, power *big.Int) (flow *big.
func AddPower(vs ReaderWriter, id crypto.PublicKey, power *big.Int) error {
// Current power + power
_, err := vs.AlterPower(id, new(big.Int).Add(vs.Power(id), power))
_, err := vs.AlterPower(id, new(big.Int).Add(vs.Power(id.Address()), power))
return err
}
func SubtractPower(vs ReaderWriter, id crypto.PublicKey, power *big.Int) error {
_, err := vs.AlterPower(id, new(big.Int).Sub(vs.Power(id), power))
_, err := vs.AlterPower(id, new(big.Int).Sub(vs.Power(id.Address()), power))
return err
}
View
@@ -44,7 +44,7 @@ func TestBlockchain_Encode(t *testing.T) {
// Should have exponentially decayed to 0
assertZero(t, flow)
assertZero(t, bc.validatorCache.Power(id1))
assertZero(t, bc.validatorCache.Power(id1.Address()))
}
// Since we have -0 and 0 with big.Int due to its representation with a neg flag
@@ -3,10 +3,8 @@ package abci
import (
"fmt"
"math/big"
"sync"
"time"
"runtime/debug"
"sync"
"github.com/hyperledger/burrow/acm/validator"
"github.com/hyperledger/burrow/bcm"
@@ -116,12 +114,12 @@ func (app *App) BeginBlock(block abciTypes.RequestBeginBlock) (respBeginBlock ab
var err error
// Tendermint runs a block behind with the validators passed in here
previousValidators := app.blockchain.PreviousValidators()
if len(block.Validators) != previousValidators.Count() {
if len(block.LastCommitInfo.Validators) != previousValidators.Count() {
err = fmt.Errorf("Tendermint passes %d validators to BeginBlock but Burrow's Blockchain has %d",
len(block.Validators), previousValidators.Count())
len(block.LastCommitInfo.Validators), previousValidators.Count())
panic(err)
}
for _, v := range block.Validators {
for _, v := range block.LastCommitInfo.Validators {
err = app.checkValidatorMatches(previousValidators, v.Validator)
if err != nil {
panic(err)
@@ -132,14 +130,14 @@ func (app *App) BeginBlock(block abciTypes.RequestBeginBlock) (respBeginBlock ab
}
func (app *App) checkValidatorMatches(ours validator.Reader, v abciTypes.Validator) error {
publicKey, err := crypto.PublicKeyFromABCIPubKey(v.PubKey)
address, err := crypto.AddressFromBytes(v.Address)
if err != nil {
return err
}
power := ours.Power(publicKey)
power := ours.Power(address)
if power.Cmp(big.NewInt(v.Power)) != 0 {
return fmt.Errorf("validator %v has power %d from Tendermint but power %d from Burrow",
publicKey.Address(), v.Power, power)
address, v.Power, power)
}
return nil
}
@@ -167,7 +165,6 @@ func (app *App) DeliverTx(txBytes []byte) abciTypes.ResponseDeliverTx {
Log: ctr.Log,
Data: ctr.Data,
Tags: ctr.Tags,
Fee: ctr.Fee,
GasUsed: ctr.GasUsed,
GasWanted: ctr.GasWanted,
Info: ctr.Info,
@@ -241,7 +238,7 @@ func (app *App) Commit() abciTypes.ResponseCommit {
app.panicFunc(fmt.Errorf("panic occurred in abci.App/Commit: %v\n%s", r, debug.Stack()))
}
}()
blockTime := time.Unix(app.block.Header.Time, 0)
blockTime := app.block.Header.Time
app.logger.InfoMsg("Committing block",
"tag", "Commit",
structure.ScopeKey, "Commit()",
@@ -8,7 +8,7 @@ import (
type privValidatorMemory struct {
crypto.Addressable
signer func(msg []byte) tmCrypto.Signature
signer func(msg []byte) []byte
lastSignedInfo *LastSignedInfo
}
@@ -24,8 +24,8 @@ func NewPrivValidatorMemory(addressable crypto.Addressable, signer crypto.Signer
}
}
func asTendermintSigner(signer crypto.Signer) func(msg []byte) tmCrypto.Signature {
return func(msg []byte) tmCrypto.Signature {
func asTendermintSigner(signer crypto.Signer) func(msg []byte) []byte {
return func(msg []byte) []byte {
sig, err := signer.Sign(msg)
if err != nil {
return nil
@@ -8,7 +8,6 @@ import (
"time"
"github.com/hyperledger/burrow/binary"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
)
@@ -36,11 +35,11 @@ func voteToStep(vote *types.Vote) int8 {
// data signed by a validator to help prevent double signing.
type LastSignedInfo struct {
sync.Mutex
Height int64 `json:"height"`
Round int `json:"round"`
Step int8 `json:"step"`
Signature crypto.Signature `json:"signature,omitempty"` // so we dont lose signatures
SignBytes binary.HexBytes `json:"signbytes,omitempty"` // so we dont lose signatures
Height int64 `json:"height"`
Round int `json:"round"`
Step int8 `json:"step"`
Signature []byte `json:"signature,omitempty"` // so we dont lose signatures
SignBytes binary.HexBytes `json:"signbytes,omitempty"` // so we dont lose signatures
}
func NewLastSignedInfo() *LastSignedInfo {
@@ -49,7 +48,7 @@ func NewLastSignedInfo() *LastSignedInfo {
}
}
type tmCryptoSigner func(msg []byte) crypto.Signature
type tmCryptoSigner func(msg []byte) []byte
// SignVote signs a canonical representation of the vote, along with the
// chainID. Implements PrivValidator.
@@ -175,7 +174,7 @@ func (lsi *LastSignedInfo) signProposal(sign tmCryptoSigner, chainID string, pro
// Persist height/round/step and signature
func (lsi *LastSignedInfo) saveSigned(height int64, round int, step int8,
signBytes []byte, sig crypto.Signature) {
signBytes []byte, sig []byte) {
lsi.Height = height
lsi.Round = round
View
@@ -125,7 +125,10 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tmTy
app := abci.NewApp(kern.nodeInfo, kern.Blockchain, checker, committer, txCodec, kern.Panic, logger)
// We could use this to provide/register our own metrics (though this will register them with us). Unfortunately
// Tendermint currently ignores the metrics passed unless its own server is turned on.
metricsProvider := node.DefaultMetricsProvider
metricsProvider := node.DefaultMetricsProvider(&tmConfig.InstrumentationConfig{
Prometheus: false,
PrometheusListenAddr: "",
})
kern.Node, err = tendermint.NewNode(tmConf, privValidator, tmGenesisDoc, app, metricsProvider, tmLogger)
if err != nil {
return nil, err
View
@@ -63,17 +63,6 @@ func (p PublicKey) TendermintPubKey() tmCrypto.PubKey {
// Signature extensions
func (sig Signature) TendermintSignature() tmCrypto.Signature {
switch sig.CurveType {
case CurveTypeEd25519:
s := tmEd25519.SignatureEd25519{}
copy(s[:], sig.Signature)
return s
case CurveTypeSecp256k1:
s := tmSecp256k1.SignatureSecp256k1{}
copy(s[:], sig.Signature)
return s
default:
return nil
}
func (sig Signature) TendermintSignature() []byte {
return sig.Signature
}
@@ -175,7 +175,7 @@ func TestChangePowerByAddress(t *testing.T) {
vs, err := qcli.GetValidatorSet(context.Background(), &rpcquery.GetValidatorSetParam{})
require.NoError(t, err)
set := validator.UnpersistSet(vs.Set)
assert.Equal(t, new(big.Int).SetUint64(power), set.Power(acc.PublicKey()))
assert.Equal(t, new(big.Int).SetUint64(power), set.Power(acc.Address()))
}
func TestInvalidSequenceNumber(t *testing.T) {
View
@@ -21,7 +21,6 @@ import (
"github.com/hyperledger/burrow/acm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
tmEd25519 "github.com/tendermint/tendermint/crypto/ed25519"
tmTypes "github.com/tendermint/tendermint/types"
)
@@ -48,7 +47,7 @@ func TestResultGetBlock(t *testing.T) {
LastCommit: &tmTypes.Commit{
Precommits: []*tmTypes.Vote{
{
Signature: tmEd25519.SignatureEd25519{1, 2, 3},
Signature: []byte{1, 2, 3},
},
},
},
View
@@ -376,7 +376,7 @@ func Status(blockchain bcm.BlockchainInfo, nodeView *tendermint.NodeView, blockT
ValidatorInfo: &validator.Validator{
Address: &address,
PublicKey: publicKey,
Power: blockchain.Validators().Power(publicKey).Uint64(),
Power: blockchain.Validators().Power(address).Uint64(),
},
}

0 comments on commit 6bba3d1

Please sign in to comment.