github.com/codingfuture/orig-energi3@v0.8.4/core/energi_preblacklist_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 core 18 19 import ( 20 "io/ioutil" 21 "os" 22 "strings" 23 "testing" 24 "time" 25 26 "github.com/ethereum/go-ethereum/accounts/abi" 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/consensus/ethash" 29 "github.com/ethereum/go-ethereum/core/state" 30 "github.com/ethereum/go-ethereum/core/types" 31 "github.com/ethereum/go-ethereum/core/vm" 32 "github.com/ethereum/go-ethereum/ethdb" 33 "github.com/ethereum/go-ethereum/event" 34 "github.com/ethereum/go-ethereum/log" 35 "github.com/ethereum/go-ethereum/params" 36 37 "github.com/stretchr/testify/assert" 38 39 energi_abi "energi.world/core/gen3/energi/abi" 40 energi_params "energi.world/core/gen3/energi/params" 41 ) 42 43 /* 44 type fakeSigner struct { 45 sender common.Address 46 } 47 48 func (s *fakeSigner) Sender(tx *types.Transaction) (common.Address, error) { 49 return s.sender, nil 50 } 51 func (sg *fakeSigner) SignatureValues(tx *types.Transaction, sig []byte) (r, s, v *big.Int, err error) { 52 return common.Big0, common.Big0, common.Big0, nil 53 } 54 func (s *fakeSigner) Hash(tx *types.Transaction) common.Hash { 55 return tx.Hash() 56 } 57 func (s *fakeSigner) Equal(types.Signer) bool { 58 return false 59 } 60 */ 61 62 func TestPreBlacklist(t *testing.T) { 63 t.Parallel() 64 log.Root().SetHandler(log.StdoutHandler) 65 66 now := time.Now() // It can be fixed 67 adjust_time := time.Duration(0) 68 69 testdb := ethdb.NewMemDatabase() 70 gspec := &Genesis{ 71 Config: params.TestnetChainConfig, 72 } 73 gspec.MustCommit(testdb) 74 engine := ethash.NewFaker() 75 76 chain, err := NewBlockChain( 77 testdb, nil, gspec.Config, 78 engine, vm.Config{}, nil) 79 assert.Empty(t, err) 80 81 dir, err := ioutil.TempDir(os.TempDir(), "test-*") 82 if err != nil { 83 panic(err) 84 } 85 86 pool := NewTxPool(TxPoolConfig{Protection: dir}, gspec.Config, chain) 87 prebl := pool.preBlacklist 88 prebl.timeNow = func() time.Time { 89 return now.Add(adjust_time) 90 } 91 92 bladdr1 := common.HexToAddress("0x1111") 93 bladdr2 := common.HexToAddress("0x2222") 94 sender := common.HexToAddress("0x3333") 95 wladdr1 := common.HexToAddress("0x4444") 96 97 gspec.Config.Energi = ¶ms.EnergiConfig{ 98 EBISigner: sender, 99 } 100 101 signer := &fakeSigner{} 102 pool.signer = signer 103 signer.sender = sender 104 105 defer chain.Stop() 106 defer pool.Stop() 107 pool.chain = chain 108 pool.currentState, _ = chain.State() 109 110 blreg_abi, err := abi.JSON(strings.NewReader(energi_abi.IBlacklistRegistryABI)) 111 assert.Empty(t, err) 112 propose1Call, err := blreg_abi.Pack("propose", bladdr1) 113 assert.Empty(t, err) 114 propose2Call, err := blreg_abi.Pack("propose", bladdr2) 115 assert.Empty(t, err) 116 proposeWLCall, err := blreg_abi.Pack("propose", wladdr1) 117 assert.Empty(t, err) 118 revokeCall, err := blreg_abi.Pack("proposeRevoke", bladdr1) 119 assert.Empty(t, err) 120 121 propose1 := types.NewTransaction( 122 1, energi_params.Energi_BlacklistRegistry, common.Big0, 1000000, common.Big0, propose1Call) 123 propose2 := types.NewTransaction( 124 2, energi_params.Energi_BlacklistRegistry, common.Big0, 1000000, common.Big0, propose2Call) 125 proposeWL := types.NewTransaction( 126 3, energi_params.Energi_BlacklistRegistry, common.Big0, 1000000, common.Big0, proposeWLCall) 127 revoke := types.NewTransaction( 128 4, energi_params.Energi_BlacklistRegistry, common.Big0, 1000000, common.Big0, revokeCall) 129 proposePaid := types.NewTransaction( 130 1, energi_params.Energi_BlacklistRegistry, common.Big0, 1000000, common.Big1, propose1Call) 131 132 pool.currentState.SetCode( 133 energi_params.Energi_BlacklistRegistry, 134 // PUSH1 1 PUSH1 0 MSTORE PUSH1 1 PUSH1 0 RETURN 135 []byte{0x60, 0x01, 0x60, 0x00, 0x52, 0x60, 0x20, 0x60, 0x00, 0xF3}, 136 ) 137 pool.currentState.SetState( 138 energi_params.Energi_Whitelist, 139 wladdr1.Hash(), 140 common.BytesToHash([]byte{0x01}), 141 ) 142 assert.True(t, IsWhitelisted(pool.currentState, wladdr1)) 143 144 log.Trace("Make sure removed in pool") 145 signer.sender = bladdr1 146 err = pool.AddLocal(revoke) 147 assert.Equal(t, nil, err) 148 assert.Equal(t, 1, len(pool.queue[bladdr1].Flatten())) 149 signer.sender = sender 150 151 log.Trace("Initial") 152 err = prebl.processTx(pool, revoke) 153 assert.Equal(t, nil, err) 154 assert.Equal(t, 0, len(prebl.proposed)) 155 assert.Equal(t, 1, len(pool.queue[bladdr1].Flatten())) 156 157 err = prebl.processTx(pool, propose1) 158 assert.Equal(t, nil, err) 159 assert.Equal(t, 1, len(prebl.proposed)) 160 if qb, ok := pool.queue[bladdr1]; ok { 161 assert.Equal(t, 1, len(qb.Flatten())) 162 } 163 164 adjust_time = time.Duration(10) * time.Minute 165 166 err = prebl.processTx(pool, propose2) 167 assert.Equal(t, nil, err) 168 assert.Equal(t, 2, len(prebl.proposed)) 169 170 err = prebl.processTx(pool, proposeWL) 171 assert.Equal(t, nil, err) 172 assert.Equal(t, 2, len(prebl.proposed)) 173 assert.True(t, IsWhitelisted(pool.currentState, wladdr1)) 174 175 // Non-EBI 176 err = prebl.processTx(pool, proposePaid) 177 assert.Equal(t, nil, err) 178 assert.Equal(t, 2, len(prebl.proposed)) 179 180 log.Trace("Check if filtered properly") 181 signer.sender = bladdr1 182 err = prebl.processTx(pool, revoke) 183 assert.Equal(t, ErrPreBlacklist, err) 184 185 signer.sender = sender 186 err = prebl.processTx(pool, revoke) 187 assert.Equal(t, nil, err) 188 189 signer.sender = bladdr2 190 err = prebl.processTx(pool, revoke) 191 assert.Equal(t, ErrPreBlacklist, err) 192 193 signer.sender = sender 194 195 log.Trace("Check block filter hook") 196 blocks := make(types.Blocks, 0, 3) 197 blocks = append(blocks, types.NewBlockWithHeader(&types.Header{Coinbase: sender})) 198 blocks = append(blocks, types.NewBlockWithHeader(&types.Header{Coinbase: bladdr1})) 199 blocks = append(blocks, types.NewBlockWithHeader(&types.Header{Coinbase: sender})) 200 blocks = pool.PreBlacklistHook(blocks) 201 assert.Equal(t, 1, len(blocks)) 202 assert.Equal(t, sender, blocks[0].Coinbase()) 203 204 log.Trace("After timeout") 205 adjust_time = pbPeriod + time.Minute 206 207 err = prebl.processTx(pool, revoke) 208 assert.Equal(t, nil, err) 209 assert.Equal(t, 1, len(prebl.proposed)) 210 211 err = prebl.processTx(pool, propose1) 212 assert.Equal(t, nil, err) 213 assert.Equal(t, 2, len(prebl.proposed)) 214 215 err = prebl.processTx(pool, propose2) 216 assert.Equal(t, nil, err) 217 assert.Equal(t, 2, len(prebl.proposed)) 218 219 adjust_time *= time.Duration(2) 220 err = prebl.processTx(pool, revoke) 221 assert.Equal(t, nil, err) 222 assert.Equal(t, 0, len(prebl.proposed)) 223 224 log.Trace("Ignore not valid proposals") 225 226 pool.currentState.SetCode( 227 energi_params.Energi_BlacklistRegistry, 228 // PUSH1 1 PUSH1 0 MSTORE PUSH1 1 PUSH1 0 REVERT 229 []byte{0x60, 0x01, 0x60, 0x00, 0x52, 0x60, 0x20, 0x60, 0x00, 0xFD}, 230 ) 231 232 err = prebl.processTx(pool, propose1) 233 assert.Equal(t, nil, err) 234 assert.Equal(t, 0, len(prebl.proposed)) 235 } 236 237 func TestPersistence(t *testing.T) { 238 dir, err := ioutil.TempDir(os.TempDir(), "test-*") 239 if err != nil { 240 panic(err) 241 } 242 243 statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) 244 blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} 245 pool := NewTxPool(TxPoolConfig{Protection: dir}, params.TestChainConfig, blockchain) 246 247 preblacklistNewData := map[common.Address]time.Time{ 248 common.HexToAddress("12"): time.Unix(123456, 0), 249 common.HexToAddress("13"): time.Unix(56789, 0), 250 } 251 252 mnHeartbeatsNewData := map[common.Address]time.Time{ 253 common.HexToAddress("14"): time.Unix(674782, 0), 254 common.HexToAddress("15"): time.Unix(1232142, 0), 255 } 256 257 mnInvalidationsNewData := map[common.Address]time.Time{ 258 common.HexToAddress("24"): time.Unix(13132, 0), 259 common.HexToAddress("35"): time.Unix(113231, 0), 260 } 261 262 mnCheckpointsNewData := map[common.Address]time.Time{ 263 common.HexToAddress("124"): time.Unix(1231124, 0), 264 common.HexToAddress("152"): time.Unix(123123, 0), 265 } 266 267 coinClaimsNewData := map[uint32]time.Time{ 268 3124: time.Unix(12313, 0), 269 3152: time.Unix(123121, 0), 270 } 271 272 // Assign the new data. 273 pool.preBlacklist.proposed = preblacklistNewData 274 pool.zfProtector.mnHeartbeats = mnHeartbeatsNewData 275 pool.zfProtector.mnInvalidations = mnInvalidationsNewData 276 pool.zfProtector.mnCheckpoints = mnCheckpointsNewData 277 pool.zfProtector.coinClaims = coinClaimsNewData 278 279 // Persist in the persist path. 280 err = pool.persistenceWriter() 281 assert.Equal(t, nil, err) 282 283 // Drop the previous set data to simulate a shutdown. 284 pool.preBlacklist.proposed = nil 285 pool.zfProtector.mnHeartbeats = nil 286 pool.zfProtector.mnInvalidations = nil 287 pool.zfProtector.mnCheckpoints = nil 288 pool.zfProtector.coinClaims = nil 289 290 // Assert that the data was actually dropped. 291 assert.NotEqual(t, preblacklistNewData, pool.preBlacklist.proposed) 292 assert.NotEqual(t, mnHeartbeatsNewData, pool.zfProtector.mnHeartbeats) 293 assert.NotEqual(t, mnInvalidationsNewData, pool.zfProtector.mnInvalidations) 294 assert.NotEqual(t, mnCheckpointsNewData, pool.zfProtector.mnCheckpoints) 295 assert.NotEqual(t, coinClaimsNewData, pool.zfProtector.coinClaims) 296 297 // Read the persisted data. 298 err = pool.persistenceReader() 299 assert.Equal(t, nil, err) 300 301 // Assert that the persisted data was successfully read. 302 assert.Equal(t, preblacklistNewData, pool.preBlacklist.proposed) 303 assert.Equal(t, mnHeartbeatsNewData, pool.zfProtector.mnHeartbeats) 304 assert.Equal(t, mnInvalidationsNewData, pool.zfProtector.mnInvalidations) 305 assert.Equal(t, mnCheckpointsNewData, pool.zfProtector.mnCheckpoints) 306 assert.Equal(t, coinClaimsNewData, pool.zfProtector.coinClaims) 307 308 // Cleanup 309 os.Remove(dir) 310 }