mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
Revert adding double validation layer
This commit is contained in:
parent
161053b345
commit
360584a498
3 changed files with 93 additions and 16 deletions
|
|
@ -1633,16 +1633,16 @@ func (bc *BlockChain) UpdateM1() error {
|
||||||
ms = append(ms, XDPoS.Masternode{Address: candidate, Stake: v.Uint64()})
|
ms = append(ms, XDPoS.Masternode{Address: candidate, Stake: v.Uint64()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Info("Ordered list of masternode candidates")
|
|
||||||
for _, m := range ms {
|
|
||||||
log.Info("", "address", m.Address.String(), "stake", m.Stake)
|
|
||||||
}
|
|
||||||
if len(ms) == 0 {
|
if len(ms) == 0 {
|
||||||
log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch")
|
log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch")
|
||||||
} else {
|
} else {
|
||||||
sort.Slice(ms, func(i, j int) bool {
|
sort.Slice(ms, func(i, j int) bool {
|
||||||
return ms[i].Stake >= ms[j].Stake
|
return ms[i].Stake >= ms[j].Stake
|
||||||
})
|
})
|
||||||
|
log.Info("Ordered list of masternode candidates")
|
||||||
|
for _, m := range ms {
|
||||||
|
log.Info("", "address", m.Address.String(), "stake", m.Stake)
|
||||||
|
}
|
||||||
// update masternodes
|
// update masternodes
|
||||||
log.Info("Updating new set of masternodes")
|
log.Info("Updating new set of masternodes")
|
||||||
if len(ms) > common.MaxMasternodes {
|
if len(ms) > common.MaxMasternodes {
|
||||||
|
|
|
||||||
|
|
@ -562,6 +562,14 @@ func (pool *TxPool) local() map[common.Address]types.Transactions {
|
||||||
return txs
|
return txs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pool *TxPool) GetSender(tx *types.Transaction) (common.Address, error) {
|
||||||
|
from, err := types.Sender(pool.signer, tx)
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, ErrInvalidSender
|
||||||
|
}
|
||||||
|
return from, nil
|
||||||
|
}
|
||||||
|
|
||||||
// validateTx checks whether a transaction is valid according to the consensus
|
// validateTx checks whether a transaction is valid according to the consensus
|
||||||
// rules and adheres to some heuristic limits of the local node (price and size).
|
// rules and adheres to some heuristic limits of the local node (price and size).
|
||||||
func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const NumOfMasternodes = 99
|
const NumOfMasternodes = 99
|
||||||
|
|
@ -190,7 +191,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
if eth.chainConfig.XDPoS != nil {
|
if eth.chainConfig.XDPoS != nil {
|
||||||
c := eth.engine.(*XDPoS.XDPoS)
|
c := eth.engine.(*XDPoS.XDPoS)
|
||||||
|
|
||||||
// Inject hook for send tx sign to smartcontract after insert block into chain.
|
// Hook sends tx sign to smartcontract after inserting block to chain.
|
||||||
importedHook := func(block *types.Block) {
|
importedHook := func(block *types.Block) {
|
||||||
snap, err := c.GetSnapshot(eth.blockchain, block.Header())
|
snap, err := c.GetSnapshot(eth.blockchain, block.Header())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -202,16 +203,62 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, authorized := snap.Signers[eth.etherbase]; authorized {
|
if _, authorized := snap.Signers[eth.etherbase]; authorized {
|
||||||
|
// double validation
|
||||||
|
m2, err := getM2(snap, eth, block)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail to validate M2 condition for imported block", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if eth.etherbase != m2 {
|
||||||
|
// firstly, look into pending txPool
|
||||||
|
pendingMap, err := eth.txPool.Pending()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail to get txPool pending", "err", err)
|
||||||
|
//reset pendingMap
|
||||||
|
pendingMap = map[common.Address]types.Transactions{}
|
||||||
|
}
|
||||||
|
txsSentFromM2 := pendingMap[m2]
|
||||||
|
if len(txsSentFromM2) > 0 {
|
||||||
|
for _, tx := range txsSentFromM2 {
|
||||||
|
if tx.To().String() == common.BlockSigners {
|
||||||
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 {
|
||||||
log.Error("Fail to create tx sign for imported block", "error", err)
|
log.Error("Fail to create tx sign for imported block", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//then wait until signTx from m2 comes into txPool
|
||||||
|
txCh := make(chan core.TxPreEvent, txChanSize)
|
||||||
|
subEvent := eth.txPool.SubscribeTxPreEvent(txCh)
|
||||||
|
G:
|
||||||
|
select {
|
||||||
|
case event := <-txCh:
|
||||||
|
from, err := eth.txPool.GetSender(event.Tx)
|
||||||
|
if (err == nil) && (event.Tx.To().String() == common.BlockSigners) && (from == m2) {
|
||||||
|
if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil {
|
||||||
|
log.Error("Fail to create tx sign for imported block", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//timeout 10s
|
||||||
|
case <-time.After(time.Duration(10) * time.Second):
|
||||||
|
break G
|
||||||
|
}
|
||||||
|
subEvent.Unsubscribe()
|
||||||
|
} else if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil {
|
||||||
|
log.Error("Fail to create tx sign for imported block", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// end of double validation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eth.protocolManager.fetcher.SetImportedHook(importedHook)
|
eth.protocolManager.fetcher.SetImportedHook(importedHook)
|
||||||
|
|
||||||
// Hook will process when preparing block.
|
// Hook prepares validators M2 for the current epoch
|
||||||
c.HookPrepare = func(header *types.Header, signers []common.Address) error {
|
c.HookValidator = func(header *types.Header, signers []common.Address) error {
|
||||||
number := header.Number.Int64()
|
number := header.Number.Int64()
|
||||||
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
||||||
validators, err := GetValidators(eth.blockchain, signers)
|
validators, err := GetValidators(eth.blockchain, signers)
|
||||||
|
|
@ -222,7 +269,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Hook penalty.
|
|
||||||
|
// Hook scans for bad masternodes and decide to penalty them
|
||||||
c.HookPenalty = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
|
c.HookPenalty = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
|
||||||
client, err := eth.blockchain.GetClient()
|
client, err := eth.blockchain.GetClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -263,7 +311,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return []common.Address{}, nil
|
return []common.Address{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook reward for XDPoS validator.
|
// Hook calculates reward for masternodes
|
||||||
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error {
|
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) error {
|
||||||
client, err := eth.blockchain.GetClient()
|
client, err := eth.blockchain.GetClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -308,7 +356,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
c.VerifyValidators = func(header *types.Header, signers []common.Address) error {
|
|
||||||
|
// Hook verifies masternodes set
|
||||||
|
c.HookVerifyMNs = func(header *types.Header, signers []common.Address) error {
|
||||||
number := header.Number.Int64()
|
number := header.Number.Int64()
|
||||||
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
if number > 0 && number%common.EpocBlockRandomize == 0 {
|
||||||
validators, err := GetValidators(eth.blockchain, signers)
|
validators, err := GetValidators(eth.blockchain, signers)
|
||||||
|
|
@ -326,6 +376,25 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
return eth, nil
|
return eth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getM2(snap *XDPoS.Snapshot, eth *Ethereum, block *types.Block) (common.Address, error) {
|
||||||
|
epoch := eth.chainConfig.XDPoS.Epoch
|
||||||
|
no := block.NumberU64()
|
||||||
|
cpNo := no
|
||||||
|
if no%epoch != 0 {
|
||||||
|
cpNo = no - (no % epoch)
|
||||||
|
}
|
||||||
|
cpBlk := eth.blockchain.GetBlockByNumber(cpNo)
|
||||||
|
m, err := contracts.GetM1M2FromCheckpointBlock(cpBlk)
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, err
|
||||||
|
}
|
||||||
|
m1, err := XDPoS.WhoIsCreator(snap, block.Header())
|
||||||
|
if err != nil {
|
||||||
|
return common.Address{}, err
|
||||||
|
}
|
||||||
|
return m[m1], nil
|
||||||
|
}
|
||||||
|
|
||||||
func makeExtraData(extra []byte) []byte {
|
func makeExtraData(extra []byte) []byte {
|
||||||
if len(extra) == 0 {
|
if len(extra) == 0 {
|
||||||
// create default extradata
|
// create default extradata
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue