mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
71231140a5
Changes summary: - Continue with the gasLimit check skip in ``verifyHeader`` of ``merge.go`` for unless pre-merge block and blockGasLimitContract present - Refactor ``aura.go`` a bit - Have ``sysCall`` method customized to be able to call state (contract) at a parent (or any other) header state
136 lines
3.6 KiB
Go
136 lines
3.6 KiB
Go
package aura
|
|
|
|
import (
|
|
"bytes"
|
|
"sort"
|
|
"sync"
|
|
|
|
"github.com/ledgerwatch/secp256k1"
|
|
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
|
|
"github.com/ledgerwatch/erigon/crypto"
|
|
"github.com/ledgerwatch/erigon/rlp"
|
|
)
|
|
|
|
// 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 libcommon.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() (libcommon.Address, error) {
|
|
sRlp, err := EmptyStepRlp(s.step, s.parentHash)
|
|
if err != nil {
|
|
return libcommon.Address{}, err
|
|
}
|
|
message := crypto.Keccak256(sRlp)
|
|
public, err := secp256k1.RecoverPubkey(message, s.signature)
|
|
if err != nil {
|
|
return libcommon.Address{}, err
|
|
}
|
|
ecdsa, err := crypto.UnmarshalPubkeyStd(public)
|
|
if err != nil {
|
|
return libcommon.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 libcommon.Hash) ([]byte, error) {
|
|
type A struct {
|
|
s uint64
|
|
h libcommon.Hash
|
|
}
|
|
return rlp.EncodeToBytes(A{s: step, h: parentHash})
|
|
}
|