github.com/codingfuture/orig-energi3@v0.8.4/energi/consensus/dos_test.go (about)

     1  // Copyright 2019 The Energi Core Authors
     2  // This file is part of the Energi Core library.
     3  //
     4  // The Energi Core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The Energi Core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package consensus
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	eth_consensus "github.com/ethereum/go-ethereum/consensus"
    24  	"github.com/ethereum/go-ethereum/core/state"
    25  	"github.com/ethereum/go-ethereum/core/types"
    26  	"github.com/ethereum/go-ethereum/log"
    27  	"github.com/ethereum/go-ethereum/params"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  
    31  	energi_params "energi.world/core/gen3/energi/params"
    32  )
    33  
    34  type fakeDoSChain struct {
    35  	current *types.Header
    36  	parent  *types.Header
    37  }
    38  
    39  func (fc *fakeDoSChain) Config() *params.ChainConfig {
    40  	panic("Not impl")
    41  }
    42  func (fc *fakeDoSChain) CurrentHeader() *types.Header {
    43  	return fc.current
    44  }
    45  func (fc *fakeDoSChain) GetHeader(hash common.Hash, number uint64) *types.Header {
    46  	return fc.parent
    47  }
    48  func (fc *fakeDoSChain) GetHeaderByNumber(number uint64) *types.Header {
    49  	panic("Not impl")
    50  }
    51  func (fc *fakeDoSChain) GetHeaderByHash(hash common.Hash) *types.Header {
    52  	panic("Not impl")
    53  }
    54  func (fc *fakeDoSChain) GetBlock(hash common.Hash, number uint64) *types.Block {
    55  	panic("Not impl")
    56  }
    57  func (fc *fakeDoSChain) CalculateBlockState(hash common.Hash, number uint64) *state.StateDB {
    58  	panic("Not impl")
    59  }
    60  
    61  func KnownStakesTestCount(ks *KnownStakes) (ret int) {
    62  	ks.Range(func(_, _ interface{}) bool {
    63  		ret++
    64  		return true
    65  	})
    66  	return
    67  }
    68  
    69  func TestPoSDoS(t *testing.T) {
    70  	t.Parallel()
    71  	log.Root().SetHandler(log.StdoutHandler)
    72  
    73  	h := &types.Header{}
    74  	p := &types.Header{}
    75  	c := &types.Header{}
    76  	fc := &fakeDoSChain{
    77  		parent:  p,
    78  		current: c,
    79  	}
    80  
    81  	base := uint64(1000000)
    82  	curr_time := base
    83  	engine := New(nil, nil)
    84  	engine.now = func() uint64 { return curr_time }
    85  
    86  	// POS-8: old fork protection
    87  	//============================
    88  
    89  	log.Trace("Regular grow")
    90  	curr_time = base
    91  	p.Time = base
    92  	c.Time = base
    93  	h.Time = base + energi_params.MinBlockGap
    94  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
    95  
    96  	log.Trace("Side chain as new fork")
    97  	curr_time = base
    98  	p.Time = base - energi_params.OldForkPeriod
    99  	c.Time = base
   100  	h.Time = base + energi_params.MinBlockGap
   101  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   102  
   103  	log.Trace("Side chain as old fork")
   104  	curr_time = base + 1
   105  	p.Time = base - energi_params.OldForkPeriod
   106  	c.Time = base
   107  	h.Time = base + energi_params.MinBlockGap
   108  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   109  
   110  	log.Trace("Side chain as old fork")
   111  	curr_time = base
   112  	p.Time = base - energi_params.OldForkPeriod - 1
   113  	c.Time = base
   114  	h.Time = base + energi_params.MinBlockGap
   115  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   116  
   117  	log.Trace("Side chain as old fork an near old current")
   118  	curr_time = base + energi_params.OldForkPeriod - 1
   119  	p.Time = base - energi_params.OldForkPeriod - 1
   120  	c.Time = base
   121  	h.Time = base + energi_params.MinBlockGap
   122  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   123  
   124  	log.Trace("Side chain as old fork an old current - allow old forks")
   125  	curr_time = base + energi_params.OldForkPeriod
   126  	p.Time = base - energi_params.OldForkPeriod - 1
   127  	c.Time = base
   128  	h.Time = base + energi_params.MinBlockGap
   129  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   130  
   131  	// POS-9: stake throttling
   132  	//============================
   133  
   134  	log.Trace("Another variation")
   135  	curr_time += energi_params.StakeThrottle
   136  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   137  	p.Time = base
   138  	c.Time = base
   139  	h.Time = base + energi_params.MinBlockGap + 1
   140  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   141  	assert.Equal(t, 1, KnownStakesTestCount(&engine.knownStakes))
   142  
   143  	log.Trace("Another coinbase")
   144  	h.Coinbase = common.HexToAddress("0x1234")
   145  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   146  	assert.Equal(t, 2, KnownStakesTestCount(&engine.knownStakes))
   147  
   148  	log.Trace("Another variation")
   149  	h.Root = common.HexToHash("0x1234")
   150  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   151  
   152  	log.Trace("Should reset")
   153  	curr_time += energi_params.StakeThrottle
   154  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   155  
   156  	log.Trace("Check correct cleanup")
   157  	h.Coinbase = common.HexToAddress("0x2345")
   158  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   159  	h.Coinbase = common.HexToAddress("0x3456")
   160  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   161  	assert.Equal(t, 3, KnownStakesTestCount(&engine.knownStakes))
   162  
   163  	curr_time += energi_params.StakeThrottle / 2
   164  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   165  	h.Time += 1
   166  	assert.Equal(t, eth_consensus.ErrDoSThrottle, engine.checkDoS(fc, h, p))
   167  	assert.Equal(t, 3, KnownStakesTestCount(&engine.knownStakes))
   168  
   169  	curr_time += energi_params.StakeThrottle
   170  	assert.Equal(t, nil, engine.checkDoS(fc, h, p))
   171  	assert.Equal(t, 1, KnownStakesTestCount(&engine.knownStakes))
   172  }