Fix cross-shard verification during staking epoch change

pull/1878/head
Rongjian Lan 5 years ago
parent 61e613b492
commit 842ced116a
  1. 5
      core/rawdb/accessors_chain.go
  2. 2
      internal/chain/engine.go
  3. 11
      node/node.go
  4. 44
      node/node_newblock.go
  5. 6
      shard/shard_state.go
  6. 4
      test/deploy.sh

@ -32,6 +32,9 @@ import (
staking "github.com/harmony-one/harmony/staking/types"
)
// MsgNoShardStateFromDB error message for shard state reading failure
var MsgNoShardStateFromDB = "failed to read shard state from DB"
// Indicate whether the receipts corresponding to a blockHash is spent or not
const (
SpentByte byte = iota
@ -418,7 +421,7 @@ func ReadShardState(
var data []byte
data, err = db.Get(shardStateKey(epoch))
if err != nil {
return nil, ctxerror.New("cannot read sharding state from rawdb",
return nil, ctxerror.New(MsgNoShardStateFromDB,
"epoch", epoch,
).WithCause(err)
}

@ -293,7 +293,7 @@ func GetPublicKeys(chain engine.ChainReader, header *block.Header, reCalculate b
shardState, err = chain.ReadShardState(header.Epoch())
if err != nil {
return nil, ctxerror.New("failed to read shard state of epoch",
"epoch", header.Epoch().Uint64())
"epoch", header.Epoch().Uint64()).WithCause(err)
}
}

@ -211,17 +211,6 @@ type Node struct {
accountManager *accounts.Manager
// Next shard state
nextShardState struct {
// The received master shard state
master *shard.EpochShardState
// When for a leader to propose the next shard state,
// or for a validator to wait for a proposal before view change.
// TODO ek – replace with retry-based logic instead of delay
proposeTime time.Time
}
isFirstTime bool // the node was started with a fresh database
// How long in second the leader needs to wait to propose a new block.
BlockPeriod time.Duration

@ -2,14 +2,16 @@ package node
import (
"sort"
"strings"
"time"
"github.com/harmony-one/harmony/core/rawdb"
types2 "github.com/harmony-one/harmony/staking/types"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
)
// Constants of proposing a new block
@ -149,40 +151,6 @@ func (node *Node) proposeNewBlock() (*types.Block, error) {
return node.Worker.FinalizeNewBlock(sig, mask, node.Consensus.GetViewID(), coinbase, crossLinks, shardState)
}
// TODO is this still needed?
func (node *Node) proposeLocalShardState(block *types.Block) {
logger := block.Logger(utils.Logger())
// TODO ek – read this from beaconchain once BC sync is fixed
if node.nextShardState.master == nil {
logger.Debug().Msg("yet to receive master proposal from beaconchain")
return
}
nlogger := logger.With().
Uint64("nextEpoch", node.nextShardState.master.Epoch).
Time("proposeTime", node.nextShardState.proposeTime).
Logger()
logger = &nlogger
if time.Now().Before(node.nextShardState.proposeTime) {
logger.Debug().Msg("still waiting for shard state to propagate")
return
}
masterShardState := node.nextShardState.master.ShardState
var localShardState shard.State
committee := masterShardState.FindCommitteeByID(block.ShardID())
if committee != nil {
logger.Info().Msg("found local shard info; proposing it")
localShardState = append(localShardState, *committee)
} else {
logger.Info().Msg("beacon committee disowned us; proposing nothing")
// Leave local proposal empty to signal the end of shard (disbanding).
}
err := block.AddShardState(localShardState)
if err != nil {
logger.Error().Err(err).Msg("Failed proposin local shard state")
}
}
func (node *Node) proposeReceiptsProof() []*types.CXReceiptsProof {
if !node.Blockchain().Config().IsCrossTx(node.Worker.GetNewEpoch()) {
return []*types.CXReceiptsProof{}
@ -233,7 +201,11 @@ Loop:
}
if err := node.Blockchain().Validator().ValidateCXReceiptsProof(cxp); err != nil {
utils.Logger().Error().Err(err).Msg("[proposeReceiptsProof] Invalid CXReceiptsProof")
if strings.Contains(err.Error(), rawdb.MsgNoShardStateFromDB) {
pendingReceiptsList = append(pendingReceiptsList, cxp)
} else {
utils.Logger().Error().Err(err).Msg("[proposeReceiptsProof] Invalid CXReceiptsProof")
}
continue
}

@ -22,12 +22,6 @@ var (
// PublicKeySizeInBytes ..
const PublicKeySizeInBytes = 48
// EpochShardState is the shard state of an epoch
type EpochShardState struct {
Epoch uint64
ShardState State
}
// State is the collection of all committees
type State []Committee

@ -230,11 +230,11 @@ if [ "$DOTEST" == "true" ]; then
while [ $i -le $NUM_TEST ]; do
"${ROOT}/bin/wallet" -p local transfer --from $ACC1 --to $ACC3 --shardID 0 --toShardID 1 --amount 0.1 --pass pass:"" 2>&1 | tee -a "${LOG_FILE}"
"${ROOT}/bin/wallet" -p local transfer --from $ACC2 --to $ACC3 --shardID 1 --toShardID 0 --amount 0.1 --pass pass:"" 2>&1 | tee -a "${LOG_FILE}"
sleep 20
sleep 25
i=$((i+1))
done
echo "waiting for the result"
sleep 16
sleep 20
check_result
[ -e $RESULT_FILE ] && cat $RESULT_FILE
fi

Loading…
Cancel
Save