github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/block/block_test.go (about) 1 package block 2 3 import ( 4 "encoding/base64" 5 "encoding/hex" 6 "encoding/json" 7 "strings" 8 "testing" 9 10 "github.com/nspcc-dev/neo-go/internal/testserdes" 11 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 12 "github.com/nspcc-dev/neo-go/pkg/crypto/hash" 13 "github.com/nspcc-dev/neo-go/pkg/encoding/address" 14 "github.com/nspcc-dev/neo-go/pkg/io" 15 "github.com/nspcc-dev/neo-go/pkg/util" 16 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func trim0x(value any) string { 22 s := value.(string) 23 return strings.TrimPrefix(s, "0x") 24 } 25 26 // Test blocks are blocks from testnet with their corresponding indices. 27 func TestDecodeBlock1(t *testing.T) { 28 data, err := getBlockData(1) 29 require.NoError(t, err) 30 31 b, err := hex.DecodeString(data["raw"].(string)) 32 require.NoError(t, err) 33 34 block := New(false) 35 assert.NoError(t, testserdes.DecodeBinary(b, block)) 36 37 assert.Equal(t, uint32(data["index"].(float64)), block.Index) 38 assert.Equal(t, uint32(data["version"].(float64)), block.Version) 39 assert.Equal(t, trim0x(data["hash"]), block.Hash().StringLE()) 40 assert.Equal(t, trim0x(data["previousblockhash"]), block.PrevHash.StringLE()) 41 assert.Equal(t, trim0x(data["merkleroot"]), block.MerkleRoot.StringLE()) 42 assert.Equal(t, trim0x(data["nextconsensus"]), address.Uint160ToString(block.NextConsensus)) 43 44 scripts := data["witnesses"].([]any) 45 script := scripts[0].(map[string]any) 46 assert.Equal(t, script["invocation"].(string), base64.StdEncoding.EncodeToString(block.Script.InvocationScript)) 47 assert.Equal(t, script["verification"].(string), base64.StdEncoding.EncodeToString(block.Script.VerificationScript)) 48 49 tx := data["tx"].([]any) 50 tx0 := tx[0].(map[string]any) 51 assert.Equal(t, len(tx), len(block.Transactions)) 52 assert.Equal(t, len(tx0["attributes"].([]any)), len(block.Transactions[0].Attributes)) 53 } 54 55 func TestTrimmedBlock(t *testing.T) { 56 block := getDecodedBlock(t, 1) 57 58 buf := io.NewBufBinWriter() 59 block.EncodeTrimmed(buf.BinWriter) 60 require.NoError(t, buf.Err) 61 62 r := io.NewBinReaderFromBuf(buf.Bytes()) 63 trimmedBlock, err := NewTrimmedFromReader(false, r) 64 require.NoError(t, err) 65 66 assert.True(t, trimmedBlock.Trimmed) 67 assert.Equal(t, block.Version, trimmedBlock.Version) 68 assert.Equal(t, block.PrevHash, trimmedBlock.PrevHash) 69 assert.Equal(t, block.MerkleRoot, trimmedBlock.MerkleRoot) 70 assert.Equal(t, block.Timestamp, trimmedBlock.Timestamp) 71 assert.Equal(t, block.Index, trimmedBlock.Index) 72 assert.Equal(t, block.NextConsensus, trimmedBlock.NextConsensus) 73 74 assert.Equal(t, block.Script, trimmedBlock.Script) 75 assert.Equal(t, len(block.Transactions), len(trimmedBlock.Transactions)) 76 for i := 0; i < len(block.Transactions); i++ { 77 assert.Equal(t, block.Transactions[i].Hash(), trimmedBlock.Transactions[i].Hash()) 78 assert.True(t, trimmedBlock.Transactions[i].Trimmed) 79 } 80 } 81 82 func newDumbBlock() *Block { 83 return &Block{ 84 Header: Header{ 85 Version: 0, 86 PrevHash: hash.Sha256([]byte("a")), 87 MerkleRoot: hash.Sha256([]byte("b")), 88 Timestamp: 100500, 89 Index: 1, 90 NextConsensus: hash.Hash160([]byte("a")), 91 Script: transaction.Witness{ 92 VerificationScript: []byte{0x51}, // PUSH1 93 InvocationScript: []byte{0x61}, // NOP 94 }, 95 }, 96 Transactions: []*transaction.Transaction{ 97 transaction.New([]byte{byte(opcode.PUSH1)}, 0), 98 }, 99 } 100 } 101 102 func TestHashBlockEqualsHashHeader(t *testing.T) { 103 block := newDumbBlock() 104 105 assert.Equal(t, block.Hash(), block.Header.Hash()) 106 } 107 108 func TestBinBlockDecodeEncode(t *testing.T) { 109 // block with two transfer transactions taken from C# privnet 110 rawblock := "AAAAAAwIVa2D6Yha3tArd5XnwkAf7deJBsdyyvpYb2xMZGBbkOUNHAsfre0rKA/F+Ox05/bQSXmcRZnzK3M6Z+/TxJUh0MNFeAEAAAAAAAAAAAAAAQAAAADe7nnBifMAmLC6ai65CzqSWKbH/wHGDEDgwCcXkcaFw5MGOp1cpkgApzDTX2/RxKlmPeXTgWYtfEA8g9svUSbZA4TeoGyWvX8LiN0tJKrzajdMGvTVGqVmDEDp6PBmZmRx9CxswtLht6oWa2Uq4rl5diPsLtqXZeZepMlxUSbaCdlFTB7iWQG9yKXWR5hc0sScevvuVwwsUYdlDEDwlhwZrP07E5fEQKttVMYAiL7edd/eW2yoMGZe6Q95g7yXQ69edVHfQb61fBw3DjCpMDZ5lsxp3BgzXglJwMSKkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQIAWNC7C8DYpwAAAAAAIKpEAAAAAADoAwAAAd7uecGJ8wCYsLpqLrkLOpJYpsf/AQBbCwIA4fUFDBSAzse29bVvUFePc38WLTqxTUZlDQwU3u55wYnzAJiwumouuQs6klimx/8UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQHGDEC4UIzT61GYPx0LdksrF6C2ioYai6fbwpjv3BGAqiyagxiomYGZRLeXZyD67O5FJ86pXRFtSbVYu2YDG+T5ICIgDEDzm/wl+BnHvQXaHQ1rGLtdUMc41wN6I48kPPM7F23gL9sVxGziQIMRLnpTbWHrnzaU9Sy0fXkvIrdJy1KABkSQDEDBwuBuVK+nsZvn1oAscPj6d3FJiUGK9xiHpX9Ipp/5jTnXRBAyzyGc8IZMBVql4WS8kwFe6ojA/9BvFb5eWXnEkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQDYJLwZwNinAAAAAAAgqkQAAAAAAOgDAAAB3u55wYnzAJiwumouuQs6klimx/8BAF8LAwBA2d2ITQoADBSAzse29bVvUFePc38WLTqxTUZlDQwU3u55wYnzAJiwumouuQs6klimx/8UwB8MCHRyYW5zZmVyDBTPduKL0AYsSkeO41VhARMZ88+k0kFifVtSOQHGDEDWn0D7z2ELqpN8ghcM/PtfFwo56/BfEasfHuSKECJMYxvU47r2ZtSihg59lGxSZzHsvxTy6nsyvJ22ycNhINdJDECl61cg937N/HujKsLMu2wJMS7C54bzJ3q22Czqllvw3Yp809USgKDs+W+3QD7rI+SFs0OhIn0gooCUU6f/13WjDEDr9XdeT5CGTO8CL0JigzcTcucs0GBcqHs8fToO6zPuuCfS7Wh6dyxSCijT4A4S+7BUdW3dsO7828ke1fj8oNxmkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQ==" 111 rawblockBytes, _ := base64.StdEncoding.DecodeString(rawblock) 112 113 b := New(false) 114 115 assert.NoError(t, testserdes.DecodeBinary(rawblockBytes, b)) 116 expected := map[string]bool{ // 1 trans 117 "5a30127b16a628de6aa6823418d76214b97a0fc6db865024d3d2c6e939ce3433": false, 118 "25426643feed564cd3e57f346d6c68692f5622b3063da11c5572d99ee1a5b49a": false, 119 } 120 121 var hashes []string 122 123 for _, tx := range b.Transactions { 124 hashes = append(hashes, tx.Hash().StringLE()) 125 } 126 127 assert.Equal(t, len(expected), len(hashes)) 128 129 // changes value in map to true, if hash is found 130 for _, hash := range hashes { 131 expected[hash] = true 132 } 133 134 // iterate map; all values should be true 135 val := true 136 for _, v := range expected { 137 if v == false { 138 val = false 139 } 140 } 141 assert.Equal(t, true, val) 142 143 data, err := testserdes.EncodeBinary(b) 144 assert.NoError(t, err) 145 assert.Equal(t, rawblock, base64.StdEncoding.EncodeToString(data)) 146 147 testserdes.MarshalUnmarshalJSON(t, b, New(false)) 148 } 149 150 func TestJSONEmptyTx(t *testing.T) { 151 jblock := `{"hash":"0x5f3fbb43d1e516fe07771e2e873ebc9e2810662401acf603a775aace486220bd","version":0,"previousblockhash":"0x1f4d1defa46faa5e7b9b8d3f79a06bec777d7c26c4aa5f6f5899a291daa87c15","merkleroot":"0x0000000000000000000000000000000000000000000000000000000000000000","time":1627894840919,"nonce":"BA8E021F1AEEA3F6","index":1,"nextconsensus":"NVg7LjGcUSrgxgjX3zEgqaksfMaiS8Z6e1","primary":0,"witnesses":[{"invocation":"DEAq7W/jUhpMon1t9muqXKfBvNyGwLfFFM1vAxrMKvUl6MqK+LL/lJAJP9uAk/cberIWWhSsdcxUtltkBLemg/VuDECQZGuvP93JlZga2ml8cnbe5cNiGgO0EMrbGYyzvgr8calP5SwMNPSYms10gIHxlsuXDU++EQpZu/vKxfHoxdC5DEDgsA3POVZdfN+i5+ekvtsaIvif42n0GC+dZi3Rp37ETmt4NtkoK2I2UXi+WIjm5yXLJsPhAvEV6cJSrvqBdsQBDEDTS6NU+kB+tgeBe9lWv+6y0L2qcUBIaUxiTCaNWZtLPghQICBvjDz1/9ttJRXG3I5N9CFDjjLKCpdIY842HW4/DEC+wlWjkCzVqzKslvpCKZbEPUGIf87CFAD88xqzl26m/TpTUcT0+D5oI2bVzAk0mcdBTPnyjcNbv17BFmr63+09","verification":"FQwhAkhv0VcCxEkKJnAxEqXMHQkj/Wl6M0Br1aHADgATsJpwDCECTHt/tsMQ/M8bozsIJRnYKWTqk4aNZ2Zi1KWa1UjfDn0MIQKq7DhHD2qtAELG6HfP2Ah9Jnaw9Rb93TYoAbm9OTY5ngwhA7IJ/U9TpxcOpERODLCmu2pTwr0BaSaYnPhfmw+6F6cMDCEDuNnVdx2PUTqghpucyNUJhkA7eMbaNokGOMPUalrc4EoMIQLKDidpe5wkj28W4IX9AGHib0TahbWO6DXBEMql7DulVAwhAt9I9g6PPgHEj/QLm38TENeosqGTGIvv4cLj33QOiVCTF0Ge0Nw6"}],"tx":[]}` 152 b := New(false) 153 require.NoError(t, json.Unmarshal([]byte(jblock), b)) 154 s, err := json.Marshal(b) 155 require.NoError(t, err) 156 require.JSONEq(t, jblock, string(s)) 157 } 158 159 func TestBlockSizeCalculation(t *testing.T) { 160 // block taken from C# privnet: 02d7c7801742cd404eb178780c840477f1eef4a771ecc8cc9434640fe8f2bb09 161 // The Size in golang is given by counting the number of bytes of an object. (len(Bytes)) 162 // its implementation is different from the corresponding C# and python implementations. But the result should 163 // be the same. In this test we provide more details then necessary because in case of failure we can easily debug the 164 // root cause of the size calculation missmatch. 165 166 rawBlock := "AAAAAAwIVa2D6Yha3tArd5XnwkAf7deJBsdyyvpYb2xMZGBbkOUNHAsfre0rKA/F+Ox05/bQSXmcRZnzK3M6Z+/TxJUh0MNFeAEAAAAAAAAAAAAAAQAAAADe7nnBifMAmLC6ai65CzqSWKbH/wHGDEDgwCcXkcaFw5MGOp1cpkgApzDTX2/RxKlmPeXTgWYtfEA8g9svUSbZA4TeoGyWvX8LiN0tJKrzajdMGvTVGqVmDEDp6PBmZmRx9CxswtLht6oWa2Uq4rl5diPsLtqXZeZepMlxUSbaCdlFTB7iWQG9yKXWR5hc0sScevvuVwwsUYdlDEDwlhwZrP07E5fEQKttVMYAiL7edd/eW2yoMGZe6Q95g7yXQ69edVHfQb61fBw3DjCpMDZ5lsxp3BgzXglJwMSKkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQIAWNC7C8DYpwAAAAAAIKpEAAAAAADoAwAAAd7uecGJ8wCYsLpqLrkLOpJYpsf/AQBbCwIA4fUFDBSAzse29bVvUFePc38WLTqxTUZlDQwU3u55wYnzAJiwumouuQs6klimx/8UwB8MCHRyYW5zZmVyDBT1Y+pAvCg9TQ4FxI6jBbPyoHNA70FifVtSOQHGDEC4UIzT61GYPx0LdksrF6C2ioYai6fbwpjv3BGAqiyagxiomYGZRLeXZyD67O5FJ86pXRFtSbVYu2YDG+T5ICIgDEDzm/wl+BnHvQXaHQ1rGLtdUMc41wN6I48kPPM7F23gL9sVxGziQIMRLnpTbWHrnzaU9Sy0fXkvIrdJy1KABkSQDEDBwuBuVK+nsZvn1oAscPj6d3FJiUGK9xiHpX9Ipp/5jTnXRBAyzyGc8IZMBVql4WS8kwFe6ojA/9BvFb5eWXnEkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQDYJLwZwNinAAAAAAAgqkQAAAAAAOgDAAAB3u55wYnzAJiwumouuQs6klimx/8BAF8LAwBA2d2ITQoADBSAzse29bVvUFePc38WLTqxTUZlDQwU3u55wYnzAJiwumouuQs6klimx/8UwB8MCHRyYW5zZmVyDBTPduKL0AYsSkeO41VhARMZ88+k0kFifVtSOQHGDEDWn0D7z2ELqpN8ghcM/PtfFwo56/BfEasfHuSKECJMYxvU47r2ZtSihg59lGxSZzHsvxTy6nsyvJ22ycNhINdJDECl61cg937N/HujKsLMu2wJMS7C54bzJ3q22Czqllvw3Yp809USgKDs+W+3QD7rI+SFs0OhIn0gooCUU6f/13WjDEDr9XdeT5CGTO8CL0JigzcTcucs0GBcqHs8fToO6zPuuCfS7Wh6dyxSCijT4A4S+7BUdW3dsO7828ke1fj8oNxmkxMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRRBe85spQ==" 167 rawBlockBytes, _ := base64.StdEncoding.DecodeString(rawBlock) 168 169 b := New(false) 170 assert.NoError(t, testserdes.DecodeBinary(rawBlockBytes, b)) 171 172 expected := []struct { 173 ID string 174 Size int 175 Version int 176 SignersLen int 177 AttributesLen int 178 WitnessesLen int 179 }{ // 2 transactions 180 {ID: "5a30127b16a628de6aa6823418d76214b97a0fc6db865024d3d2c6e939ce3433", Size: 488, Version: 0, SignersLen: 1, AttributesLen: 0, WitnessesLen: 1}, 181 {ID: "25426643feed564cd3e57f346d6c68692f5622b3063da11c5572d99ee1a5b49a", Size: 492, Version: 0, SignersLen: 1, AttributesLen: 0, WitnessesLen: 1}, 182 } 183 184 for i, tx := range b.Transactions { 185 txID := tx.Hash() 186 assert.Equal(t, expected[i].ID, txID.StringLE()) 187 188 assert.Equal(t, expected[i].Size, io.GetVarSize(tx)) 189 assert.Equal(t, expected[i].Version, int(tx.Version)) 190 assert.Equal(t, expected[i].SignersLen, len(tx.Signers)) 191 assert.Equal(t, expected[i].AttributesLen, len(tx.Attributes)) 192 assert.Equal(t, expected[i].WitnessesLen, len(tx.Scripts)) 193 } 194 195 assert.Equal(t, len(expected), len(b.Transactions)) 196 197 // Block specific tests 198 assert.Equal(t, 0, int(b.Version)) 199 assert.Equal(t, "5b60644c6c6f58faca72c70689d7ed1f40c2e795772bd0de5a88e983ad55080c", b.PrevHash.StringLE()) 200 assert.Equal(t, "95c4d3ef673a732bf399459c7949d0f6e774ecf8c50f282bedad1f0b1c0de590", b.MerkleRoot.StringLE()) 201 assert.Equal(t, 1616078164001, int(b.Timestamp)) 202 assert.Equal(t, 1, int(b.Index)) 203 204 nextConsensus := address.Uint160ToString(b.NextConsensus) 205 assert.Equal(t, "NgEisvCqr2h8wpRxQb7bVPWUZdbVCY8Uo6", nextConsensus) 206 207 assert.Equal(t, "DEDgwCcXkcaFw5MGOp1cpkgApzDTX2/RxKlmPeXTgWYtfEA8g9svUSbZA4TeoGyWvX8LiN0tJKrzajdMGvTVGqVmDEDp6PBmZmRx9CxswtLht6oWa2Uq4rl5diPsLtqXZeZepMlxUSbaCdlFTB7iWQG9yKXWR5hc0sScevvuVwwsUYdlDEDwlhwZrP07E5fEQKttVMYAiL7edd/eW2yoMGZe6Q95g7yXQ69edVHfQb61fBw3DjCpMDZ5lsxp3BgzXglJwMSK", base64.StdEncoding.EncodeToString(b.Script.InvocationScript)) 208 assert.Equal(t, "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl", base64.StdEncoding.EncodeToString(b.Script.VerificationScript)) 209 assert.Equal(t, "0285238e7b5d3ca50ae8f8636dedb4fa486bc0536016e1f1edfd74442af7412e", b.Hash().StringLE()) 210 211 benc, err := testserdes.EncodeBinary(b) 212 assert.NoError(t, err) 213 // test size of the block 214 assert.Equal(t, 1438, len(benc)) 215 assert.Equal(t, rawBlock, base64.StdEncoding.EncodeToString(benc)) 216 } 217 218 func TestBlockEncodeDecode(t *testing.T) { 219 t.Run("positive", func(t *testing.T) { 220 b := newDumbBlock() 221 b.Transactions = []*transaction.Transaction{} 222 _ = b.Hash() 223 testserdes.EncodeDecodeBinary(t, b, new(Block)) 224 }) 225 226 t.Run("bad contents count", func(t *testing.T) { 227 b := newDumbBlock() 228 b.Transactions = make([]*transaction.Transaction, MaxTransactionsPerBlock+1) 229 for i := range b.Transactions { 230 b.Transactions[i] = &transaction.Transaction{ 231 Script: []byte("my_pretty_script"), 232 } 233 } 234 _ = b.Hash() 235 data, err := testserdes.EncodeBinary(b) 236 require.NoError(t, err) 237 238 require.ErrorIs(t, testserdes.DecodeBinary(data, new(Block)), ErrMaxContentsPerBlock) 239 }) 240 } 241 242 func TestGetExpectedBlockSize(t *testing.T) { 243 check := func(t *testing.T, stateRootEnabled bool) { 244 t.Run("without transactions", func(t *testing.T) { 245 b := newDumbBlock() 246 b.StateRootEnabled = stateRootEnabled 247 b.Transactions = []*transaction.Transaction{} 248 require.Equal(t, io.GetVarSize(b), b.GetExpectedBlockSize()) 249 require.Equal(t, io.GetVarSize(b), b.GetExpectedBlockSizeWithoutTransactions(0)) 250 }) 251 t.Run("with one transaction", func(t *testing.T) { 252 b := newDumbBlock() 253 b.StateRootEnabled = stateRootEnabled 254 expected := io.GetVarSize(b) 255 require.Equal(t, expected, b.GetExpectedBlockSize()) 256 require.Equal(t, expected-b.Transactions[0].Size(), b.GetExpectedBlockSizeWithoutTransactions(len(b.Transactions))) 257 }) 258 t.Run("with multiple transactions", func(t *testing.T) { 259 b := newDumbBlock() 260 b.StateRootEnabled = stateRootEnabled 261 b.Transactions = make([]*transaction.Transaction, 123) 262 for i := range b.Transactions { 263 tx := transaction.New([]byte{byte(opcode.RET)}, int64(i)) 264 tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}} 265 tx.Scripts = []transaction.Witness{{}} 266 b.Transactions[i] = tx 267 } 268 expected := io.GetVarSize(b) 269 require.Equal(t, expected, b.GetExpectedBlockSize()) 270 for _, tx := range b.Transactions { 271 expected -= tx.Size() 272 } 273 require.Equal(t, expected, b.GetExpectedBlockSizeWithoutTransactions(len(b.Transactions))) 274 }) 275 } 276 t.Run("StateRoot enabled", func(t *testing.T) { 277 check(t, true) 278 }) 279 t.Run("StateRoot disabled", func(t *testing.T) { 280 check(t, false) 281 }) 282 }