github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/les/odr_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package les 18 19 import ( 20 "bytes" 21 "math/big" 22 "testing" 23 "time" 24 25 "github.com/atheioschain/go-atheios/common" 26 "github.com/atheioschain/go-atheios/core" 27 "github.com/atheioschain/go-atheios/core/state" 28 "github.com/atheioschain/go-atheios/core/types" 29 "github.com/atheioschain/go-atheios/core/vm" 30 "github.com/atheioschain/go-atheios/ethdb" 31 "github.com/atheioschain/go-atheios/light" 32 "github.com/atheioschain/go-atheios/params" 33 "github.com/atheioschain/go-atheios/rlp" 34 "golang.org/x/net/context" 35 ) 36 37 type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte 38 39 func TestOdrGetBlockLes1(t *testing.T) { testOdr(t, 1, 1, odrGetBlock) } 40 41 func odrGetBlock(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte { 42 var block *types.Block 43 if bc != nil { 44 block = bc.GetBlockByHash(bhash) 45 } else { 46 block, _ = lc.GetBlockByHash(ctx, bhash) 47 } 48 if block == nil { 49 return nil 50 } 51 rlp, _ := rlp.EncodeToBytes(block) 52 return rlp 53 } 54 55 func TestOdrGetReceiptsLes1(t *testing.T) { testOdr(t, 1, 1, odrGetReceipts) } 56 57 func odrGetReceipts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte { 58 var receipts types.Receipts 59 if bc != nil { 60 receipts = core.GetBlockReceipts(db, bhash, core.GetBlockNumber(db, bhash)) 61 } else { 62 receipts, _ = light.GetBlockReceipts(ctx, lc.Odr(), bhash, core.GetBlockNumber(db, bhash)) 63 } 64 if receipts == nil { 65 return nil 66 } 67 rlp, _ := rlp.EncodeToBytes(receipts) 68 return rlp 69 } 70 71 func TestOdrAccountsLes1(t *testing.T) { testOdr(t, 1, 1, odrAccounts) } 72 73 func odrAccounts(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte { 74 dummyAddr := common.HexToAddress("1234567812345678123456781234567812345678") 75 acc := []common.Address{testBankAddress, acc1Addr, acc2Addr, dummyAddr} 76 77 var res []byte 78 for _, addr := range acc { 79 if bc != nil { 80 header := bc.GetHeaderByHash(bhash) 81 st, err := state.New(header.Root, db) 82 if err == nil { 83 bal := st.GetBalance(addr) 84 rlp, _ := rlp.EncodeToBytes(bal) 85 res = append(res, rlp...) 86 } 87 } else { 88 header := lc.GetHeaderByHash(bhash) 89 st := light.NewLightState(light.StateTrieID(header), lc.Odr()) 90 bal, err := st.GetBalance(ctx, addr) 91 if err == nil { 92 rlp, _ := rlp.EncodeToBytes(bal) 93 res = append(res, rlp...) 94 } 95 } 96 } 97 98 return res 99 } 100 101 func TestOdrContractCallLes1(t *testing.T) { testOdr(t, 1, 2, odrContractCall) } 102 103 type callmsg struct { 104 types.Message 105 } 106 107 func (callmsg) CheckNonce() bool { return false } 108 109 func odrContractCall(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte { 110 data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000") 111 112 var res []byte 113 for i := 0; i < 3; i++ { 114 data[35] = byte(i) 115 if bc != nil { 116 header := bc.GetHeaderByHash(bhash) 117 statedb, err := state.New(header.Root, db) 118 119 if err == nil { 120 from := statedb.GetOrNewStateObject(testBankAddress) 121 from.SetBalance(common.MaxBig) 122 123 msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} 124 125 context := core.NewEVMContext(msg, header, bc) 126 vmenv := vm.NewEVM(context, statedb, config, vm.Config{}) 127 128 //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) 129 gp := new(core.GasPool).AddGas(common.MaxBig) 130 ret, _, _ := core.ApplyMessage(vmenv, msg, gp) 131 res = append(res, ret...) 132 } 133 } else { 134 header := lc.GetHeaderByHash(bhash) 135 state := light.NewLightState(light.StateTrieID(header), lc.Odr()) 136 vmstate := light.NewVMState(ctx, state) 137 from, err := state.GetOrNewStateObject(ctx, testBankAddress) 138 if err == nil { 139 from.SetBalance(common.MaxBig) 140 141 msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), big.NewInt(100000), new(big.Int), data, false)} 142 143 context := core.NewEVMContext(msg, header, lc) 144 vmenv := vm.NewEVM(context, vmstate, config, vm.Config{}) 145 146 //vmenv := light.NewEnv(ctx, state, config, lc, msg, header, vm.Config{}) 147 gp := new(core.GasPool).AddGas(common.MaxBig) 148 ret, _, _ := core.ApplyMessage(vmenv, msg, gp) 149 if vmstate.Error() == nil { 150 res = append(res, ret...) 151 } 152 } 153 } 154 } 155 return res 156 } 157 158 func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) { 159 // Assemble the test environment 160 pm, db, odr := newTestProtocolManagerMust(t, false, 4, testChainGen) 161 lpm, ldb, odr := newTestProtocolManagerMust(t, true, 0, nil) 162 _, err1, lpeer, err2 := newTestPeerPair("peer", protocol, pm, lpm) 163 pool := &testServerPool{} 164 pool.setPeer(lpeer) 165 odr.serverPool = pool 166 select { 167 case <-time.After(time.Millisecond * 100): 168 case err := <-err1: 169 t.Fatalf("peer 1 handshake error: %v", err) 170 case err := <-err2: 171 t.Fatalf("peer 1 handshake error: %v", err) 172 } 173 174 lpm.synchronise(lpeer) 175 176 test := func(expFail uint64) { 177 for i := uint64(0); i <= pm.blockchain.CurrentHeader().Number.Uint64(); i++ { 178 bhash := core.GetCanonicalHash(db, i) 179 b1 := fn(light.NoOdr, db, pm.chainConfig, pm.blockchain.(*core.BlockChain), nil, bhash) 180 ctx, _ := context.WithTimeout(context.Background(), 200*time.Millisecond) 181 b2 := fn(ctx, ldb, lpm.chainConfig, nil, lpm.blockchain.(*light.LightChain), bhash) 182 eq := bytes.Equal(b1, b2) 183 exp := i < expFail 184 if exp && !eq { 185 t.Errorf("odr mismatch") 186 } 187 if !exp && eq { 188 t.Errorf("unexpected odr match") 189 } 190 } 191 } 192 193 // temporarily remove peer to test odr fails 194 pool.setPeer(nil) 195 // expect retrievals to fail (except genesis block) without a les peer 196 test(expFail) 197 pool.setPeer(lpeer) 198 // expect all retrievals to pass 199 test(5) 200 pool.setPeer(nil) 201 // still expect all retrievals to pass, now data should be cached locally 202 test(5) 203 }