Skip to content

Commit

Permalink
go-kosu: add genesis state verifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustavo Chain committed Sep 17, 2019
1 parent 67b4ae8 commit 68e7577
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/go-kosu/Makefile
Expand Up @@ -12,6 +12,7 @@ GOLINT = golangci-lint run --enable-all \
--disable=gochecknoinits \
--disable=scopelint \
--disable=interfacer \
--disable=funlen \
--exclude-use-default=false \
--deadline=10m

Expand Down
66 changes: 66 additions & 0 deletions packages/go-kosu/abci/app_test.go
Expand Up @@ -131,3 +131,69 @@ func TestUpdateConfirmationThreshold(t *testing.T) {
)
}
}

func TestGenesisStateCorrectness(t *testing.T) {
dir := initTendermint(t)
closer := func() { _ = os.RemoveAll(dir) }
defer closer()

app := NewApp(db.NewMemDB(), dir)

updates := abci.ValidatorUpdates{
abci.Ed25519ValidatorUpdate([]byte("some_pub_key"), 10),
}

t.Run("InitialValidatorInfo_And_Snapshot_Defined", func(t *testing.T) {
app.InitChain(abci.RequestInitChain{
Validators: updates, AppStateBytes: []byte(`{
"initial_validator_info": [
{"public_key": "some_pub_key", "ethereum_address": "0xethereum", "initial_stake": "10000000000000000000"}
],
"snapshot_block": 999
}`),
})
})

t.Run("InitialValidatorInfo_And_Snapshot_Zero", func(t *testing.T) {
fn := func() {
app.InitChain(abci.RequestInitChain{
Validators: updates, AppStateBytes: []byte(`{
"initial_validator_info": [
{"public_key": "some_pub_key", "ethereum_address": "0xethereum", "initial_stake": "10000000000000000000"}
],
"snapshot_block": 0
}`),
})
}
assert.Panics(t, fn)
})

t.Run("Balances_Doesnt_Match", func(t *testing.T) {
fn := func() {
app.InitChain(abci.RequestInitChain{
Validators: updates, AppStateBytes: []byte(`{
"initial_validator_info": [
{"public_key": "some_pub_key", "ethereum_address": "0xethereum", "initial_stake": "99990000000000000000"}
],
"snapshot_block": 999
}`),
})
}
assert.Panics(t, fn)
})

t.Run("PublicKeys_Doesnt_Match", func(t *testing.T) {
fn := func() {
app.InitChain(abci.RequestInitChain{
Validators: updates, AppStateBytes: []byte(`{
"initial_validator_info": [
{"public_key": "different_pub_key", "ethereum_address": "0xethereum", "initial_stake": "10000000000000000000"}
],
"snapshot_block": 999
}`),
})
}
assert.Panics(t, fn)
})

}
14 changes: 9 additions & 5 deletions packages/go-kosu/abci/genesis.go
@@ -1,8 +1,8 @@
package abci

import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"

abci "github.com/tendermint/tendermint/abci/types"
Expand All @@ -13,17 +13,17 @@ import (
// GenesisValidator is the data structure used to define a validator in the app_state section of the genesis file
// It links a Tendermint PublicKey with an Ethereum Address.
type GenesisValidator struct {
PublicKey []byte
EthereumAddress string
InitialStake string
PublicKey string `json:"public_key"`
EthereumAddress string `json:"ethereum_address"`
InitialStake string `json:"initial_stake"`
}

// GenesisValidatorSet is the initial set of validators
type GenesisValidatorSet []GenesisValidator

func (s GenesisValidatorSet) Len() int { return len(s) }
func (s GenesisValidatorSet) Less(i, j int) bool {
return bytes.Compare(s[i].PublicKey, s[j].PublicKey) <= 0
return s[i].PublicKey < s[j].PublicKey
}
func (s GenesisValidatorSet) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

Expand All @@ -44,6 +44,10 @@ func NewGenesisFromRequest(req abci.RequestInitChain) (*Genesis, error) {
if err := json.Unmarshal(req.AppStateBytes, gen); err != nil {
return nil, err
}

if len(gen.InitialValidatorInfo) != 0 && gen.SnapshotBlock == 0 {
return nil, errors.New(".SnapshotBlock can't be zero when .InitialValidatorInfo are defined")
}
return gen, nil
}

Expand Down
4 changes: 2 additions & 2 deletions packages/go-kosu/abci/validators.go
Expand Up @@ -66,9 +66,9 @@ func UnifyValidators(updates abci.ValidatorUpdates, state GenesisValidatorSet) (
s := state[i]

// key verification
if !bytes.Equal(v.PublicKey, s.PublicKey) {
if !bytes.Equal(v.PublicKey, []byte(s.PublicKey)) {
return nil, NewPublicKeyMismatchError(
v.PublicKey, s.PublicKey,
v.PublicKey, []byte(s.PublicKey),
)
}

Expand Down
10 changes: 5 additions & 5 deletions packages/go-kosu/abci/validators_test.go
Expand Up @@ -53,7 +53,7 @@ func TestValidatorsVerification(t *testing.T) {
}

gen := GenesisValidatorSet{
GenesisValidator{PublicKey: pk2, EthereumAddress: "0x1", InitialStake: "1"},
GenesisValidator{PublicKey: string(pk2), EthereumAddress: "0x1", InitialStake: "1"},
}

_, err := UnifyValidators(updates, gen)
Expand All @@ -69,7 +69,7 @@ func TestValidatorsVerification(t *testing.T) {
}

gen := GenesisValidatorSet{
GenesisValidator{PublicKey: pk, EthereumAddress: "0x1", InitialStake: "20000000000000000000"},
GenesisValidator{PublicKey: string(pk), EthereumAddress: "0x1", InitialStake: "20000000000000000000"},
}

_, err := UnifyValidators(updates, gen)
Expand All @@ -87,8 +87,8 @@ func TestValidatorsVerification(t *testing.T) {
}

gen := GenesisValidatorSet{
GenesisValidator{PublicKey: pk2, EthereumAddress: "0x2", InitialStake: "2000000000000000000"},
GenesisValidator{PublicKey: pk1, EthereumAddress: "0x1", InitialStake: "1000000000000000000"},
GenesisValidator{PublicKey: string(pk2), EthereumAddress: "0x2", InitialStake: "2000000000000000000"},
GenesisValidator{PublicKey: string(pk1), EthereumAddress: "0x1", InitialStake: "1000000000000000000"},
}

set, err := UnifyValidators(updates, gen)
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestValidatorsVerificationOnInitChain(t *testing.T) {
require.NoError(t, json.Unmarshal(doc.AppState, gen))

gen.InitialValidatorInfo = GenesisValidatorSet{
GenesisValidator{PublicKey: []byte("key_foo")},
GenesisValidator{PublicKey: "key_foo"},
}

assert.Panics(t, func() {
Expand Down

0 comments on commit 68e7577

Please sign in to comment.