mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
cmd, contracts, les: discard stale checkpoint
This commit is contained in:
parent
8d1972d793
commit
ad66858ac1
4 changed files with 39 additions and 94 deletions
|
|
@ -19,7 +19,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -46,7 +45,6 @@ var commandQueryCheckpoint = cli.Command{
|
||||||
Fetch the registered checkpoint with the specified index.
|
Fetch the registered checkpoint with the specified index.
|
||||||
`,
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
checkpointIndexFlag,
|
|
||||||
clientURLFlag,
|
clientURLFlag,
|
||||||
},
|
},
|
||||||
Action: utils.MigrateFlags(queryCheckpoint),
|
Action: utils.MigrateFlags(queryCheckpoint),
|
||||||
|
|
@ -84,20 +82,11 @@ func queryAdmin(ctx *cli.Context) error {
|
||||||
// registrar contract.
|
// registrar contract.
|
||||||
func queryCheckpoint(ctx *cli.Context) error {
|
func queryCheckpoint(ctx *cli.Context) error {
|
||||||
contract := setupContract(setupDialContext(ctx))
|
contract := setupContract(setupDialContext(ctx))
|
||||||
if ctx.GlobalIsSet(checkpointIndexFlag.Name) {
|
index, checkpoint, height, err := contract.Contract().GetLatestCheckpoint(nil)
|
||||||
index := ctx.GlobalInt64(checkpointIndexFlag.Name)
|
if err != nil {
|
||||||
checkpoint, height, err := contract.Contract().GetCheckpoint(nil, big.NewInt(index))
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("Checkpoint(registered at height #%d) %d => %s\n", height, index, common.Hash(checkpoint).Hex())
|
|
||||||
} else {
|
|
||||||
index, checkpoint, height, err := contract.Contract().GetLatestCheckpoint(nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("Latest checkpoint(registered at height #%d) %d => %s\n", height, index, common.Hash(checkpoint).Hex())
|
|
||||||
}
|
}
|
||||||
|
fmt.Printf("Latest checkpoint(registered at height #%d) %d => %s\n", height, index, common.Hash(checkpoint).Hex())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -68,22 +68,7 @@ contract Registrar {
|
||||||
view
|
view
|
||||||
public
|
public
|
||||||
returns(uint, bytes32, uint) {
|
returns(uint, bytes32, uint) {
|
||||||
(bytes32 hash, uint height) = GetCheckpoint(latest);
|
return (sectionIndex, hash, height);
|
||||||
return (latest, hash, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Get a stable checkpoint information with specified section index.
|
|
||||||
* @param _sectionIndex section index
|
|
||||||
* @return checkpoint hash
|
|
||||||
* @return the associated register block height
|
|
||||||
*/
|
|
||||||
function GetCheckpoint(uint _sectionIndex)
|
|
||||||
view
|
|
||||||
public
|
|
||||||
returns(bytes32, uint)
|
|
||||||
{
|
|
||||||
return (checkpoints[_sectionIndex], register_height[_sectionIndex]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -115,7 +100,7 @@ contract Registrar {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Filter out stale announcement
|
// Filter out stale announcement
|
||||||
if (_sectionIndex == latest && (latest != 0 || register_height[0] != 0)) {
|
if (_sectionIndex == sectionIndex && (sectionIndex != 0 || height != 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Filter out invalid announcement
|
// Filter out invalid announcement
|
||||||
|
|
@ -134,7 +119,15 @@ contract Registrar {
|
||||||
bool isNew = (old == "");
|
bool isNew = (old == "");
|
||||||
pending_proposal.usermap[msg.sender] = _hash;
|
pending_proposal.usermap[msg.sender] = _hash;
|
||||||
|
|
||||||
if (!isNew) {
|
if (isNew) {
|
||||||
|
// New checkpoint announcement
|
||||||
|
pending_proposal.count += 1;
|
||||||
|
pending_proposal.index = _sectionIndex;
|
||||||
|
pending_proposal.votemap[_hash].push(Vote({
|
||||||
|
addr: msg.sender,
|
||||||
|
sig: _sig
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
// Checkpoint modification
|
// Checkpoint modification
|
||||||
Vote[] storage votes = pending_proposal.votemap[old];
|
Vote[] storage votes = pending_proposal.votemap[old];
|
||||||
for (uint i = 0; i < votes.length - 1; i++) {
|
for (uint i = 0; i < votes.length - 1; i++) {
|
||||||
|
|
@ -149,21 +142,14 @@ contract Registrar {
|
||||||
addr: msg.sender,
|
addr: msg.sender,
|
||||||
sig: _sig
|
sig: _sig
|
||||||
}));
|
}));
|
||||||
} else {
|
|
||||||
// New checkpoint announcement
|
|
||||||
pending_proposal.count += 1;
|
|
||||||
pending_proposal.index = _sectionIndex;
|
|
||||||
pending_proposal.votemap[_hash].push(Vote({
|
|
||||||
addr: msg.sender,
|
|
||||||
sig: _sig
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
if (pending_proposal.votemap[_hash].length < threshold) {
|
if (pending_proposal.votemap[_hash].length < threshold) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
checkpoints[_sectionIndex] = _hash;
|
// Update latest checkpoint
|
||||||
register_height[_sectionIndex] = block.number;
|
hash = _hash;
|
||||||
latest = _sectionIndex;
|
height = block.number;
|
||||||
|
sectionIndex = _sectionIndex;
|
||||||
|
|
||||||
bytes memory sigs;
|
bytes memory sigs;
|
||||||
for (uint idx = 0; idx < threshold; idx++) {
|
for (uint idx = 0; idx < threshold; idx++) {
|
||||||
|
|
@ -243,15 +229,15 @@ contract Registrar {
|
||||||
// A list of admin users so that we can obtain all admin users.
|
// A list of admin users so that we can obtain all admin users.
|
||||||
address[] adminList;
|
address[] adminList;
|
||||||
|
|
||||||
// Registered checkpoint information
|
|
||||||
mapping(uint => bytes32) checkpoints;
|
|
||||||
|
|
||||||
// Latest stored section id
|
// Latest stored section id
|
||||||
// Note all registered checkpoint information should continuous with previous one.
|
// Note all registered checkpoint information should continuous with previous one.
|
||||||
uint latest;
|
uint sectionIndex;
|
||||||
|
|
||||||
// The block height associated with latest registered checkpoint.
|
// The block height associated with latest registered checkpoint.
|
||||||
mapping(uint => uint) register_height;
|
uint height;
|
||||||
|
|
||||||
|
// The hash of latest registered checkpoint.
|
||||||
|
bytes32 hash;
|
||||||
|
|
||||||
// The frequency for creating a checkpoint
|
// The frequency for creating a checkpoint
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
package les
|
package les
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
|
@ -87,21 +86,22 @@ func (reg *checkpointRegistrar) isRunning() bool {
|
||||||
// stableCheckpoint returns the stable checkpoint which generated by local indexers
|
// stableCheckpoint returns the stable checkpoint which generated by local indexers
|
||||||
// and announced by trusted signers.
|
// and announced by trusted signers.
|
||||||
func (reg *checkpointRegistrar) stableCheckpoint() (*params.TrustedCheckpoint, uint64) {
|
func (reg *checkpointRegistrar) stableCheckpoint() (*params.TrustedCheckpoint, uint64) {
|
||||||
latest, hash, _, err := reg.contract.Contract().GetLatestCheckpoint(nil)
|
latest, hash, height, err := reg.contract.Contract().GetLatestCheckpoint(nil)
|
||||||
|
// Short circuit if the checkpoint contract is empty.
|
||||||
if err != nil || latest.Uint64() == 0 && hash == [32]byte{} {
|
if err != nil || latest.Uint64() == 0 && hash == [32]byte{} {
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
index := latest.Uint64()
|
local := reg.getLocal(latest.Uint64())
|
||||||
for {
|
// The following scenarios may occur:
|
||||||
local := reg.getLocal(index)
|
//
|
||||||
hash, height, err := reg.contract.Contract().GetCheckpoint(nil, big.NewInt(int64(index)))
|
// * local node is out of sync so that it doesn't have the
|
||||||
if err == nil && local.HashEqual(common.Hash(hash)) {
|
// checkpoint which registered in the contract.
|
||||||
return &local, height.Uint64()
|
// * local checkpoint doesn't match with the registered one.
|
||||||
}
|
//
|
||||||
if index == 0 {
|
// In both cases, server won't send the **stable** checkpoint
|
||||||
break
|
// to the client(no worry, client can use hardcoded one instead).
|
||||||
}
|
if local.HashEqual(common.Hash(hash)) {
|
||||||
index -= 1
|
return &local, height.Uint64()
|
||||||
}
|
}
|
||||||
return nil, 0
|
return nil, 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue