github.com/aswedchain/aswed@v1.0.1/core/rlp_test.go (about) 1 // Copyright 2019 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 core 18 19 import ( 20 "fmt" 21 "math/big" 22 "testing" 23 24 "github.com/aswedchain/aswed/common" 25 "github.com/aswedchain/aswed/consensus/ethash" 26 "github.com/aswedchain/aswed/core/rawdb" 27 "github.com/aswedchain/aswed/core/types" 28 "github.com/aswedchain/aswed/crypto" 29 "github.com/aswedchain/aswed/params" 30 "github.com/aswedchain/aswed/rlp" 31 "golang.org/x/crypto/sha3" 32 ) 33 34 func getBlock(transactions int, uncles int, dataSize int) *types.Block { 35 var ( 36 aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") 37 // Generate a canonical chain to act as the main dataset 38 engine = ethash.NewFaker() 39 db = rawdb.NewMemoryDatabase() 40 // A sender who makes transactions, has some funds 41 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 42 address = crypto.PubkeyToAddress(key.PublicKey) 43 funds = big.NewInt(1000000000) 44 gspec = &Genesis{ 45 Config: params.TestChainConfig, 46 Alloc: GenesisAlloc{address: {Balance: funds}}, 47 } 48 genesis = gspec.MustCommit(db) 49 ) 50 51 // We need to generate as many blocks +1 as uncles 52 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, uncles+1, 53 func(n int, b *BlockGen) { 54 if n == uncles { 55 // Add transactions and stuff on the last block 56 for i := 0; i < transactions; i++ { 57 tx, _ := types.SignTx(types.NewTransaction(uint64(i), aa, 58 big.NewInt(0), 50000, big.NewInt(1), make([]byte, dataSize)), types.HomesteadSigner{}, key) 59 b.AddTx(tx) 60 } 61 for i := 0; i < uncles; i++ { 62 b.AddUncle(&types.Header{ParentHash: b.PrevBlock(n - 1 - i).Hash(), Number: big.NewInt(int64(n - i))}) 63 } 64 } 65 }) 66 block := blocks[len(blocks)-1] 67 return block 68 } 69 70 // TestRlpIterator tests that individual transactions can be picked out 71 // from blocks without full unmarshalling/marshalling 72 func TestRlpIterator(t *testing.T) { 73 for _, tt := range []struct { 74 txs int 75 uncles int 76 datasize int 77 }{ 78 {0, 0, 0}, 79 {0, 2, 0}, 80 {10, 0, 0}, 81 {10, 2, 0}, 82 {10, 2, 50}, 83 } { 84 testRlpIterator(t, tt.txs, tt.uncles, tt.datasize) 85 } 86 } 87 88 func testRlpIterator(t *testing.T, txs, uncles, datasize int) { 89 desc := fmt.Sprintf("%d txs [%d datasize] and %d uncles", txs, datasize, uncles) 90 bodyRlp, _ := rlp.EncodeToBytes(getBlock(txs, uncles, datasize).Body()) 91 it, err := rlp.NewListIterator(bodyRlp) 92 if err != nil { 93 t.Fatal(err) 94 } 95 // Check that txs exist 96 if !it.Next() { 97 t.Fatal("expected two elems, got zero") 98 } 99 txdata := it.Value() 100 // Check that uncles exist 101 if !it.Next() { 102 t.Fatal("expected two elems, got one") 103 } 104 // No more after that 105 if it.Next() { 106 t.Fatal("expected only two elems, got more") 107 } 108 txIt, err := rlp.NewListIterator(txdata) 109 if err != nil { 110 t.Fatal(err) 111 } 112 var gotHashes []common.Hash 113 var expHashes []common.Hash 114 for txIt.Next() { 115 gotHashes = append(gotHashes, crypto.Keccak256Hash(txIt.Value())) 116 } 117 118 var expBody types.Body 119 err = rlp.DecodeBytes(bodyRlp, &expBody) 120 if err != nil { 121 t.Fatal(err) 122 } 123 for _, tx := range expBody.Transactions { 124 expHashes = append(expHashes, tx.Hash()) 125 } 126 if gotLen, expLen := len(gotHashes), len(expHashes); gotLen != expLen { 127 t.Fatalf("testcase %v: length wrong, got %d exp %d", desc, gotLen, expLen) 128 } 129 // also sanity check against input 130 if gotLen := len(gotHashes); gotLen != txs { 131 t.Fatalf("testcase %v: length wrong, got %d exp %d", desc, gotLen, txs) 132 } 133 for i, got := range gotHashes { 134 if exp := expHashes[i]; got != exp { 135 t.Errorf("testcase %v: hash wrong, got %x, exp %x", desc, got, exp) 136 } 137 } 138 } 139 140 // BenchmarkHashing compares the speeds of hashing a rlp raw data directly 141 // without the unmarshalling/marshalling step 142 func BenchmarkHashing(b *testing.B) { 143 // Make a pretty fat block 144 var ( 145 bodyRlp []byte 146 blockRlp []byte 147 ) 148 { 149 block := getBlock(200, 2, 50) 150 bodyRlp, _ = rlp.EncodeToBytes(block.Body()) 151 blockRlp, _ = rlp.EncodeToBytes(block) 152 } 153 var got common.Hash 154 var hasher = sha3.NewLegacyKeccak256() 155 b.Run("iteratorhashing", func(b *testing.B) { 156 b.ResetTimer() 157 for i := 0; i < b.N; i++ { 158 var hash common.Hash 159 it, err := rlp.NewListIterator(bodyRlp) 160 if err != nil { 161 b.Fatal(err) 162 } 163 it.Next() 164 txs := it.Value() 165 txIt, err := rlp.NewListIterator(txs) 166 if err != nil { 167 b.Fatal(err) 168 } 169 for txIt.Next() { 170 hasher.Reset() 171 hasher.Write(txIt.Value()) 172 hasher.Sum(hash[:0]) 173 got = hash 174 } 175 } 176 }) 177 var exp common.Hash 178 b.Run("fullbodyhashing", func(b *testing.B) { 179 b.ResetTimer() 180 for i := 0; i < b.N; i++ { 181 var body types.Body 182 rlp.DecodeBytes(bodyRlp, &body) 183 for _, tx := range body.Transactions { 184 exp = tx.Hash() 185 } 186 } 187 }) 188 b.Run("fullblockhashing", func(b *testing.B) { 189 b.ResetTimer() 190 for i := 0; i < b.N; i++ { 191 var block types.Block 192 rlp.DecodeBytes(blockRlp, &block) 193 for _, tx := range block.Transactions() { 194 tx.Hash() 195 } 196 } 197 }) 198 if got != exp { 199 b.Fatalf("hash wrong, got %x exp %x", got, exp) 200 } 201 }