erigon-pulse/consensus/aura/aura.go
2022-12-05 18:48:08 +07:00

1758 lines
82 KiB
Go

// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package aura
import (
"bytes"
"container/list"
"encoding/json"
"fmt"
"math/big"
"sort"
"sync"
"time"
lru "github.com/hashicorp/golang-lru"
"github.com/holiman/uint256"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/accounts/abi"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/consensus"
"github.com/ledgerwatch/erigon/consensus/aura/aurainterfaces"
"github.com/ledgerwatch/erigon/consensus/aura/contracts"
"github.com/ledgerwatch/erigon/consensus/clique"
"github.com/ledgerwatch/erigon/consensus/ethash"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/secp256k1"
"go.uber.org/atomic"
)
const DEBUG_LOG_FROM = 999_999_999
/*
Not implemented features from OS:
- two_thirds_majority_transition - because no chains in OE where this is != MaxUint64 - means 1/2 majority used everywhere
- emptyStepsTransition - same
Repo with solidity sources: https://github.com/poanetwork/posdao-contracts
*/
type StepDurationInfo struct {
TransitionStep uint64
TransitionTimestamp uint64
StepDuration uint64
}
// EpochTransitionProof - Holds 2 proofs inside: ValidatorSetProof and FinalityProof
type EpochTransitionProof struct {
SignalNumber uint64
SetProof []byte
FinalityProof []byte
}
// ValidatorSetProof - validator set proof
type ValidatorSetProof struct {
Header *types.Header
Receipts types.Receipts
}
// FirstValidatorSetProof state-dependent proofs for the safe contract:
// only "first" proofs are such.
type FirstValidatorSetProof struct { // TODO: whaaat? here is no state!
ContractAddress common.Address
Header *types.Header
}
type EpochTransition struct {
/// Block hash at which the transition occurred.
BlockHash common.Hash
/// Block number at which the transition occurred.
BlockNumber uint64
/// "transition/epoch" proof from the engine combined with a finality proof.
ProofRlp []byte
}
type Step struct {
calibrate bool // whether calibration is enabled.
inner *atomic.Uint64
// Planned durations of steps.
durations []StepDurationInfo
}
func (s *Step) doCalibrate() {
if s.calibrate {
if !s.optCalibrate() {
ctr := s.inner.Load()
panic(fmt.Errorf("step counter under- or overflow: %d", ctr))
}
}
}
// optCalibrate Calibrates the AuRa step number according to the current time.
func (s *Step) optCalibrate() bool {
now := time.Now().Unix()
var info StepDurationInfo
i := 0
for _, d := range s.durations {
if d.TransitionTimestamp >= uint64(now) {
break
}
info = d
i++
}
if i == 0 {
panic("durations cannot be empty")
}
if uint64(now) < info.TransitionTimestamp {
return false
}
newStep := (uint64(now)-info.TransitionTimestamp)/info.StepDuration + info.TransitionStep
s.inner.Store(newStep)
return true
}
type PermissionedStep struct {
inner *Step
canPropose *atomic.Bool
}
type ReceivedStepHashes map[uint64]map[common.Address]common.Hash //BTreeMap<(u64, Address), H256>
// nolint
func (r ReceivedStepHashes) get(step uint64, author common.Address) (common.Hash, bool) {
res, ok := r[step]
if !ok {
return common.Hash{}, false
}
result, ok := res[author]
return result, ok
}
// nolint
func (r ReceivedStepHashes) insert(step uint64, author common.Address, blockHash common.Hash) {
res, ok := r[step]
if !ok {
res = map[common.Address]common.Hash{}
r[step] = res
}
res[author] = blockHash
}
// nolint
func (r ReceivedStepHashes) dropAncient(step uint64) {
for i := range r {
if i < step {
delete(r, i)
}
}
}
// nolint
type EpochManager struct {
epochTransitionHash common.Hash // H256,
epochTransitionNumber uint64 // BlockNumber
finalityChecker *RollingFinality
force bool
}
func NewEpochManager() *EpochManager {
return &EpochManager{
finalityChecker: NewRollingFinality([]common.Address{}),
force: true,
}
}
func (e *EpochManager) noteNewEpoch() { e.force = true }
// zoomValidators - Zooms to the epoch after the header with the given hash. Returns true if succeeded, false otherwise.
// It's analog of zoom_to_after function in OE, but doesn't require external locking
// nolint
func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, hash common.Hash, call consensus.SystemCall) (*RollingFinality, uint64, bool) {
var lastWasParent bool
if e.finalityChecker.lastPushed != nil {
lastWasParent = *e.finalityChecker.lastPushed == hash
}
// early exit for current target == chain head, but only if the epochs are
// the same.
if lastWasParent && !e.force {
return e.finalityChecker, e.epochTransitionNumber, true
}
e.force = false
// epoch_transition_for can be an expensive call, but in the absence of
// forks it will only need to be called for the block directly after
// epoch transition, in which case it will be O(1) and require a single
// DB lookup.
lastTransition, ok := epochTransitionFor2(chain, er, hash)
if !ok {
if lastTransition.BlockNumber > DEBUG_LOG_FROM {
fmt.Printf("zoom1: %d\n", lastTransition.BlockNumber)
}
return e.finalityChecker, e.epochTransitionNumber, false
}
// extract other epoch set if it's not the same as the last.
if lastTransition.BlockHash != e.epochTransitionHash {
proof := &EpochTransitionProof{}
if err := rlp.DecodeBytes(lastTransition.ProofRlp, proof); err != nil {
panic(err)
}
first := proof.SignalNumber == 0
if lastTransition.BlockNumber > DEBUG_LOG_FROM {
fmt.Printf("zoom2: %d,%d\n", lastTransition.BlockNumber, len(proof.SetProof))
}
// use signal number so multi-set first calculation is correct.
list, _, err := validators.epochSet(first, proof.SignalNumber, proof.SetProof, call)
if err != nil {
panic(fmt.Errorf("proof produced by this engine is invalid: %w", err))
}
epochSet := list.validators
log.Trace("[aura] Updating finality checker with new validator set extracted from epoch", "num", lastTransition.BlockNumber)
e.finalityChecker = NewRollingFinality(epochSet)
if proof.SignalNumber >= DEBUG_LOG_FROM {
fmt.Printf("new rolling finality: %d\n", proof.SignalNumber)
for i := 0; i < len(epochSet); i++ {
fmt.Printf("\t%x\n", epochSet[i])
}
}
}
e.epochTransitionHash = lastTransition.BlockHash
e.epochTransitionNumber = lastTransition.BlockNumber
return e.finalityChecker, e.epochTransitionNumber, true
}
// / Get the transition to the epoch the given parent hash is part of
// / or transitions to.
// / This will give the epoch that any children of this parent belong to.
// /
// / The block corresponding the the parent hash must be stored already.
// nolint
func epochTransitionFor2(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash common.Hash) (transition EpochTransition, ok bool) {
//TODO: probably this version of func doesn't support non-canonical epoch transitions
h := chain.GetHeaderByHash(parentHash)
if h == nil {
return transition, false
}
num, hash, transitionProof, err := e.FindBeforeOrEqualNumber(h.Number.Uint64())
if err != nil {
panic(err)
}
if transitionProof == nil {
panic("genesis epoch transition must already be set")
}
return EpochTransition{BlockNumber: num, BlockHash: hash, ProofRlp: transitionProof}, true
}
// nolint
func epochTransitionFor(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash common.Hash) (transition EpochTransition, ok bool) {
// slow path: loop back block by block
for {
h := chain.GetHeaderByHash(parentHash)
if h == nil {
return transition, false
}
// look for transition in database.
transitionProof, err := e.GetEpoch(h.Hash(), h.Number.Uint64())
if err != nil {
panic(err)
}
if transitionProof != nil {
return EpochTransition{
BlockNumber: h.Number.Uint64(),
BlockHash: h.Hash(),
ProofRlp: transitionProof,
}, true
}
// canonical hash -> fast breakout:
// get the last epoch transition up to this block.
//
// if `block_hash` is canonical it will only return transitions up to
// the parent.
canonical := chain.GetHeaderByNumber(h.Number.Uint64())
if canonical == nil {
return transition, false
}
//nolint
if canonical.Hash() == parentHash {
return EpochTransition{
BlockNumber: 0,
BlockHash: common.HexToHash("0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f"),
ProofRlp: params.SokolGenesisEpochProof,
}, true
/* TODO:
return self
.epoch_transitions()
.map(|(_, t)| t)
.take_while(|t| t.block_number <= details.number)
.last();
*/
}
parentHash = h.Hash()
}
}
// AuRa
// nolint
type AuRa struct {
db kv.RwDB // Database to store and retrieve snapshot checkpoints
exitCh chan struct{}
lock sync.RWMutex // Protects the signer fields
step PermissionedStep
// History of step hashes recently received from peers.
receivedStepHashes ReceivedStepHashes
OurSigningAddress common.Address // Same as Etherbase in Mining
cfg AuthorityRoundParams
EmptyStepsSet *EmptyStepSet
EpochManager *EpochManager // Mutex<EpochManager>,
certifier *common.Address // certifies service transactions
certifierLock sync.RWMutex
}
type GasLimitOverride struct {
cache *lru.Cache
}
func NewGasLimitOverride() *GasLimitOverride {
// The number of recent block hashes for which the gas limit override is memoized.
const GasLimitOverrideCacheCapacity = 10
cache, err := lru.New(GasLimitOverrideCacheCapacity)
if err != nil {
panic("error creating prefetching cache for blocks")
}
return &GasLimitOverride{cache: cache}
}
func (pb *GasLimitOverride) Pop(hash common.Hash) *uint256.Int {
if val, ok := pb.cache.Get(hash); ok && val != nil {
pb.cache.Remove(hash)
if v, ok := val.(*uint256.Int); ok {
return v
}
}
return nil
}
func (pb *GasLimitOverride) Add(hash common.Hash, b *uint256.Int) {
if b == nil {
return
}
pb.cache.ContainsOrAdd(hash, b)
}
func NewAuRa(config *params.AuRaConfig, db kv.RwDB, ourSigningAddress common.Address, engineParamsJson []byte) (*AuRa, error) {
spec := JsonSpec{}
err := json.Unmarshal(engineParamsJson, &spec)
if err != nil {
return nil, err
}
auraParams, err := FromJson(spec)
if err != nil {
return nil, err
}
if _, ok := auraParams.StepDurations[0]; !ok {
return nil, fmt.Errorf("authority Round step 0 duration is undefined")
}
for _, v := range auraParams.StepDurations {
if v == 0 {
return nil, fmt.Errorf("authority Round step duration cannot be 0")
}
}
//shouldTimeout := auraParams.StartStep == nil
initialStep := uint64(0)
if auraParams.StartStep != nil {
initialStep = *auraParams.StartStep
}
durations := make([]StepDurationInfo, 0, 1+len(auraParams.StepDurations))
durInfo := StepDurationInfo{
TransitionStep: 0,
TransitionTimestamp: 0,
StepDuration: auraParams.StepDurations[0],
}
durations = append(durations, durInfo)
times := common.SortedKeys(auraParams.StepDurations)
for i := 1; i < len(auraParams.StepDurations); i++ { // skip first
time := times[i]
dur := auraParams.StepDurations[time]
step, t, ok := nextStepTimeDuration(durInfo, time)
if !ok {
return nil, fmt.Errorf("timestamp overflow")
}
durInfo.TransitionStep = step
durInfo.TransitionTimestamp = t
durInfo.StepDuration = dur
durations = append(durations, durInfo)
}
step := &Step{
inner: atomic.NewUint64(initialStep),
calibrate: auraParams.StartStep == nil,
durations: durations,
}
step.doCalibrate()
/*
let engine = Arc::new(AuthorityRound {
epoch_manager: Mutex::new(EpochManager::blank()),
received_step_hashes: RwLock::new(Default::default()),
gas_limit_override_cache: Mutex::new(LruCache::new(GAS_LIMIT_OVERRIDE_CACHE_CAPACITY)),
})
// Do not initialize timeouts for tests.
if should_timeout {
let handler = TransitionHandler {
step: engine.step.clone(),
client: engine.client.clone(),
};
engine
.transition_service
.register_handler(Arc::new(handler))?;
}
*/
exitCh := make(chan struct{})
c := &AuRa{
db: db,
exitCh: exitCh,
step: PermissionedStep{inner: step, canPropose: atomic.NewBool(true)},
OurSigningAddress: ourSigningAddress,
cfg: auraParams,
receivedStepHashes: ReceivedStepHashes{},
EpochManager: NewEpochManager(),
}
_ = config
return c, nil
}
// A helper accumulator function mapping a step duration and a step duration transition timestamp
// to the corresponding step number and the correct starting second of the step.
func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, bool) {
stepDiff := time + info.StepDuration
if stepDiff < 1 {
return 0, 0, false
}
stepDiff -= 1
if stepDiff < info.TransitionTimestamp {
return 0, 0, false
}
stepDiff -= info.TransitionTimestamp
if info.StepDuration == 0 {
return 0, 0, false
}
stepDiff /= info.StepDuration
timeDiff := stepDiff * info.StepDuration
return info.TransitionStep + stepDiff, info.TransitionTimestamp + timeDiff, true
}
// Type returns underlying consensus engine
func (c *AuRa) Type() params.ConsensusType {
return params.AuRaConsensus
}
// Author implements consensus.Engine, returning the Ethereum address recovered
// from the signature in the header's extra-data section.
// This is thread-safe (only access the Coinbase of the header)
func (c *AuRa) Author(header *types.Header) (common.Address, error) {
/*
let message = keccak(empty_step_rlp(self.step, &self.parent_hash));
let public = publickey::recover(&self.signature.into(), &message)?;
Ok(publickey::public_to_address(&public))
*/
return header.Coinbase, nil
}
// VerifyHeader checks whether a header conforms to the consensus rules.
func (c *AuRa) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, _ bool) error {
number := header.Number.Uint64()
parent := chain.GetHeader(header.ParentHash, number-1)
if parent == nil {
log.Error("consensus.ErrUnknownAncestor", "parentNum", number-1, "hash", header.ParentHash.String())
return consensus.ErrUnknownAncestor
}
return ethash.VerifyHeaderBasics(chain, header, parent, false)
}
// nolint
func (c *AuRa) hasReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) bool {
/*
self
.received_step_hashes
.read()
.get(&received_step_key)
.map_or(false, |h| *h != new_hash)
*/
return false
}
// nolint
func (c *AuRa) insertReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) {
/*
self.received_step_hashes
.write()
.insert(received_step_key, new_hash);
*/
}
// nolint
func (c *AuRa) verifyFamily(chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, call consensus.Call, syscall consensus.SystemCall) error {
// TODO: I call it from Initialize - because looks like no much reason to have separated "verifyFamily" call
step := header.AuRaStep
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
parentStep := parent.AuRaStep
//nolint
validators, setNumber, err := c.epochSet(chain, e, header, syscall)
if err != nil {
return err
}
return nil
// TODO(yperbasis): re-enable the rest
// Ensure header is from the step after parent.
//nolint
if step == parentStep ||
(header.Number.Uint64() >= c.cfg.ValidateStepTransition && step <= parentStep) {
log.Trace("[aura] Multiple blocks proposed for step", "num", parentStep)
_ = setNumber
/*
self.validators.report_malicious(
header.author(),
set_number,
header.number(),
Default::default(),
);
Err(EngineError::DoubleVote(*header.author()))?;
*/
return fmt.Errorf("double vote: %x", header.Coinbase)
}
// Report malice if the validator produced other sibling blocks in the same step.
if !c.hasReceivedStepHashes(step, header.Coinbase, header.Hash()) {
/*
trace!(target: "engine", "Validator {} produced sibling blocks in the same step", header.author());
self.validators.report_malicious(
header.author(),
set_number,
header.number(),
Default::default(),
);
*/
} else {
c.insertReceivedStepHashes(step, header.Coinbase, header.Hash())
}
// Remove hash records older than two full rounds of steps (picked as a reasonable trade-off between
// memory consumption and fault-tolerance).
cnt, err := count(validators, parent.Hash(), call)
if err != nil {
return err
}
siblingMaliceDetectionPeriod := 2 * cnt
oldestStep := uint64(0) // let oldest_step = parent_step.saturating_sub(sibling_malice_detection_period);
if parentStep > siblingMaliceDetectionPeriod {
oldestStep = parentStep - siblingMaliceDetectionPeriod
}
//nolint
if oldestStep > 0 {
/*
let mut rsh = self.received_step_hashes.write();
let new_rsh = rsh.split_off(&(oldest_step, Address::zero()));
*rsh = new_rsh;
*/
}
emptyStepLen := uint64(0)
//self.report_skipped(header, step, parent_step, &*validators, set_number);
/*
// If empty step messages are enabled we will validate the messages in the seal, missing messages are not
// reported as there's no way to tell whether the empty step message was never sent or simply not included.
let empty_steps_len = if header.number() >= self.empty_steps_transition {
let validate_empty_steps = || -> Result<usize, Error> {
let strict_empty_steps = header.number() >= self.strict_empty_steps_transition;
let empty_steps = header_empty_steps(header)?;
let empty_steps_len = empty_steps.len();
let mut prev_empty_step = 0;
for empty_step in empty_steps {
if empty_step.step <= parent_step || empty_step.step >= step {
Err(EngineError::InsufficientProof(format!(
"empty step proof for invalid step: {:?}",
empty_step.step
)))?;
}
if empty_step.parent_hash != *header.parent_hash() {
Err(EngineError::InsufficientProof(format!(
"empty step proof for invalid parent hash: {:?}",
empty_step.parent_hash
)))?;
}
if !empty_step.verify(&*validators).unwrap_or(false) {
Err(EngineError::InsufficientProof(format!(
"invalid empty step proof: {:?}",
empty_step
)))?;
}
if strict_empty_steps {
if empty_step.step <= prev_empty_step {
Err(EngineError::InsufficientProof(format!(
"{} empty step: {:?}",
if empty_step.step == prev_empty_step {
"duplicate"
} else {
"unordered"
},
empty_step
)))?;
}
prev_empty_step = empty_step.step;
}
}
Ok(empty_steps_len)
};
match validate_empty_steps() {
Ok(len) => len,
Err(err) => {
trace!(
target: "engine",
"Reporting benign misbehaviour (cause: invalid empty steps) \
at block #{}, epoch set number {}. Own address: {}",
header.number(), set_number, self.address().unwrap_or_default()
);
self.validators
.report_benign(header.author(), set_number, header.number());
return Err(err);
}
}
} else {
self.report_skipped(header, step, parent_step, &*validators, set_number);
0
};
*/
if header.Number.Uint64() >= c.cfg.ValidateScoreTransition {
expectedDifficulty := calculateScore(parentStep, step, emptyStepLen)
if header.Difficulty.Cmp(expectedDifficulty.ToBig()) != 0 {
return fmt.Errorf("invlid difficulty: expect=%s, found=%s\n", expectedDifficulty, header.Difficulty)
}
}
return nil
}
// VerifyUncles implements consensus.Engine, always returning an error for any
// uncles as this consensus mechanism doesn't permit uncles.
func (c *AuRa) VerifyUncles(chain consensus.ChainReader, header *types.Header, uncles []*types.Header) error {
return nil
//if len(uncles) > 0 {
// return errors.New("uncles not allowed")
//}
//return nil
}
// VerifySeal implements consensus.Engine, checking whether the signature contained
// in the header satisfies the consensus protocol requirements.
func (c *AuRa) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error {
return nil
//snap, err := c.Snapshot(chain, header.Number.Uint64(), header.Hash(), nil)
//if err != nil {
// return err
//}
//return c.verifySeal(chain, header, snap)
}
// Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top.
func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState) error {
return nil
/// If the block isn't a checkpoint, cast a random vote (good enough for now)
//header.Coinbase = common.Address{}
//header.Nonce = types.BlockNonce{}
//
//number := header.Number.Uint64()
/// Assemble the voting snapshot to check which votes make sense
//snap, err := c.Snapshot(chain, number-1, header.ParentHash, nil)
//if err != nil {
// return err
//}
//if number%c.config.Epoch != 0 {
// c.lock.RLock()
//
// // Gather all the proposals that make sense voting on
// addresses := make([]common.Address, 0, len(c.proposals))
// for address, authorize := range c.proposals {
// if snap.validVote(address, authorize) {
// addresses = append(addresses, address)
// }
// }
// // If there's pending proposals, cast a vote on them
// if len(addresses) > 0 {
// header.Coinbase = addresses[rand.Intn(len(addresses))]
// if c.proposals[header.Coinbase] {
// copy(header.Nonce[:], NonceAuthVote)
// } else {
// copy(header.Nonce[:], nonceDropVote)
// }
// }
// c.lock.RUnlock()
//}
/// Set the correct difficulty
//header.Difficulty = calcDifficulty(snap, c.signer)
//
/// Ensure the extra data has all its components
//if len(header.Extra) < ExtraVanity {
// header.Extra = append(header.Extra, bytes.Repeat([]byte{0x00}, ExtraVanity-len(header.Extra))...)
//}
//header.Extra = header.Extra[:ExtraVanity]
//
//if number%c.config.Epoch == 0 {
// for _, signer := range snap.GetSigners() {
// header.Extra = append(header.Extra, signer[:]...)
// }
//}
//header.Extra = append(header.Extra, make([]byte, ExtraSeal)...)
//
/// Mix digest is reserved for now, set to empty
//header.MixDigest = common.Hash{}
//
/// Ensure the timestamp has the correct delay
//parent := chain.GetHeader(header.ParentHash, number-1)
//if parent == nil {
// return consensus.ErrUnknownAncestor
//}
//header.Time = parent.Time + c.config.Period
//
//now := uint64(time.Now().Unix())
//if header.Time < now {
// header.Time = now
//}
//
//return nil
}
func (c *AuRa) Initialize(config *params.ChainConfig, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header,
state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall,
) {
blockNum := header.Number.Uint64()
for address, rewrittenCode := range c.cfg.RewriteBytecode[blockNum] {
state.SetCode(address, rewrittenCode)
}
c.certifierLock.Lock()
if c.cfg.Registrar != nil && c.certifier == nil && config.IsLondon(blockNum) {
c.certifier = getCertifier(*c.cfg.Registrar, syscall)
}
c.certifierLock.Unlock()
if blockNum == 1 {
proof, err := c.GenesisEpochData(header, syscall)
if err != nil {
panic(err)
}
err = e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators
if err != nil {
panic(err)
}
}
//if err := c.verifyFamily(chain, e, header, call, syscall); err != nil { //TODO: OE has it as a separate engine call? why?
// panic(err)
//}
// check_and_lock_block -> check_epoch_end_signal
epoch, err := e.GetEpoch(header.ParentHash, blockNum-1)
if err != nil {
log.Warn("[aura] initialize block: on epoch begin", "err", err)
return
}
isEpochBegin := epoch != nil
if !isEpochBegin {
return
}
err = c.cfg.Validators.onEpochBegin(isEpochBegin, header, syscall)
if err != nil {
log.Warn("[aura] initialize block: on epoch begin", "err", err)
return
}
// check_and_lock_block -> check_epoch_end_signal END (before enact)
}
// word `signal epoch` == word `pending epoch`
func (c *AuRa) Finalize(config *params.ChainConfig, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal,
e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall,
) (types.Transactions, types.Receipts, error) {
// accumulateRewards retrieves rewards for a block and applies them to the coinbase accounts for miner and uncle miners
beneficiaries, _, rewards, err := AccumulateRewards(config, c, header, uncles, syscall)
if err != nil {
return nil, nil, fmt.Errorf("buildAncestrySubChain: %w", err)
}
for i := range beneficiaries {
//fmt.Printf("beneficiary: n=%d, %x,%d\n", header.Number.Uint64(), beneficiaries[i], rewards[i])
state.AddBalance(beneficiaries[i], rewards[i])
}
// check_and_lock_block -> check_epoch_end_signal (after enact)
if header.Number.Uint64() >= DEBUG_LOG_FROM {
fmt.Printf("finalize1: %d,%d\n", header.Number.Uint64(), len(receipts))
}
pendingTransitionProof, err := c.cfg.Validators.signalEpochEnd(header.Number.Uint64() == 0, header, receipts)
if err != nil {
return nil, nil, err
}
if pendingTransitionProof != nil {
if header.Number.Uint64() >= DEBUG_LOG_FROM {
fmt.Printf("insert_pending_trancition: %d,receipts=%d, lenProof=%d\n", header.Number.Uint64(), len(receipts), len(pendingTransitionProof))
}
if err = e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil {
return nil, nil, err
}
}
// check_and_lock_block -> check_epoch_end_signal END
finalized := buildFinality(c.EpochManager, chain, e, c.cfg.Validators, header, syscall)
c.EpochManager.finalityChecker.print(header.Number.Uint64())
epochEndProof, err := isEpochEnd(chain, e, finalized, header)
if err != nil {
return nil, nil, err
}
if epochEndProof != nil {
c.EpochManager.noteNewEpoch()
log.Info("[aura] epoch transition", "block_num", header.Number.Uint64())
if err := e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil {
return nil, nil, err
}
}
return txs, receipts, nil
}
func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, header *types.Header, syscall consensus.SystemCall) []unAssembledHeader {
// commit_block -> aura.build_finality
_, _, ok := e.zoomToAfter(chain, er, validators, header.ParentHash, syscall)
if !ok {
return []unAssembledHeader{}
}
if e.finalityChecker.lastPushed == nil || *e.finalityChecker.lastPushed != header.ParentHash {
if err := e.finalityChecker.buildAncestrySubChain(func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool) {
h := chain.GetHeaderByHash(hash)
if h == nil {
return nil, common.Hash{}, common.Hash{}, 0, false
}
return []common.Address{h.Coinbase}, h.Hash(), h.ParentHash, h.Number.Uint64(), true
}, header.ParentHash, e.epochTransitionHash); err != nil {
//log.Warn("[aura] buildAncestrySubChain", "err", err)
return []unAssembledHeader{}
}
}
res, err := e.finalityChecker.push(header.Hash(), header.Number.Uint64(), []common.Address{header.Coinbase})
if err != nil {
//log.Warn("[aura] finalityChecker.push", "err", err)
return []unAssembledHeader{}
}
return res
}
func isEpochEnd(chain consensus.ChainHeaderReader, e consensus.EpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) {
// commit_block -> aura.is_epoch_end
for i := range finalized {
pendingTransitionProof, err := e.GetPendingEpoch(finalized[i].hash, finalized[i].number)
if err != nil {
return nil, err
}
if pendingTransitionProof == nil {
continue
}
if header.Number.Uint64() >= DEBUG_LOG_FROM {
fmt.Printf("pending transition: %d,%x,len=%d\n", finalized[i].number, finalized[i].hash, len(pendingTransitionProof))
}
finalityProof := allHeadersUntil(chain, header, finalized[i].hash)
var finalizedHeader *types.Header
if finalized[i].hash == header.Hash() {
finalizedHeader = header
} else {
finalizedHeader = chain.GetHeader(finalized[i].hash, finalized[i].number)
}
signalNumber := finalizedHeader.Number
finalityProof = append(finalityProof, finalizedHeader)
for i, j := 0, len(finalityProof)-1; i < j; i, j = i+1, j-1 { // reverse
finalityProof[i], finalityProof[j] = finalityProof[j], finalityProof[i]
}
finalityProofRLP, err := rlp.EncodeToBytes(finalityProof)
if err != nil {
return nil, err
}
/*
// We turn off can_propose here because upon validator set change there can
// be two valid proposers for a single step: one from the old set and
// one from the new.
//
// This way, upon encountering an epoch change, the proposer from the
// new set will be forced to wait until the next step to avoid sealing a
// block that breaks the invariant that the parent's step < the block's step.
self.step.can_propose.store(false, AtomicOrdering::SeqCst);
*/
return rlp.EncodeToBytes(EpochTransitionProof{SignalNumber: signalNumber.Uint64(), SetProof: pendingTransitionProof, FinalityProof: finalityProofRLP})
}
return nil, nil
}
// allHeadersUntil walk the chain backwards from current head until finalized_hash
// to construct transition proof. author == ec_recover(sig) known
// since the blocks are in the DB.
func allHeadersUntil(chain consensus.ChainHeaderReader, from *types.Header, to common.Hash) (out []*types.Header) {
var header = from
for {
header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
if header == nil {
panic("not found header")
}
if header.Number.Uint64() == 0 {
break
}
if to == header.Hash() {
break
}
out = append(out, header)
}
return out
}
//func (c *AuRa) check_epoch_end(cc *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
//}
// FinalizeAndAssemble implements consensus.Engine
func (c *AuRa) FinalizeAndAssemble(chainConfig *params.ChainConfig, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal,
e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call,
) (*types.Block, types.Transactions, types.Receipts, error) {
outTxs, outReceipts, err := c.Finalize(chainConfig, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall)
if err != nil {
return nil, nil, nil, err
}
// Assemble and return the final block for sealing
return types.NewBlock(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, nil
}
// Authorize injects a private key into the consensus engine to mint new blocks
// with.
func (c *AuRa) Authorize(signer common.Address, signFn clique.SignerFn) {
c.lock.Lock()
defer c.lock.Unlock()
//c.signer = signer
//c.signFn = signFn
}
func (c *AuRa) GenesisEpochData(header *types.Header, caller consensus.SystemCall) ([]byte, error) {
setProof, err := c.cfg.Validators.genesisEpochData(header, caller)
if err != nil {
return nil, err
}
res, err := rlp.EncodeToBytes(EpochTransitionProof{SignalNumber: 0, SetProof: setProof, FinalityProof: []byte{}})
if err != nil {
panic(err)
}
//fmt.Printf("reere: %x\n", res)
//f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
//f91a8c80b91a87f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acaa3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01b853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47080
return res, nil
}
func (c *AuRa) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
return nil
//header := block.Header()
//
/// Sealing the genesis block is not supported
//number := header.Number.Uint64()
//if number == 0 {
// return errUnknownBlock
//}
/// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
//if c.config.Period == 0 && len(block.Transactions()) == 0 {
// log.Info("Sealing paused, waiting for transactions")
// return nil
//}
/// Don't hold the signer fields for the entire sealing procedure
//c.lock.RLock()
//signer, signFn := c.signer, c.signFn
//c.lock.RUnlock()
//
/// Bail out if we're unauthorized to sign a block
//snap, err := c.Snapshot(chain, number-1, header.ParentHash, nil)
//if err != nil {
// return err
//}
//if _, authorized := snap.Signers[signer]; !authorized {
// return ErrUnauthorizedSigner
//}
/// If we're amongst the recent signers, wait for the next block
//for seen, recent := range snap.Recents {
// if recent == signer {
// // Signer is among RecentsRLP, only wait if the current block doesn't shift it out
// if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit {
// log.Info("Signed recently, must wait for others")
// return nil
// }
// }
//}
/// Sweet, the protocol permits us to sign the block, wait for our time
//delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple
//if header.Difficulty.Cmp(diffNoTurn) == 0 {
// // It's not our turn explicitly to sign, delay it a bit
// wiggle := time.Duration(len(snap.Signers)/2+1) * wiggleTime
// delay += time.Duration(rand.Int63n(int64(wiggle)))
//
// log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
//}
/// Sign all the things!
//sighash, err := signFn(signer, accounts.MimetypeClique, CliqueRLP(header))
//if err != nil {
// return err
//}
//copy(header.Extra[len(header.Extra)-ExtraSeal:], sighash)
/// Wait until sealing is terminated or delay timeout.
//log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
//go func() {
// select {
// case <-stop:
// return
// case <-time.After(delay):
// }
//
// select {
// case results <- block.WithSeal(header):
// default:
// log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header))
// }
//}()
//
//return nil
}
func stepProposer(validators ValidatorSet, blockHash common.Hash, step uint64, call consensus.Call) (common.Address, error) {
//c, err := validators.defaultCaller(blockHash)
//if err != nil {
// return common.Address{}, err
//}
return validators.getWithCaller(blockHash, uint(step), call)
}
// GenerateSeal - Attempt to seal the block internally.
//
// This operation is synchronous and may (quite reasonably) not be available, in which case
// `Seal::None` will be returned.
func (c *AuRa) GenerateSeal(chain consensus.ChainHeaderReader, current, parent *types.Header, call consensus.Call) []byte {
// first check to avoid generating signature most of the time
// (but there's still a race to the `compare_exchange`)
if !c.step.canPropose.Load() {
log.Trace("[aura] Aborting seal generation. Can't propose.")
return nil
}
parentStep := parent.AuRaStep
step := c.step.inner.inner.Load()
// filter messages from old and future steps and different parents
expectedDiff := calculateScore(parentStep, step, 0)
if current.Difficulty.Cmp(expectedDiff.ToBig()) != 0 {
log.Trace(fmt.Sprintf("[aura] Aborting seal generation. The step or empty_steps have changed in the meantime. %d != %d", current.Difficulty, expectedDiff))
return nil
}
if parentStep > step {
log.Warn(fmt.Sprintf("[aura] Aborting seal generation for invalid step: %d > %d", parentStep, step))
return nil
}
validators, setNumber, err := c.epochSet(chain, nil, current, nil)
if err != nil {
log.Warn("[aura] Unable to generate seal", "err", err)
return nil
}
stepProposerAddr, err := stepProposer(validators, current.ParentHash, step, call)
if err != nil {
log.Warn("[aura] Unable to get stepProposer", "err", err)
return nil
}
if stepProposerAddr != current.Coinbase {
return nil
}
// this is guarded against by `can_propose` unless the block was signed
// on the same step (implies same key) and on a different node.
if parentStep == step {
log.Warn("Attempted to seal block on the same step as parent. Is this authority sealing with more than one node?")
return nil
}
// TODO(yperbasis) re-enable the rest
_ = setNumber
/*
signature, err := c.sign(current.bareHash())
if err != nil {
log.Warn("[aura] generate_seal: FAIL: Accounts secret key unavailable.", "err", err)
return nil
}
*/
/*
// only issue the seal if we were the first to reach the compare_exchange.
if self
.step
.can_propose
.compare_exchange(true, false, AtomicOrdering::SeqCst, AtomicOrdering::SeqCst)
.is_ok()
{
// we can drop all accumulated empty step messages that are
// older than the parent step since we're including them in
// the seal
self.clear_empty_steps(parent_step);
// report any skipped primaries between the parent block and
// the block we're sealing, unless we have empty steps enabled
if header.number() < self.empty_steps_transition {
self.report_skipped(header, step, parent_step, &*validators, set_number);
}
let mut fields =
vec![encode(&step), encode(&(H520::from(signature).as_bytes()))];
if let Some(empty_steps_rlp) = empty_steps_rlp {
fields.push(empty_steps_rlp);
}
return Seal::Regular(fields);
}
*/
return nil
}
// epochSet fetch correct validator set for epoch at header, taking into account
// finality of previous transitions.
func (c *AuRa) epochSet(chain consensus.ChainHeaderReader, e consensus.EpochReader, h *types.Header, call consensus.SystemCall) (ValidatorSet, uint64, error) {
if c.cfg.ImmediateTransitions {
return c.cfg.Validators, h.Number.Uint64(), nil
}
finalityChecker, epochTransitionNumber, ok := c.EpochManager.zoomToAfter(chain, e, c.cfg.Validators, h.ParentHash, call)
if !ok {
return nil, 0, fmt.Errorf("unable to zoomToAfter to epoch")
}
return finalityChecker.signers, epochTransitionNumber, nil
}
func (c *AuRa) CalcDifficulty(chain consensus.ChainHeaderReader, time, parentTime uint64, parentDifficulty *big.Int, parentNumber uint64, parentHash, parentUncleHash common.Hash, parentStep uint64) *big.Int {
currentStep := c.step.inner.inner.Load()
currentEmptyStepsLen := 0
return calculateScore(parentStep, currentStep, uint64(currentEmptyStepsLen)).ToBig()
/* TODO: do I need gasLimit override logic here ?
if let Some(gas_limit) = self.gas_limit_override(header) {
trace!(target: "engine", "Setting gas limit to {} for block {}.", gas_limit, header.number());
let parent_gas_limit = *parent.gas_limit();
header.set_gas_limit(gas_limit);
if parent_gas_limit != gas_limit {
info!(target: "engine", "Block gas limit was changed from {} to {}.", parent_gas_limit, gas_limit);
}
}
*/
}
// calculateScore - analog of PoW difficulty:
//
// sqrt(U256::max_value()) + parent_step - current_step + current_empty_steps
func calculateScore(parentStep, currentStep, currentEmptySteps uint64) *uint256.Int {
maxU128 := uint256.NewInt(0).SetAllOne()
maxU128 = maxU128.Rsh(maxU128, 128)
res := maxU128.Add(maxU128, uint256.NewInt(parentStep))
res = res.Sub(res, uint256.NewInt(currentStep))
res = res.Add(res, uint256.NewInt(currentEmptySteps))
return res
}
func (c *AuRa) SealHash(header *types.Header) common.Hash {
return clique.SealHash(header)
}
// See https://openethereum.github.io/Permissioning.html#gas-price
// This is thread-safe: it only accesses the `certifier` which is used behind a RWLock
func (c *AuRa) IsServiceTransaction(sender common.Address, syscall consensus.SystemCall) bool {
c.certifierLock.RLock()
defer c.certifierLock.RUnlock()
if c.certifier == nil {
return false
}
packed, err := certifierAbi().Pack("certified", sender)
if err != nil {
panic(err)
}
out, err := syscall(*c.certifier, packed)
if err != nil {
panic(err)
}
res, err := certifierAbi().Unpack("certified", out)
if err != nil {
panic(err)
}
certified := res[0].(bool)
return certified
}
// Close implements consensus.Engine. It's a noop for clique as there are no background threads.
func (c *AuRa) Close() error {
libcommon.SafeClose(c.exitCh)
return nil
}
// APIs implements consensus.Engine, returning the user facing RPC API to allow
// controlling the signer voting.
func (c *AuRa) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return []rpc.API{
//{
//Namespace: "clique",
//Version: "1.0",
//Service: &API{chain: chain, clique: c},
//Public: false,
//}
}
}
// nolint
func (c *AuRa) emptySteps(fromStep, toStep uint64, parentHash common.Hash) []EmptyStep {
from := EmptyStep{step: fromStep + 1, parentHash: parentHash}
to := EmptyStep{step: toStep}
res := []EmptyStep{}
if to.LessOrEqual(&from) {
return res
}
c.EmptyStepsSet.Sort()
c.EmptyStepsSet.ForEach(func(i int, step *EmptyStep) {
if step.Less(&from) || (&to).Less(step) {
return
}
if step.parentHash != parentHash {
return
}
res = append(res, *step)
})
return res
}
// AccumulateRewards returns rewards for a given block. The mining reward consists
// of the static blockReward plus a reward for each included uncle (if any). Individual
// uncle rewards are also returned in an array.
func AccumulateRewards(_ *params.ChainConfig, aura *AuRa, header *types.Header, _ []*types.Header, syscall consensus.SystemCall) (beneficiaries []common.Address, rewardKind []aurainterfaces.RewardKind, rewards []*uint256.Int, err error) {
beneficiaries = append(beneficiaries, header.Coinbase)
rewardKind = append(rewardKind, aurainterfaces.RewardAuthor)
var rewardContractAddress BlockRewardContract
var foundContract bool
for _, c := range aura.cfg.BlockRewardContractTransitions {
if c.blockNum > header.Number.Uint64() {
break
}
foundContract = true
rewardContractAddress = c
}
if foundContract {
beneficiaries, rewards = callBlockRewardAbi(rewardContractAddress.address, syscall, beneficiaries, rewardKind)
rewardKind = make([]aurainterfaces.RewardKind, len(beneficiaries))
for i := 0; i < len(rewardKind); i++ {
rewardKind[i] = aurainterfaces.RewardExternal
}
} else {
// block_reward.iter.rev().find(|&(block, _)| *block <= number)
var reward BlockReward
var found bool
for i := range aura.cfg.BlockReward {
if aura.cfg.BlockReward[i].blockNum > header.Number.Uint64() {
break
}
found = true
reward = aura.cfg.BlockReward[i]
}
if !found {
panic("Current block's reward is not found; this indicates a chain config error")
}
for range beneficiaries {
rewards = append(rewards, reward.amount)
}
}
//err = aura.cfg.Validators.onCloseBlock(header, aura.OurSigningAddress)
//if err != nil {
// return
//}
return
}
func callBlockRewardAbi(contractAddr common.Address, syscall consensus.SystemCall, beneficiaries []common.Address, rewardKind []aurainterfaces.RewardKind) ([]common.Address, []*uint256.Int) {
castedKind := make([]uint16, len(rewardKind))
for i := range rewardKind {
castedKind[i] = uint16(rewardKind[i])
}
packed, err := blockRewardAbi().Pack("reward", beneficiaries, castedKind)
if err != nil {
panic(err)
}
out, err := syscall(contractAddr, packed)
if err != nil {
panic(err)
}
if len(out) == 0 {
return nil, nil
}
res, err := blockRewardAbi().Unpack("reward", out)
if err != nil {
panic(err)
}
beneficiariesRes := res[0].([]common.Address)
rewardsBig := res[1].([]*big.Int)
rewardsU256 := make([]*uint256.Int, len(rewardsBig))
for i := 0; i < len(rewardsBig); i++ {
var overflow bool
rewardsU256[i], overflow = uint256.FromBig(rewardsBig[i])
if overflow {
panic("Overflow in callBlockRewardAbi")
}
}
return beneficiariesRes, rewardsU256
}
func blockRewardAbi() abi.ABI {
a, err := abi.JSON(bytes.NewReader(contracts.BlockReward))
if err != nil {
panic(err)
}
return a
}
func certifierAbi() abi.ABI {
a, err := abi.JSON(bytes.NewReader(contracts.Certifier))
if err != nil {
panic(err)
}
return a
}
func registrarAbi() abi.ABI {
a, err := abi.JSON(bytes.NewReader(contracts.Registrar))
if err != nil {
panic(err)
}
return a
}
func getCertifier(registrar common.Address, syscall consensus.SystemCall) *common.Address {
hashedKey, err := common.HashData([]byte("service_transaction_checker"))
if err != nil {
panic(err)
}
packed, err := registrarAbi().Pack("getAddress", hashedKey, "A")
if err != nil {
panic(err)
}
out, err := syscall(registrar, packed)
if err != nil {
panic(err)
}
if len(out) == 0 {
return nil
}
res, err := registrarAbi().Unpack("getAddress", out)
if err != nil {
panic(err)
}
certifier := res[0].(common.Address)
return &certifier
}
// An empty step message that is included in a seal, the only difference is that it doesn't include
// the `parent_hash` in order to save space. The included signature is of the original empty step
// message, which can be reconstructed by using the parent hash of the block in which this sealed
// empty message is included.
// nolint
type SealedEmptyStep struct {
signature []byte // H520
step uint64
}
/*
// extracts the empty steps from the header seal. should only be called when there are 3 fields in the seal
// (i.e. header.number() >= self.empty_steps_transition).
func headerEmptySteps(header *types.Header) ([]EmptyStep, error) {
s := headerEmptyStepsRaw(header)
sealedSteps := []SealedEmptyStep{}
err := rlp.DecodeBytes(s, &sealedSteps)
if err != nil {
return nil, err
}
steps := make([]EmptyStep, len(sealedSteps))
for i := range sealedSteps {
steps[i] = newEmptyStepFromSealed(sealedSteps[i], header.ParentHash)
}
return steps, nil
}
func newEmptyStepFromSealed(step SealedEmptyStep, parentHash common.Hash) EmptyStep {
return EmptyStep{
signature: step.signature,
step: step.step,
parentHash: parentHash,
}
}
// extracts the raw empty steps vec from the header seal. should only be called when there are 3 fields in the seal
// (i.e. header.number() >= self.empty_steps_transition)
func headerEmptyStepsRaw(header *types.Header) []byte {
if len(header.Seal) < 3 {
panic("was checked with verify_block_basic; has 3 fields; qed")
}
return header.Seal[2]
}
*/
// A message broadcast by authorities when it's their turn to seal a block but there are no
// transactions. Other authorities accumulate these messages and later include them in the seal as
// proof.
//
// An empty step message is created _instead of_ a block if there are no pending transactions.
// It cannot itself be a parent, and `parent_hash` always points to the most recent block. E.g.:
// - Validator A creates block `bA`.
// - Validator B has no pending transactions, so it signs an empty step message `mB`
// instead whose hash points to block `bA`.
// - Validator C also has no pending transactions, so it also signs an empty step message `mC`
// instead whose hash points to block `bA`.
// - Validator D creates block `bD`. The parent is block `bA`, and the header includes `mB` and `mC`.
type EmptyStep struct {
// The signature of the other two fields, by the message's author.
signature []byte // H520
// This message's step number.
step uint64
// The hash of the most recent block.
parentHash common.Hash // H256
}
func (s *EmptyStep) Less(other *EmptyStep) bool {
if s.step < other.step {
return true
}
if bytes.Compare(s.parentHash[:], other.parentHash[:]) < 0 {
return true
}
if bytes.Compare(s.signature, other.signature) < 0 {
return true
}
return false
}
func (s *EmptyStep) LessOrEqual(other *EmptyStep) bool {
if s.step <= other.step {
return true
}
if bytes.Compare(s.parentHash[:], other.parentHash[:]) <= 0 {
return true
}
if bytes.Compare(s.signature, other.signature) <= 0 {
return true
}
return false
}
// Returns `true` if the message has a valid signature by the expected proposer in the message's step.
func (s *EmptyStep) verify(validators ValidatorSet) (bool, error) { //nolint
//sRlp, err := EmptyStepRlp(s.step, s.parentHash)
//if err != nil {
// return false, err
//}
//message := crypto.Keccak256(sRlp)
/*
let correct_proposer = step_proposer(validators, &self.parent_hash, self.step);
publickey::verify_address(&correct_proposer, &self.signature.into(), &message)
.map_err(|e| e.into())
*/
return true, nil
}
// nolint
func (s *EmptyStep) author() (common.Address, error) {
sRlp, err := EmptyStepRlp(s.step, s.parentHash)
if err != nil {
return common.Address{}, err
}
message := crypto.Keccak256(sRlp)
public, err := secp256k1.RecoverPubkey(message, s.signature)
if err != nil {
return common.Address{}, err
}
ecdsa, err := crypto.UnmarshalPubkeyStd(public)
if err != nil {
return common.Address{}, err
}
return crypto.PubkeyToAddress(*ecdsa), nil
}
type EmptyStepSet struct {
lock sync.Mutex
list []*EmptyStep
}
func (s *EmptyStepSet) Less(i, j int) bool { return s.list[i].Less(s.list[j]) }
func (s *EmptyStepSet) Swap(i, j int) { s.list[i], s.list[j] = s.list[j], s.list[i] }
func (s *EmptyStepSet) Len() int { return len(s.list) }
func (s *EmptyStepSet) Sort() {
s.lock.Lock()
defer s.lock.Unlock()
sort.Stable(s)
}
func (s *EmptyStepSet) ForEach(f func(int, *EmptyStep)) {
s.lock.Lock()
defer s.lock.Unlock()
for i, el := range s.list {
f(i, el)
}
}
func EmptyStepFullRlp(signature []byte, emptyStepRlp []byte) ([]byte, error) {
type A struct {
s []byte
r []byte
}
return rlp.EncodeToBytes(A{s: signature, r: emptyStepRlp})
}
func EmptyStepRlp(step uint64, parentHash common.Hash) ([]byte, error) {
type A struct {
s uint64
h common.Hash
}
return rlp.EncodeToBytes(A{s: step, h: parentHash})
}
// nolint
type unAssembledHeader struct {
hash common.Hash
number uint64
signers []common.Address
}
type unAssembledHeaders struct {
l *list.List
}
func (u unAssembledHeaders) PushBack(header *unAssembledHeader) { u.l.PushBack(header) }
func (u unAssembledHeaders) PushFront(header *unAssembledHeader) { u.l.PushFront(header) }
func (u unAssembledHeaders) Pop() *unAssembledHeader {
e := u.l.Front()
if e == nil {
return nil
}
u.l.Remove(e)
return e.Value.(*unAssembledHeader)
}
func (u unAssembledHeaders) Front() *unAssembledHeader {
e := u.l.Front()
if e == nil {
return nil
}
return e.Value.(*unAssembledHeader)
}
// RollingFinality checker for authority round consensus.
// Stores a chain of unfinalized hashes that can be pushed onto.
// nolint
type RollingFinality struct {
headers unAssembledHeaders //nolint
signers *SimpleList
signCount map[common.Address]uint
lastPushed *common.Hash // Option<H256>,
}
// NewRollingFinality creates a blank finality checker under the given validator set.
func NewRollingFinality(signers []common.Address) *RollingFinality {
return &RollingFinality{
signers: NewSimpleList(signers),
headers: unAssembledHeaders{l: list.New()},
signCount: map[common.Address]uint{},
}
}
// Clears the finality status, but keeps the validator set.
func (f *RollingFinality) print(num uint64) {
if num > DEBUG_LOG_FROM {
h := f.headers
fmt.Printf("finality_heads: %d\n", num)
i := 0
for e := h.l.Front(); e != nil; e = e.Next() {
i++
a := e.Value.(*unAssembledHeader)
fmt.Printf("\t%d,%x\n", a.number, a.signers[0])
}
if i == 0 {
fmt.Printf("\tempty\n")
}
}
}
func (f *RollingFinality) clear() {
f.headers = unAssembledHeaders{l: list.New()}
f.signCount = map[common.Address]uint{}
f.lastPushed = nil
}
// Push a hash onto the rolling finality checker (implying `subchain_head` == head.parent)
//
// Fails if `signer` isn't a member of the active validator set.
// Returns a list of all newly finalized headers.
func (f *RollingFinality) push(head common.Hash, num uint64, signers []common.Address) (newlyFinalized []unAssembledHeader, err error) {
for i := range signers {
if !f.hasSigner(signers[i]) {
return nil, fmt.Errorf("unknown validator")
}
}
f.addSigners(signers)
f.headers.PushBack(&unAssembledHeader{hash: head, number: num, signers: signers})
for f.isFinalized() {
e := f.headers.Pop()
if e == nil {
panic("headers length always greater than sign count length")
}
f.removeSigners(e.signers)
newlyFinalized = append(newlyFinalized, *e)
}
f.lastPushed = &head
return newlyFinalized, nil
}
// isFinalized returns whether the first entry in `self.headers` is finalized.
func (f *RollingFinality) isFinalized() bool {
e := f.headers.Front()
if e == nil {
return false
}
return len(f.signCount)*2 > len(f.signers.validators)
}
func (f *RollingFinality) hasSigner(signer common.Address) bool {
for j := range f.signers.validators {
if f.signers.validators[j] == signer {
return true
}
}
return false
}
func (f *RollingFinality) addSigners(signers []common.Address) bool {
for i := range signers {
count, ok := f.signCount[signers[i]]
if ok {
f.signCount[signers[i]] = count + 1
} else {
f.signCount[signers[i]] = 1
}
}
return false
}
func (f *RollingFinality) removeSigners(signers []common.Address) {
for i := range signers {
count, ok := f.signCount[signers[i]]
if !ok {
panic("all hashes in `header` should have entries in `sign_count` for their signers")
//continue
}
if count <= 1 {
delete(f.signCount, signers[i])
} else {
f.signCount[signers[i]] = count - 1
}
}
}
func (f *RollingFinality) buildAncestrySubChain(get func(hash common.Hash) ([]common.Address, common.Hash, common.Hash, uint64, bool), parentHash, epochTransitionHash common.Hash) error { // starts from chainHeadParentHash
f.clear()
for {
signers, blockHash, newParentHash, blockNum, ok := get(parentHash)
if !ok {
return nil
}
if blockHash == epochTransitionHash {
return nil
}
for i := range signers {
if !f.hasSigner(signers[i]) {
return fmt.Errorf("unknown validator: blockNum=%d", blockNum)
}
}
if f.lastPushed == nil {
copyHash := parentHash
f.lastPushed = &copyHash
}
f.addSigners(signers)
f.headers.PushFront(&unAssembledHeader{hash: blockHash, number: blockNum, signers: signers})
// break when we've got our first finalized block.
if f.isFinalized() {
e := f.headers.Pop()
if e == nil {
panic("we just pushed a block")
}
f.removeSigners(e.signers)
//log.Info("[aura] finality encountered already finalized block", "hash", e.hash.String(), "number", e.number)
break
}
parentHash = newParentHash
}
return nil
}