mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd, contracts: add replay-protection
This commit is contained in:
parent
5d31d9f277
commit
144514518c
7 changed files with 95 additions and 41 deletions
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
|
|
@ -102,7 +103,7 @@ func registerCheckpoint(ctx *cli.Context) error {
|
||||||
var result [3]string
|
var result [3]string
|
||||||
index := ctx.GlobalInt64(checkpointIndexFlag.Name)
|
index := ctx.GlobalInt64(checkpointIndexFlag.Name)
|
||||||
if err := rpcClient.Call(&result, "les_getCheckpoint", index); err != nil {
|
if err := rpcClient.Call(&result, "les_getCheckpoint", index); err != nil {
|
||||||
utils.Fatalf("Failed to get local checkpoint %v", err)
|
utils.Fatalf("Failed to get local checkpoint %v, please ensure the les API is exposed", err)
|
||||||
}
|
}
|
||||||
checkpoint = ¶ms.TrustedCheckpoint{
|
checkpoint = ¶ms.TrustedCheckpoint{
|
||||||
SectionIndex: uint64(index),
|
SectionIndex: uint64(index),
|
||||||
|
|
@ -116,7 +117,7 @@ func registerCheckpoint(ctx *cli.Context) error {
|
||||||
var result [4]string
|
var result [4]string
|
||||||
err := rpcClient.Call(&result, "les_latestCheckpoint")
|
err := rpcClient.Call(&result, "les_latestCheckpoint")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Failed to get local checkpoint %v", err)
|
utils.Fatalf("Failed to get local checkpoint %v, please ensure the les API is exposed", err)
|
||||||
}
|
}
|
||||||
index, err := strconv.ParseUint(result[0], 0, 64)
|
index, err := strconv.ParseUint(result[0], 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -132,12 +133,15 @@ func registerCheckpoint(ctx *cli.Context) error {
|
||||||
"chtroot", checkpoint.CHTRoot, "bloomroot", checkpoint.BloomRoot, "hash", checkpoint.Hash())
|
"chtroot", checkpoint.CHTRoot, "bloomroot", checkpoint.BloomRoot, "hash", checkpoint.Hash())
|
||||||
}
|
}
|
||||||
contract := setupContract(rpcClient)
|
contract := setupContract(rpcClient)
|
||||||
// Filter out stale checkpoint announcement
|
|
||||||
|
// Ensure the validness of the checkpoint.
|
||||||
latest, _, h, err := contract.Contract().GetLatestCheckpoint(nil)
|
latest, _, h, err := contract.Contract().GetLatestCheckpoint(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
head, err := ethclient.NewClient(rpcClient).HeaderByNumber(context.Background(), nil)
|
reqCtx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancelFn()
|
||||||
|
head, err := ethclient.NewClient(rpcClient).HeaderByNumber(reqCtx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +155,8 @@ func registerCheckpoint(ctx *cli.Context) error {
|
||||||
if checkpoint.SectionIndex == latest.Uint64() && (latest.Uint64() != 0 || h.Uint64() != 0) {
|
if checkpoint.SectionIndex == latest.Uint64() && (latest.Uint64() != 0 || h.Uint64() != 0) {
|
||||||
utils.Fatalf("Stale checkpoint, latest registered %d, given %d", latest.Uint64(), checkpoint.SectionIndex)
|
utils.Fatalf("Stale checkpoint, latest registered %d, given %d", latest.Uint64(), checkpoint.SectionIndex)
|
||||||
}
|
}
|
||||||
// Ensure the invoker is a trusted signer.
|
|
||||||
|
// Ensure the caller is a trusted signer.
|
||||||
signers, err := contract.Contract().GetAllAdmin(nil)
|
signers, err := contract.Contract().GetAllAdmin(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -166,8 +171,15 @@ func registerCheckpoint(ctx *cli.Context) error {
|
||||||
if !trusted {
|
if !trusted {
|
||||||
utils.Fatalf("Address %s is not a trusted signer", key.Address)
|
utils.Fatalf("Address %s is not a trusted signer", key.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch identity information
|
||||||
|
identity, err := ethclient.NewClient(rpcClient).HeaderByNumber(reqCtx, big.NewInt(int64(headNumber-128)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Register the checkpoint
|
// Register the checkpoint
|
||||||
tx, err := contract.SetCheckpoint(key.PrivateKey, big.NewInt(int64(checkpoint.SectionIndex)), checkpoint.Hash().Bytes())
|
tx, err := contract.SetCheckpoint(key.PrivateKey, big.NewInt(int64(checkpoint.SectionIndex)), checkpoint.Hash().Bytes(), identity.Number.Uint64(), identity.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -37,6 +37,14 @@ contract Registrar {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Check whether the vote truly belongs to local chain.
|
||||||
|
*/
|
||||||
|
modifier replayProtection(uint64 _number, bytes32 _hash) {
|
||||||
|
require(blockhash(_number) == _hash);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Events
|
Events
|
||||||
*/
|
*/
|
||||||
|
|
@ -81,6 +89,8 @@ contract Registrar {
|
||||||
*
|
*
|
||||||
* @param _sectionIndex section index
|
* @param _sectionIndex section index
|
||||||
* @param _hash checkpoint hash calculated in the client side
|
* @param _hash checkpoint hash calculated in the client side
|
||||||
|
* @param _identityNumber block number used to protect transaction replay.
|
||||||
|
* @param _identityHash corresponding block hash used to protect transaction replay.
|
||||||
* @param _sig admin's signature for checkpoint hash
|
* @param _sig admin's signature for checkpoint hash
|
||||||
* `checkpoint_hash = Hash(index, sectionHead, chtRoot, bloomRoot)`
|
* `checkpoint_hash = Hash(index, sectionHead, chtRoot, bloomRoot)`
|
||||||
* `_sig = Sign(privateKey, checkpoint_hash)`
|
* `_sig = Sign(privateKey, checkpoint_hash)`
|
||||||
|
|
@ -89,8 +99,11 @@ contract Registrar {
|
||||||
function SetCheckpoint(
|
function SetCheckpoint(
|
||||||
uint _sectionIndex,
|
uint _sectionIndex,
|
||||||
bytes32 _hash,
|
bytes32 _hash,
|
||||||
|
uint64 _identityNumber,
|
||||||
|
bytes32 _identityHash,
|
||||||
bytes memory _sig
|
bytes memory _sig
|
||||||
)
|
)
|
||||||
|
replayProtection(_identityNumber, _identityHash)
|
||||||
OnlyAuthorized
|
OnlyAuthorized
|
||||||
public
|
public
|
||||||
returns(bool)
|
returns(bool)
|
||||||
|
|
@ -234,7 +247,6 @@ contract Registrar {
|
||||||
address[] adminList;
|
address[] adminList;
|
||||||
|
|
||||||
// Latest stored section id
|
// Latest stored section id
|
||||||
// Note all registered checkpoint information should continuous with previous one.
|
|
||||||
uint sectionIndex;
|
uint sectionIndex;
|
||||||
|
|
||||||
// The block height associated with latest registered checkpoint.
|
// The block height associated with latest registered checkpoint.
|
||||||
|
|
|
||||||
|
|
@ -66,12 +66,12 @@ func (registrar *Registrar) LookupCheckpointEvent(blockLogs [][]*types.Log, sect
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCheckpoint creates a signature for given checkpoint with specified private key and registers into contract.
|
// SetCheckpoint creates a signature for given checkpoint with specified private key and registers into contract.
|
||||||
func (registrar *Registrar) SetCheckpoint(key *ecdsa.PrivateKey, sectionIndex *big.Int, hash []byte) (*types.Transaction, error) {
|
func (registrar *Registrar) SetCheckpoint(key *ecdsa.PrivateKey, sectionIndex *big.Int, hash []byte, identityNumber uint64, identityHash [32]byte) (*types.Transaction, error) {
|
||||||
sig, err := crypto.Sign(hash, key)
|
sig, err := crypto.Sign(hash, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var h [32]byte
|
var h [32]byte
|
||||||
copy(h[:], hash)
|
copy(h[:], hash)
|
||||||
return registrar.contract.SetCheckpoint(bind.NewKeyedTransactor(key), sectionIndex, h, sig)
|
return registrar.contract.SetCheckpoint(bind.NewKeyedTransactor(key), sectionIndex, h, identityNumber, identityHash, sig)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,9 +174,26 @@ func TestCheckpointRegister(t *testing.T) {
|
||||||
}
|
}
|
||||||
contractBackend.Commit()
|
contractBackend.Commit()
|
||||||
|
|
||||||
|
// getIdentity returns block height and hash of the head parent.
|
||||||
|
getIdentity := func() (uint64, common.Hash) {
|
||||||
|
parentNumber := contractBackend.Blockchain().CurrentHeader().Number.Uint64() - 1
|
||||||
|
parentHash := contractBackend.Blockchain().CurrentHeader().ParentHash
|
||||||
|
return parentNumber, parentHash
|
||||||
|
}
|
||||||
|
|
||||||
// Register unstable checkpoint
|
// Register unstable checkpoint
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
||||||
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
|
return assert(c, 0, nil, nil)
|
||||||
|
}, "register unstable checkpoint")
|
||||||
|
|
||||||
|
// Test transaction replay
|
||||||
|
validateOperation(t, c, contractBackend, func() {
|
||||||
|
number, hash := getIdentity()
|
||||||
|
hash = common.HexToHash("deadbeef")
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, nil, nil)
|
return assert(c, 0, nil, nil)
|
||||||
}, "register unstable checkpoint")
|
}, "register unstable checkpoint")
|
||||||
|
|
@ -185,51 +202,58 @@ func TestCheckpointRegister(t *testing.T) {
|
||||||
|
|
||||||
// Register by unauthorized user
|
// Register by unauthorized user
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
|
number, hash := getIdentity()
|
||||||
u, _ := crypto.GenerateKey()
|
u, _ := crypto.GenerateKey()
|
||||||
unauthorized := bind.NewKeyedTransactor(u)
|
unauthorized := bind.NewKeyedTransactor(u)
|
||||||
c.SetCheckpoint(unauthorized, big.NewInt(0), checkpoint0.Hash(), signCheckpoint(u, checkpoint0.Hash()))
|
c.SetCheckpoint(unauthorized, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(u, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, nil, nil)
|
return assert(c, 0, nil, nil)
|
||||||
}, "register by unauthorized user")
|
}, "register by unauthorized user")
|
||||||
|
|
||||||
// Submit a new checkpoint announcement
|
// Submit a new checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{checkpoint0.Hash()})
|
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{checkpoint0.Hash()})
|
||||||
}, "single checkpoint announcement")
|
}, "single checkpoint announcement")
|
||||||
|
|
||||||
// Submit a duplicate checkpoint announcement
|
// Submit a duplicate checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{checkpoint0.Hash()})
|
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{checkpoint0.Hash()})
|
||||||
}, "duplicate checkpoint announcement")
|
}, "duplicate checkpoint announcement")
|
||||||
|
|
||||||
// Modification
|
// Modification
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), common.HexToHash("deadbeef"), signCheckpoint(accounts[0].key, common.HexToHash("deadbeef")))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), common.HexToHash("deadbeef"), number, hash, signCheckpoint(accounts[0].key, common.HexToHash("deadbeef")))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{common.HexToHash("deadbeef")})
|
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{common.HexToHash("deadbeef")})
|
||||||
}, "checkpoint modification")
|
}, "checkpoint modification")
|
||||||
|
|
||||||
// Modification
|
// Modification
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), common.HexToHash("deadbeef2"), signCheckpoint(accounts[0].key, common.HexToHash("deadbeef2")))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), common.HexToHash("deadbeef2"), number, hash, signCheckpoint(accounts[0].key, common.HexToHash("deadbeef2")))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{common.HexToHash("deadbeef2")})
|
return assert(c, 0, []common.Address{accounts[0].addr}, []common.Hash{common.HexToHash("deadbeef2")})
|
||||||
}, "checkpoint modification")
|
}, "checkpoint modification")
|
||||||
|
|
||||||
// Another correct checkpoint announcement
|
// Another correct checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[1].key), big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[1].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[1].key), big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[1].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, []common.Address{accounts[0].addr, accounts[1].addr}, []common.Hash{common.HexToHash("deadbeef2"), checkpoint0.Hash()})
|
return assert(c, 0, []common.Address{accounts[0].addr, accounts[1].addr}, []common.Hash{common.HexToHash("deadbeef2"), checkpoint0.Hash()})
|
||||||
}, "another checkpoint announcement")
|
}, "another checkpoint announcement")
|
||||||
|
|
||||||
// enough checkpoint announcement
|
// enough checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[2].key), big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[2].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[2].key), big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[2].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
if valid, recv := validateEvents(1, events); !valid {
|
if valid, recv := validateEvents(1, events); !valid {
|
||||||
return errors.New("receive incorrect number of events")
|
return errors.New("receive incorrect number of events")
|
||||||
|
|
@ -249,14 +273,16 @@ func TestCheckpointRegister(t *testing.T) {
|
||||||
|
|
||||||
// submit a stale checkpoint announcement
|
// submit a stale checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(0), checkpoint0.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint0.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, nil, nil)
|
return assert(c, 0, nil, nil)
|
||||||
}, "submit stale checkpoint announcement")
|
}, "submit stale checkpoint announcement")
|
||||||
|
|
||||||
// submit a future checkpoint announcement
|
// submit a future checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(1), checkpoint1.Hash(), signCheckpoint(accounts[0].key, checkpoint1.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(1), checkpoint1.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint1.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, nil, nil)
|
return assert(c, 0, nil, nil)
|
||||||
}, "submit future checkpoint announcement")
|
}, "submit future checkpoint announcement")
|
||||||
|
|
@ -265,8 +291,9 @@ func TestCheckpointRegister(t *testing.T) {
|
||||||
distance := 3*sectionSize.Uint64() + processConfirms.Uint64() - contractBackend.Blockchain().CurrentHeader().Number.Uint64()
|
distance := 3*sectionSize.Uint64() + processConfirms.Uint64() - contractBackend.Blockchain().CurrentHeader().Number.Uint64()
|
||||||
contractBackend.InsertEmptyBlocks(int(distance))
|
contractBackend.InsertEmptyBlocks(int(distance))
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(2), checkpoint2.Hash(), signCheckpoint(accounts[0].key, checkpoint2.Hash()))
|
number, hash := getIdentity()
|
||||||
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[1].key), big.NewInt(2), checkpoint2.Hash(), signCheckpoint(accounts[1].key, checkpoint2.Hash()))
|
c.SetCheckpoint(transactOpts, big.NewInt(2), checkpoint2.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint2.Hash()))
|
||||||
|
c.SetCheckpoint(bind.NewKeyedTransactor(accounts[1].key), big.NewInt(2), checkpoint2.Hash(), number, hash, signCheckpoint(accounts[1].key, checkpoint2.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
if valid, recv := validateEvents(1, events); !valid {
|
if valid, recv := validateEvents(1, events); !valid {
|
||||||
return errors.New("receive incorrect number of events")
|
return errors.New("receive incorrect number of events")
|
||||||
|
|
@ -286,7 +313,8 @@ func TestCheckpointRegister(t *testing.T) {
|
||||||
|
|
||||||
// submit a stale checkpoint announcement
|
// submit a stale checkpoint announcement
|
||||||
validateOperation(t, c, contractBackend, func() {
|
validateOperation(t, c, contractBackend, func() {
|
||||||
c.SetCheckpoint(transactOpts, big.NewInt(2), checkpoint2.Hash(), signCheckpoint(accounts[0].key, checkpoint2.Hash()))
|
number, hash := getIdentity()
|
||||||
|
c.SetCheckpoint(transactOpts, big.NewInt(2), checkpoint2.Hash(), number, hash, signCheckpoint(accounts[0].key, checkpoint2.Hash()))
|
||||||
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
}, func(events <-chan *contract.ContractNewCheckpointEvent) error {
|
||||||
return assert(c, 0, nil, nil)
|
return assert(c, 0, nil, nil)
|
||||||
}, "submit stale checkpoint announcement")
|
}, "submit stale checkpoint announcement")
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,10 @@ func newTestProtocolManager(lightSync bool, blocks int, odr *LesOdr, indexers []
|
||||||
}
|
}
|
||||||
var reg *checkpointRegistrar
|
var reg *checkpointRegistrar
|
||||||
if indexers != nil {
|
if indexers != nil {
|
||||||
getLocal := func(index uint64) light.TrustedCheckpoint {
|
getLocal := func(index uint64) params.TrustedCheckpoint {
|
||||||
chtIndexer := indexers[0]
|
chtIndexer := indexers[0]
|
||||||
sectionHead := chtIndexer.SectionHead(index)
|
sectionHead := chtIndexer.SectionHead(index)
|
||||||
return light.TrustedCheckpoint{
|
return params.TrustedCheckpoint{
|
||||||
SectionIndex: index,
|
SectionIndex: index,
|
||||||
SectionHead: sectionHead,
|
SectionHead: sectionHead,
|
||||||
CHTRoot: light.GetChtRoot(db, index, sectionHead),
|
CHTRoot: light.GetChtRoot(db, index, sectionHead),
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/light"
|
"github.com/ethereum/go-ethereum/light"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCheckpointSyncingLes2(t *testing.T) { testCheckpointSyncing(t, 2) }
|
func TestCheckpointSyncingLes2(t *testing.T) { testCheckpointSyncing(t, 2) }
|
||||||
|
|
@ -49,13 +50,14 @@ func testCheckpointSyncing(t *testing.T, protocol int) {
|
||||||
chtRoot := light.GetChtRoot(server.db, 7, head)
|
chtRoot := light.GetChtRoot(server.db, 7, head)
|
||||||
btRoot := light.GetBloomTrieRoot(server.db, bts-1, head)
|
btRoot := light.GetBloomTrieRoot(server.db, bts-1, head)
|
||||||
|
|
||||||
cp := &light.TrustedCheckpoint{
|
cp := ¶ms.TrustedCheckpoint{
|
||||||
SectionIndex: 0,
|
SectionIndex: 0,
|
||||||
SectionHead: head,
|
SectionHead: head,
|
||||||
CHTRoot: chtRoot,
|
CHTRoot: chtRoot,
|
||||||
BloomRoot: btRoot,
|
BloomRoot: btRoot,
|
||||||
}
|
}
|
||||||
if _, err := server.pm.reg.contract.SetCheckpoint(signerKey, big.NewInt(int64(cp.SectionIndex)), cp.Hash().Bytes()); err != nil {
|
header := server.backend.Blockchain().CurrentHeader()
|
||||||
|
if _, err := server.pm.reg.contract.SetCheckpoint(signerKey, big.NewInt(int64(cp.SectionIndex)), cp.Hash().Bytes(), header.Number.Uint64(), header.Hash()); err != nil {
|
||||||
t.Error("register checkpoint failed", err)
|
t.Error("register checkpoint failed", err)
|
||||||
}
|
}
|
||||||
server.backend.Commit()
|
server.backend.Commit()
|
||||||
|
|
@ -63,7 +65,7 @@ func testCheckpointSyncing(t *testing.T, protocol int) {
|
||||||
|
|
||||||
// Wait for the checkpoint registration
|
// Wait for the checkpoint registration
|
||||||
for {
|
for {
|
||||||
hash, _, err := server.pm.reg.contract.Contract().GetCheckpoint(nil, big.NewInt(0))
|
_, hash, _, err := server.pm.reg.contract.Contract().GetLatestCheckpoint(nil)
|
||||||
if err != nil || hash == [32]byte{} {
|
if err != nil || hash == [32]byte{} {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue