Skip to content

Commit

Permalink
Merge pull request ethereum#485 from thanhnguyennguyen/fix-invalid-si…
Browse files Browse the repository at this point in the history
…gner-at-checkpoint

Fix ethereum#482: Ignore order of masternodes list
  • Loading branch information
ngtuna authored Apr 22, 2019
2 parents 4fc27f2 + 0afd81c commit 6806478
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
23 changes: 21 additions & 2 deletions consensus/posv/posv.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"math/big"
"math/rand"
"path/filepath"
"reflect"
"sort"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -424,9 +426,11 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
signers = RemovePenaltiesFromBlock(chain, signers, number-uint64(i)*c.config.Epoch)
}
}
byteMasterNodes := common.ExtractAddressToBytes(signers)
extraSuffix := len(header.Extra) - extraSeal
if !bytes.Equal(header.Extra[extraVanity:extraSuffix], byteMasterNodes) {
masternodesFromCheckpointHeader := common.ExtractAddressFromBytes(header.Extra[extraVanity:extraSuffix])
validSigners := compareSignersLists(masternodesFromCheckpointHeader, signers)
if !validSigners {
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
return errInvalidCheckpointSigners
}
if c.HookVerifyMNs != nil {
Expand All @@ -440,6 +444,21 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
return c.verifySeal(chain, header, parents, fullVerify)
}

// compare 2 signers lists
// return true if they are same elements, otherwise return false
func compareSignersLists(list1 []common.Address, list2 []common.Address) bool {
if len(list1) == 0 && len(list2) == 0 {
return true
}
sort.Slice(list1, func(i, j int) bool {
return list1[i].String() <= list1[j].String()
})
sort.Slice(list2, func(i, j int) bool {
return list2[i].String() <= list2[j].String()
})
return reflect.DeepEqual(list1, list2)
}

func (c *Posv) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*Snapshot, error) {
number := header.Number.Uint64()
log.Trace("take snapshot", "number", number, "hash", header.Hash())
Expand Down
35 changes: 35 additions & 0 deletions consensus/posv/posv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,38 @@ func TestGetM1M2FromCheckpointHeader(t *testing.T) {
}
}
}

func TestCompareSignersLists(t *testing.T) {
list1 := []common.Address{
common.StringToAddress("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
common.StringToAddress("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc"),
common.StringToAddress("dddddddddddddddddddddddddddddddddddddddd"),
}
list2 := []common.Address{
common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc"),
common.StringToAddress("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
common.StringToAddress("dddddddddddddddddddddddddddddddddddddddd"),
common.StringToAddress("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
}
list3 := []common.Address{
common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc"),
common.StringToAddress("dddddddddddddddddddddddddddddddddddddddd"),
common.StringToAddress("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
}
if !compareSignersLists(list1, list2) {
t.Error("list1 should be equal to list2", "list1", list1, "list2", list2)
}
if compareSignersLists(list1, list3) {
t.Error("list1 and list3 should not be same", "list1", list1, "list3", list3)
}
if !compareSignersLists([]common.Address{}, []common.Address{}) {
t.Error("Failed with empty list")
}
if !compareSignersLists([]common.Address{common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc")}, []common.Address{common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc")}) {
t.Error("Failed with list has only one signer")
}
if compareSignersLists([]common.Address{common.StringToAddress("aaaaaaaaaaaaaaaa")}, []common.Address{common.StringToAddress("cccccccccccccccccccccccccccccccccccccccc")}) {
t.Error("Failed with list has only one signer")
}
}

0 comments on commit 6806478

Please sign in to comment.