diff --git a/chain/block.go b/chain/block.go index 2a10ae17bb..71a8fe2152 100644 --- a/chain/block.go +++ b/chain/block.go @@ -293,7 +293,7 @@ func (b *StatelessBlock) initializeBuilt( } // transaction hash generation - var merkleItems [][]byte + var merkleItems [][]byte = make([][]byte, 0, len(b.Txs)+len(b.results)) for _, tx := range b.Txs { merkleItems = append(merkleItems, tx.Bytes()) } @@ -301,7 +301,8 @@ func (b *StatelessBlock) initializeBuilt( merkleItems = append(merkleItems, result.Output) } - root, _, err := utils.GenerateMerkleRoot(ctx, b.vm.Tracer(), merkleItems) + // consume bytes to avoid extra copying + root, _, err := utils.GenerateMerkleRoot(ctx, b.vm.Tracer(), merkleItems, true) if err != nil { return err } diff --git a/utils/utils.go b/utils/utils.go index 86384e1034..0417fc00f4 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -125,8 +125,8 @@ func LoadBytes(filename string, expectedSize int) ([]byte, error) { // Generate merkle root for a set of items // this function does not take ownership of given bytes array -func GenerateMerkleRoot(ctx context.Context, tracer trace.Tracer, merkleItems [][]byte) ([]byte, merkledb.MerkleDB, error) { - var batchOps []database.BatchOp +func GenerateMerkleRoot(ctx context.Context, tracer trace.Tracer, merkleItems [][]byte, consumeBytes bool) ([]byte, merkledb.MerkleDB, error) { + var batchOps []database.BatchOp = make([]database.BatchOp, 0, len(merkleItems)) for _, item := range merkleItems { key := ToID(item) @@ -148,7 +148,7 @@ func GenerateMerkleRoot(ctx context.Context, tracer trace.Tracer, merkleItems [] return nil, nil, err } - view, err := db.NewView(ctx, merkledb.ViewChanges{BatchOps: batchOps}) + view, err := db.NewView(ctx, merkledb.ViewChanges{BatchOps: batchOps, ConsumeBytes: consumeBytes}) if err != nil { return nil, nil, err }