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 }