mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
Add new block header validator for store m2 data.
This commit is contained in:
parent
0ae81138f5
commit
5360513293
5 changed files with 86 additions and 3 deletions
|
|
@ -179,6 +179,10 @@ func sigHash(header *types.Header) (hash common.Hash) {
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SigHash(header *types.Header) (hash common.Hash) {
|
||||||
|
return sigHash(header)
|
||||||
|
}
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
|
|
@ -645,7 +649,7 @@ func (c *Posv) verifySeal(chain consensus.ChainReader, header *types.Header, par
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify validator
|
// verify validator
|
||||||
assignedValidator, err := c.getValidator(creator, snap, chain, header)
|
assignedValidator, err := c.GetValidator(creator, snap, chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -656,7 +660,7 @@ func (c *Posv) verifySeal(chain consensus.ChainReader, header *types.Header, par
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Posv) getValidator(creator common.Address, snap *Snapshot, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
func (c *Posv) GetValidator(creator common.Address, snap *Snapshot, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
||||||
epoch := c.config.Epoch
|
epoch := c.config.Epoch
|
||||||
no := header.Number.Uint64()
|
no := header.Number.Uint64()
|
||||||
cpNo := no
|
cpNo := no
|
||||||
|
|
@ -946,6 +950,30 @@ func (c *Posv) RecoverSigner(header *types.Header) (common.Address, error) {
|
||||||
return ecrecover(header, c.signatures)
|
return ecrecover(header, c.signatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Posv) RecoverValidator(header *types.Header) (common.Address, error) {
|
||||||
|
// If the signature's already cached, return that
|
||||||
|
hash := header.Hash()
|
||||||
|
if address, known := c.signatures.Get(hash); known {
|
||||||
|
return address.(common.Address), nil
|
||||||
|
}
|
||||||
|
// Retrieve the signature from the header extra-data
|
||||||
|
if len(header.Validator) < extraSeal {
|
||||||
|
return common.Address{}, errMissingSignature
|
||||||
|
}
|
||||||
|
signature := header.Validator[len(header.Validator)-extraSeal:]
|
||||||
|
|
||||||
|
// Recover the public key and the Ethereum address
|
||||||
|
pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature)
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, err
|
||||||
|
}
|
||||||
|
var signer common.Address
|
||||||
|
copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
|
||||||
|
|
||||||
|
c.signatures.Add(hash, signer)
|
||||||
|
return signer, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get master nodes over extra data of previous checkpoint block.
|
// Get master nodes over extra data of previous checkpoint block.
|
||||||
func (c *Posv) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
|
func (c *Posv) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
|
||||||
if preCheckpointHeader == nil {
|
if preCheckpointHeader == nil {
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ type Header struct {
|
||||||
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
|
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
|
||||||
Nonce BlockNonce `json:"nonce" gencodec:"required"`
|
Nonce BlockNonce `json:"nonce" gencodec:"required"`
|
||||||
Validators []byte `json:"validators" gencodec:"required"`
|
Validators []byte `json:"validators" gencodec:"required"`
|
||||||
|
Validator []byte `json:"validator" gencodec:"required"`
|
||||||
Penalties []byte `json:"penalties" gencodec:"required"`
|
Penalties []byte `json:"penalties" gencodec:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,6 +257,10 @@ func CopyHeader(h *Header) *Header {
|
||||||
cpy.Extra = make([]byte, len(h.Extra))
|
cpy.Extra = make([]byte, len(h.Extra))
|
||||||
copy(cpy.Extra, h.Extra)
|
copy(cpy.Extra, h.Extra)
|
||||||
}
|
}
|
||||||
|
if len(h.Validator) > 0 {
|
||||||
|
cpy.Validator = make([]byte, len(h.Validator))
|
||||||
|
copy(cpy.Validator, h.Validator)
|
||||||
|
}
|
||||||
return &cpy
|
return &cpy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,6 +327,7 @@ func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
|
||||||
func (b *Block) UncleHash() common.Hash { return b.header.UncleHash }
|
func (b *Block) UncleHash() common.Hash { return b.header.UncleHash }
|
||||||
func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) }
|
func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) }
|
||||||
func (b *Block) Penalties() []byte { return common.CopyBytes(b.header.Penalties) }
|
func (b *Block) Penalties() []byte { return common.CopyBytes(b.header.Penalties) }
|
||||||
|
func (b *Block) Validator() []byte { return common.CopyBytes(b.header.Validator) }
|
||||||
|
|
||||||
func (b *Block) Header() *Header { return CopyHeader(b.header) }
|
func (b *Block) Header() *Header { return CopyHeader(b.header) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
if eth.chainConfig.Posv != nil {
|
if eth.chainConfig.Posv != nil {
|
||||||
c := eth.engine.(*posv.Posv)
|
c := eth.engine.(*posv.Posv)
|
||||||
|
|
||||||
signHook := func(block *types.Block) error {
|
signHook := func(block *types.Block) error {
|
||||||
if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil {
|
if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil {
|
||||||
return fmt.Errorf("Fail to create tx sign for importing block: %v", err)
|
return fmt.Errorf("Fail to create tx sign for importing block: %v", err)
|
||||||
|
|
@ -195,7 +194,41 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appendM2HeaderHook := func(block *types.Block) (*types.Block, error) {
|
||||||
|
eb, err := eth.Etherbase()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot get etherbase for append m2 header", "err", err)
|
||||||
|
return block, fmt.Errorf("etherbase missing: %v", err)
|
||||||
|
}
|
||||||
|
// Get m1.
|
||||||
|
snap, err := c.GetSnapshot(eth.blockchain, eth.blockchain.CurrentHeader())
|
||||||
|
if err != nil {
|
||||||
|
return block, fmt.Errorf("can't get snapshot: %v", err)
|
||||||
|
}
|
||||||
|
m1, err := c.RecoverSigner(block.Header())
|
||||||
|
if err != nil {
|
||||||
|
return block, fmt.Errorf("can't get block creator: %v", err)
|
||||||
|
}
|
||||||
|
m2, err := c.GetValidator(m1, snap, eth.blockchain, block.Header())
|
||||||
|
if err != nil {
|
||||||
|
return block, fmt.Errorf("can't get block validator: %v", err)
|
||||||
|
}
|
||||||
|
if m2 == eb {
|
||||||
|
wallet, _ := eth.accountManager.Find(accounts.Account{Address: eb})
|
||||||
|
header := block.Header()
|
||||||
|
sighash, _ := wallet.SignHash(accounts.Account{Address: eb}, posv.SigHash(header).Bytes())
|
||||||
|
header.Validator = sighash
|
||||||
|
block = types.NewBlockWithHeader(header)
|
||||||
|
//c := eth.engine.(*posv.Posv)
|
||||||
|
//validator, _ := c.RecoverValidator(block.Header())
|
||||||
|
//log.Error("addr", "addr", validator)
|
||||||
|
}
|
||||||
|
|
||||||
|
return block, nil
|
||||||
|
}
|
||||||
|
|
||||||
eth.protocolManager.fetcher.SetSignHook(signHook)
|
eth.protocolManager.fetcher.SetSignHook(signHook)
|
||||||
|
eth.protocolManager.fetcher.SetAppendM2HeaderHook(appendM2HeaderHook)
|
||||||
|
|
||||||
// Hook prepares validators M2 for the current epoch
|
// Hook prepares validators M2 for the current epoch
|
||||||
c.HookValidator = func(header *types.Header, signers []common.Address) error {
|
c.HookValidator = func(header *types.Header, signers []common.Address) error {
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ type Fetcher struct {
|
||||||
completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
|
completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
|
||||||
doubleValidateHook func(*types.Block) error
|
doubleValidateHook func(*types.Block) error
|
||||||
signHook func(*types.Block) error
|
signHook func(*types.Block) error
|
||||||
|
appendM2HeaderHook func(*types.Block) (*types.Block, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a block fetcher to retrieve blocks based on hash announcements.
|
// New creates a block fetcher to retrieve blocks based on hash announcements.
|
||||||
|
|
@ -653,6 +654,15 @@ func (f *Fetcher) insert(peer string, block *types.Block) {
|
||||||
// Quickly validate the header and propagate the block if it passes
|
// Quickly validate the header and propagate the block if it passes
|
||||||
switch err := f.verifyHeader(block.Header()); err {
|
switch err := f.verifyHeader(block.Header()); err {
|
||||||
case nil:
|
case nil:
|
||||||
|
// Append m2 to block header.
|
||||||
|
// Invoke the dv hook to run double validation layer
|
||||||
|
if f.appendM2HeaderHook != nil {
|
||||||
|
if block, err = f.appendM2HeaderHook(block); err != nil {
|
||||||
|
log.Error("Append m2 to block header fail", "err", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// All ok, quickly propagate to our peers
|
// All ok, quickly propagate to our peers
|
||||||
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
propBroadcastOutTimer.UpdateSince(block.ReceivedAt)
|
||||||
go f.broadcastBlock(block, true)
|
go f.broadcastBlock(block, true)
|
||||||
|
|
@ -757,3 +767,8 @@ func (f *Fetcher) SetDoubleValidateHook(doubleValidateHook func(*types.Block) er
|
||||||
func (f *Fetcher) SetSignHook(signHook func(*types.Block) error) {
|
func (f *Fetcher) SetSignHook(signHook func(*types.Block) error) {
|
||||||
f.signHook = signHook
|
f.signHook = signHook
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind append m2 to block header hook when imported into chain.
|
||||||
|
func (f *Fetcher) SetAppendM2HeaderHook(appendM2HeaderHook func(*types.Block) (*types.Block, error)) {
|
||||||
|
f.appendM2HeaderHook = appendM2HeaderHook
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -817,6 +817,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
|
||||||
"transactionsRoot": head.TxHash,
|
"transactionsRoot": head.TxHash,
|
||||||
"receiptsRoot": head.ReceiptHash,
|
"receiptsRoot": head.ReceiptHash,
|
||||||
"validators": hexutil.Bytes(head.Validators),
|
"validators": hexutil.Bytes(head.Validators),
|
||||||
|
"validator": hexutil.Bytes(head.Validator),
|
||||||
"penalties": hexutil.Bytes(head.Penalties),
|
"penalties": hexutil.Bytes(head.Penalties),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue