Revert adding double validation layer

This commit is contained in:
AnilChinchwale 2018-11-09 14:39:48 +05:30
parent 161053b345
commit 360584a498
3 changed files with 93 additions and 16 deletions

View file

@ -699,9 +699,9 @@ func (bc *BlockChain) procFutureBlocks() {
type WriteStatus byte
const (
NonStatTy WriteStatus = iota
CanonStatTy
SideStatTy
NonStatTy WriteStatus = iota
CanonStatTy
SideStatTy
)
// Rollback is designed to remove a chain of links from the database that aren't
@ -1633,16 +1633,16 @@ func (bc *BlockChain) UpdateM1() error {
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 {
log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch")
} else {
sort.Slice(ms, func(i, j int) bool {
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
log.Info("Updating new set of masternodes")
if len(ms) > common.MaxMasternodes {

View file

@ -562,6 +562,14 @@ func (pool *TxPool) local() map[common.Address]types.Transactions {
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
// rules and adheres to some heuristic limits of the local node (price and size).
func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
@ -1238,4 +1246,4 @@ func (as *accountSet) containsTx(tx *types.Transaction) bool {
// add inserts a new address into the set to track.
func (as *accountSet) add(addr common.Address) {
as.accounts[addr] = struct{}{}
}
}

View file

@ -52,6 +52,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"time"
)
const NumOfMasternodes = 99
@ -190,7 +191,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if eth.chainConfig.XDPoS != nil {
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) {
snap, err := c.GetSnapshot(eth.blockchain, block.Header())
if err != nil {
@ -202,16 +203,62 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return
}
if _, authorized := snap.Signers[eth.etherbase]; authorized {
if err := contracts.CreateTransactionSign(chainConfig, eth.txPool, eth.accountManager, block, chainDb); err != nil {
// 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 {
log.Error("Fail to create tx sign for imported block", "error", err)
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)
// Hook will process when preparing block.
c.HookPrepare = func(header *types.Header, signers []common.Address) error {
// Hook prepares validators M2 for the current epoch
c.HookValidator = func(header *types.Header, signers []common.Address) error {
number := header.Number.Int64()
if number > 0 && number%common.EpocBlockRandomize == 0 {
validators, err := GetValidators(eth.blockchain, signers)
@ -222,7 +269,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
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) {
client, err := eth.blockchain.GetClient()
if err != nil {
@ -263,7 +311,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
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 {
client, err := eth.blockchain.GetClient()
if err != nil {
@ -308,7 +356,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
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()
if number > 0 && number%common.EpocBlockRandomize == 0 {
validators, err := GetValidators(eth.blockchain, signers)
@ -326,6 +376,25 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
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 {
if len(extra) == 0 {
// create default extradata
@ -630,4 +699,4 @@ func GetValidators(bc *core.BlockChain, masternodes []common.Address) ([]byte, e
return contracts.BuildValidatorFromM2(m2), nil
}
return nil, core.ErrNotFoundM1
}
}