github.com/ledgerwatch/erigon-lib@v1.0.0/commitment/hex_patricia_hashed_test.go (about)

     1  /*
     2     Copyright 2022 Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package commitment
    18  
    19  import (
    20  	"encoding/hex"
    21  	"fmt"
    22  	"math/rand"
    23  	"testing"
    24  
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"github.com/ledgerwatch/erigon-lib/common/length"
    28  )
    29  
    30  func Test_HexPatriciaHashed_ResetThenSingularUpdates(t *testing.T) {
    31  	ms := NewMockState(t)
    32  	hph := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
    33  	hph.SetTrace(false)
    34  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
    35  		Balance("00", 4).
    36  		Balance("01", 5).
    37  		Balance("02", 6).
    38  		Balance("03", 7).
    39  		Balance("04", 8).
    40  		Storage("04", "01", "0401").
    41  		Storage("03", "56", "050505").
    42  		Storage("03", "57", "060606").
    43  		Balance("05", 9).
    44  		Storage("05", "02", "8989").
    45  		Storage("05", "04", "9898").
    46  		Build()
    47  
    48  	err := ms.applyPlainUpdates(plainKeys, updates)
    49  	require.NoError(t, err)
    50  
    51  	firstRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
    52  	require.NoError(t, err)
    53  
    54  	t.Logf("root hash %x\n", firstRootHash)
    55  
    56  	ms.applyBranchNodeUpdates(branchNodeUpdates)
    57  
    58  	fmt.Printf("1. Generated updates\n")
    59  	renderUpdates(branchNodeUpdates)
    60  
    61  	// More updates
    62  	hph.Reset()
    63  	hph.SetTrace(false)
    64  	plainKeys, hashedKeys, updates = NewUpdateBuilder().
    65  		Storage("03", "58", "050505").
    66  		Build()
    67  	err = ms.applyPlainUpdates(plainKeys, updates)
    68  	require.NoError(t, err)
    69  
    70  	secondRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
    71  	require.NoError(t, err)
    72  	require.NotEqualValues(t, firstRootHash, secondRootHash)
    73  
    74  	ms.applyBranchNodeUpdates(branchNodeUpdates)
    75  	fmt.Printf("2. Generated single update\n")
    76  	renderUpdates(branchNodeUpdates)
    77  
    78  	// More updates
    79  	hph.Reset()
    80  	hph.SetTrace(false)
    81  	plainKeys, hashedKeys, updates = NewUpdateBuilder().
    82  		Storage("03", "58", "070807").
    83  		Build()
    84  	err = ms.applyPlainUpdates(plainKeys, updates)
    85  	require.NoError(t, err)
    86  
    87  	thirdRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
    88  	require.NoError(t, err)
    89  	require.NotEqualValues(t, secondRootHash, thirdRootHash)
    90  
    91  	ms.applyBranchNodeUpdates(branchNodeUpdates)
    92  	fmt.Printf("3. Generated single update\n")
    93  	renderUpdates(branchNodeUpdates)
    94  }
    95  
    96  func Test_HexPatriciaHashed_EmptyUpdate(t *testing.T) {
    97  	ms := NewMockState(t)
    98  	hph := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
    99  	hph.SetTrace(false)
   100  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   101  		Balance("00", 4).
   102  		Nonce("00", 246462653).
   103  		Balance("01", 5).
   104  		CodeHash("03", "aaaaaaaaaaf7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a870").
   105  		Delete("00").
   106  		Storage("04", "01", "0401").
   107  		Storage("03", "56", "050505").
   108  		Build()
   109  
   110  	err := ms.applyPlainUpdates(plainKeys, updates)
   111  	require.NoError(t, err)
   112  
   113  	hashBeforeEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   114  	require.NoError(t, err)
   115  	require.NotEmpty(t, hashBeforeEmptyUpdate)
   116  
   117  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   118  
   119  	fmt.Println("1. Updates applied")
   120  	renderUpdates(branchNodeUpdates)
   121  
   122  	// generate empty updates and do NOT reset tree
   123  	hph.SetTrace(true)
   124  
   125  	plainKeys, hashedKeys, updates = NewUpdateBuilder().Build()
   126  
   127  	err = ms.applyPlainUpdates(plainKeys, updates)
   128  	require.NoError(t, err)
   129  
   130  	hashAfterEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   131  	require.NoError(t, err)
   132  
   133  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   134  	fmt.Println("2. Empty updates applied without state reset")
   135  
   136  	require.EqualValues(t, hashBeforeEmptyUpdate, hashAfterEmptyUpdate)
   137  }
   138  
   139  func Test_HexPatriciaHashed_UniqueRepresentation(t *testing.T) {
   140  	ms := NewMockState(t)
   141  	ms2 := NewMockState(t)
   142  
   143  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   144  		Balance("f5", 4).
   145  		Balance("ff", 900234).
   146  		Balance("04", 1233).
   147  		Storage("04", "01", "0401").
   148  		Balance("ba", 065606).
   149  		Balance("00", 4).
   150  		Balance("01", 5).
   151  		Balance("02", 6).
   152  		Balance("03", 7).
   153  		Storage("03", "56", "050505").
   154  		Balance("05", 9).
   155  		Storage("03", "87", "060606").
   156  		Balance("b9", 6).
   157  		Nonce("ff", 169356).
   158  		Storage("05", "02", "8989").
   159  		Storage("f5", "04", "9898").
   160  		Build()
   161  
   162  	trieOne := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   163  	trieTwo := NewHexPatriciaHashed(1, ms2.branchFn, ms2.accountFn, ms2.storageFn)
   164  
   165  	trieOne.SetTrace(true)
   166  	trieTwo.SetTrace(true)
   167  
   168  	// single sequential update
   169  	roots := make([][]byte, 0)
   170  	// branchNodeUpdatesOne := make(map[string]BranchData)
   171  	fmt.Printf("1. Trie sequential update generated following branch updates\n")
   172  	for i := 0; i < len(updates); i++ {
   173  		if err := ms.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1]); err != nil {
   174  			t.Fatal(err)
   175  		}
   176  
   177  		sequentialRoot, branchNodeUpdates, err := trieOne.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1])
   178  		require.NoError(t, err)
   179  		roots = append(roots, sequentialRoot)
   180  
   181  		ms.applyBranchNodeUpdates(branchNodeUpdates)
   182  		renderUpdates(branchNodeUpdates)
   183  	}
   184  
   185  	err := ms2.applyPlainUpdates(plainKeys, updates)
   186  	require.NoError(t, err)
   187  
   188  	fmt.Printf("\n2. Trie batch update generated following branch updates\n")
   189  	// batch update
   190  	batchRoot, branchNodeUpdatesTwo, err := trieTwo.ReviewKeys(plainKeys, hashedKeys)
   191  	require.NoError(t, err)
   192  	renderUpdates(branchNodeUpdatesTwo)
   193  
   194  	fmt.Printf("\n sequential roots:\n")
   195  	for i, rh := range roots {
   196  		fmt.Printf("%2d %+v\n", i, hex.EncodeToString(rh))
   197  	}
   198  
   199  	ms2.applyBranchNodeUpdates(branchNodeUpdatesTwo)
   200  
   201  	require.EqualValues(t, batchRoot, roots[len(roots)-1],
   202  		"expected equal roots, got sequential [%v] != batch [%v]", hex.EncodeToString(roots[len(roots)-1]), hex.EncodeToString(batchRoot))
   203  	require.Lenf(t, batchRoot, 32, "root hash length should be equal to 32 bytes")
   204  }
   205  
   206  func Test_Sepolia(t *testing.T) {
   207  	ms := NewMockState(t)
   208  
   209  	type TestData struct {
   210  		balances     map[string][]byte
   211  		expectedRoot string
   212  	}
   213  
   214  	tests := []TestData{
   215  		{
   216  			expectedRoot: "5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494",
   217  			balances: map[string][]byte{
   218  				"a2a6d93439144ffe4d27c9e088dcd8b783946263": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   219  				"bc11295936aa79d594139de1b2e12629414f3bdb": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   220  				"7cf5b79bfe291a67ab02b393e456ccc4c266f753": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   221  				"aaec86394441f915bce3e6ab399977e9906f3b69": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   222  				"f47cae1cf79ca6758bfc787dbd21e6bdbe7112b8": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   223  				"d7eddb78ed295b3c9629240e8924fb8d8874ddd8": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   224  				"8b7f0977bb4f0fbe7076fa22bc24aca043583f5e": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   225  				"e2e2659028143784d557bcec6ff3a0721048880a": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   226  				"d9a5179f091d85051d3c982785efd1455cec8699": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   227  				"beef32ca5b9a198d27b4e02f4c70439fe60356cf": {0xd3, 0xc2, 0x1b, 0xce, 0xcc, 0xed, 0xa1, 0x00, 0x00, 0x00},
   228  				"0000006916a87b82333f4245046623b23794c65c": {0x08, 0x45, 0x95, 0x16, 0x14, 0x01, 0x48, 0x4a, 0x00, 0x00, 0x00},
   229  				"b21c33de1fab3fa15499c62b59fe0cc3250020d1": {0x52, 0xb7, 0xd2, 0xdc, 0xc8, 0x0c, 0xd2, 0xe4, 0x00, 0x00, 0x00},
   230  				"10f5d45854e038071485ac9e402308cf80d2d2fe": {0x52, 0xb7, 0xd2, 0xdc, 0xc8, 0x0c, 0xd2, 0xe4, 0x00, 0x00, 0x00},
   231  				"d7d76c58b3a519e9fa6cc4d22dc017259bc49f1e": {0x52, 0xb7, 0xd2, 0xdc, 0xc8, 0x0c, 0xd2, 0xe4, 0x00, 0x00, 0x00},
   232  				"799d329e5f583419167cd722962485926e338f4a": {0x0d, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00},
   233  			},
   234  		},
   235  		{
   236  			expectedRoot: "c91d4ecd59dce3067d340b3aadfc0542974b4fb4db98af39f980a91ea00db9dc",
   237  			balances: map[string][]byte{
   238  				"2f14582947e292a2ecd20c430b46f2d27cfe213c": {0x1B, 0xC1, 0x6D, 0x67, 0x4E, 0xC8, 0x00, 0x00},
   239  			},
   240  		},
   241  		{
   242  			expectedRoot: "c91d4ecd59dce3067d340b3aadfc0542974b4fb4db98af39f980a91ea00db9dc",
   243  			balances:     map[string][]byte{},
   244  		},
   245  	}
   246  
   247  	hph := NewHexPatriciaHashed(length.Addr, ms.branchFn, ms.accountFn, ms.storageFn)
   248  	hph.SetTrace(true)
   249  
   250  	for _, testData := range tests {
   251  		builder := NewUpdateBuilder()
   252  
   253  		for address, balance := range testData.balances {
   254  			builder.IncrementBalance(address, balance)
   255  		}
   256  		plainKeys, hashedKeys, updates := builder.Build()
   257  
   258  		if err := ms.applyPlainUpdates(plainKeys, updates); err != nil {
   259  			t.Fatal(err)
   260  		}
   261  
   262  		rootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   263  		if err != nil {
   264  			t.Fatal(err)
   265  		}
   266  		ms.applyBranchNodeUpdates(branchNodeUpdates)
   267  
   268  		require.EqualValues(t, testData.expectedRoot, fmt.Sprintf("%x", rootHash))
   269  	}
   270  }
   271  
   272  func Test_HexPatriciaHashed_StateEncode(t *testing.T) {
   273  	//trie := NewHexPatriciaHashed(length.Hash, nil, nil, nil)
   274  	var s state
   275  	s.Root = make([]byte, 128)
   276  	rnd := rand.New(rand.NewSource(42))
   277  	n, err := rnd.Read(s.CurrentKey[:])
   278  	require.NoError(t, err)
   279  	require.EqualValues(t, 128, n)
   280  	n, err = rnd.Read(s.Root[:])
   281  	require.NoError(t, err)
   282  	require.EqualValues(t, len(s.Root), n)
   283  	s.RootPresent = true
   284  	s.RootTouched = true
   285  	s.RootChecked = true
   286  
   287  	s.CurrentKeyLen = int8(rnd.Intn(129))
   288  	for i := 0; i < len(s.Depths); i++ {
   289  		s.Depths[i] = rnd.Intn(256)
   290  	}
   291  	for i := 0; i < len(s.TouchMap); i++ {
   292  		s.TouchMap[i] = uint16(rnd.Intn(1<<16 - 1))
   293  	}
   294  	for i := 0; i < len(s.AfterMap); i++ {
   295  		s.AfterMap[i] = uint16(rnd.Intn(1<<16 - 1))
   296  	}
   297  	for i := 0; i < len(s.BranchBefore); i++ {
   298  		if rnd.Intn(100) > 49 {
   299  			s.BranchBefore[i] = true
   300  		}
   301  	}
   302  
   303  	enc, err := s.Encode(nil)
   304  	require.NoError(t, err)
   305  	require.NotEmpty(t, enc)
   306  
   307  	var s1 state
   308  	err = s1.Decode(enc)
   309  	require.NoError(t, err)
   310  
   311  	require.EqualValues(t, s.Root[:], s1.Root[:])
   312  	require.EqualValues(t, s.Depths[:], s1.Depths[:])
   313  	require.EqualValues(t, s.CurrentKeyLen, s1.CurrentKeyLen)
   314  	require.EqualValues(t, s.CurrentKey[:], s1.CurrentKey[:])
   315  	require.EqualValues(t, s.AfterMap[:], s1.AfterMap[:])
   316  	require.EqualValues(t, s.TouchMap[:], s1.TouchMap[:])
   317  	require.EqualValues(t, s.BranchBefore[:], s1.BranchBefore[:])
   318  	require.EqualValues(t, s.RootTouched, s1.RootTouched)
   319  	require.EqualValues(t, s.RootPresent, s1.RootPresent)
   320  	require.EqualValues(t, s.RootChecked, s1.RootChecked)
   321  }
   322  
   323  func Test_HexPatriciaHashed_StateEncodeDecodeSetup(t *testing.T) {
   324  	ms := NewMockState(t)
   325  
   326  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   327  		Balance("f5", 4).
   328  		Balance("ff", 900234).
   329  		Balance("03", 7).
   330  		Storage("03", "56", "050505").
   331  		Balance("05", 9).
   332  		Storage("03", "87", "060606").
   333  		Balance("b9", 6).
   334  		Nonce("ff", 169356).
   335  		Storage("05", "02", "8989").
   336  		Storage("f5", "04", "9898").
   337  		Build()
   338  
   339  	before := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   340  	after := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   341  
   342  	err := ms.applyPlainUpdates(plainKeys, updates)
   343  	require.NoError(t, err)
   344  
   345  	rhBefore, branchUpdates, err := before.ReviewKeys(plainKeys, hashedKeys)
   346  	require.NoError(t, err)
   347  	ms.applyBranchNodeUpdates(branchUpdates)
   348  
   349  	state, err := before.EncodeCurrentState(nil)
   350  	require.NoError(t, err)
   351  
   352  	err = after.SetState(state)
   353  	require.NoError(t, err)
   354  
   355  	rhAfter, err := after.RootHash()
   356  	require.NoError(t, err)
   357  	require.EqualValues(t, rhBefore, rhAfter)
   358  
   359  	// create new update and apply it to both tries
   360  	nextPK, nextHashed, nextUpdates := NewUpdateBuilder().
   361  		Nonce("ff", 4).
   362  		Balance("b9", 6000000000).
   363  		Balance("ad", 8000000000).
   364  		Build()
   365  
   366  	err = ms.applyPlainUpdates(nextPK, nextUpdates)
   367  	require.NoError(t, err)
   368  
   369  	rh2Before, branchUpdates, err := before.ReviewKeys(nextPK, nextHashed)
   370  	require.NoError(t, err)
   371  	ms.applyBranchNodeUpdates(branchUpdates)
   372  
   373  	rh2After, branchUpdates, err := after.ReviewKeys(nextPK, nextHashed)
   374  	require.NoError(t, err)
   375  
   376  	_ = branchUpdates
   377  
   378  	require.EqualValues(t, rh2Before, rh2After)
   379  }
   380  
   381  func Test_HexPatriciaHashed_RestoreAndContinue(t *testing.T) {
   382  	ms := NewMockState(t)
   383  	ms2 := NewMockState(t)
   384  
   385  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   386  		Balance("f5", 4).
   387  		Balance("ff", 900234).
   388  		Balance("04", 1233).
   389  		Storage("04", "01", "0401").
   390  		Balance("ba", 065606).
   391  		Balance("00", 4).
   392  		Balance("01", 5).
   393  		Balance("02", 6).
   394  		Balance("03", 7).
   395  		Storage("03", "56", "050505").
   396  		Balance("05", 9).
   397  		Storage("03", "87", "060606").
   398  		Balance("b9", 6).
   399  		Nonce("ff", 169356).
   400  		Storage("05", "02", "8989").
   401  		Storage("f5", "04", "9898").
   402  		Build()
   403  
   404  	trieOne := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   405  	trieTwo := NewHexPatriciaHashed(1, ms2.branchFn, ms2.accountFn, ms2.storageFn)
   406  
   407  	err := ms2.applyPlainUpdates(plainKeys, updates)
   408  	require.NoError(t, err)
   409  
   410  	_ = updates
   411  
   412  	batchRoot, branchNodeUpdatesTwo, err := trieTwo.ReviewKeys(plainKeys, hashedKeys)
   413  	require.NoError(t, err)
   414  	renderUpdates(branchNodeUpdatesTwo)
   415  	ms2.applyBranchNodeUpdates(branchNodeUpdatesTwo)
   416  
   417  	buf, err := trieTwo.EncodeCurrentState(nil)
   418  	require.NoError(t, err)
   419  	require.NotEmpty(t, buf)
   420  
   421  	err = trieOne.SetState(buf)
   422  	require.NoError(t, err)
   423  	require.EqualValues(t, batchRoot[:], trieOne.root.h[:])
   424  	require.EqualValues(t, trieTwo.root.hl, trieOne.root.hl)
   425  	require.EqualValues(t, trieTwo.root.apl, trieOne.root.apl)
   426  	if trieTwo.root.apl > 0 {
   427  		require.EqualValues(t, trieTwo.root.apk, trieOne.root.apk)
   428  	}
   429  	require.EqualValues(t, trieTwo.root.spl, trieOne.root.spl)
   430  	if trieTwo.root.apl > 0 {
   431  		require.EqualValues(t, trieTwo.root.spk, trieOne.root.spk)
   432  	}
   433  	if trieTwo.root.downHashedLen > 0 {
   434  		require.EqualValues(t, trieTwo.root.downHashedKey, trieOne.root.downHashedKey)
   435  	}
   436  	require.EqualValues(t, trieTwo.root.Nonce, trieOne.root.Nonce)
   437  	//require.EqualValues(t, trieTwo.root.CodeHash, trieOne.root.CodeHash)
   438  	require.EqualValues(t, trieTwo.root.StorageLen, trieOne.root.StorageLen)
   439  	require.EqualValues(t, trieTwo.root.extension, trieOne.root.extension)
   440  
   441  	require.EqualValues(t, trieTwo.currentKey, trieOne.currentKey)
   442  	require.EqualValues(t, trieTwo.afterMap, trieOne.afterMap)
   443  	require.EqualValues(t, trieTwo.touchMap[:], trieOne.touchMap[:])
   444  	require.EqualValues(t, trieTwo.branchBefore[:], trieOne.branchBefore[:])
   445  	require.EqualValues(t, trieTwo.rootTouched, trieOne.rootTouched)
   446  	require.EqualValues(t, trieTwo.rootPresent, trieOne.rootPresent)
   447  	require.EqualValues(t, trieTwo.rootChecked, trieOne.rootChecked)
   448  	require.EqualValues(t, trieTwo.currentKeyLen, trieOne.currentKeyLen)
   449  }
   450  
   451  func Test_HexPatriciaHashed_ProcessUpdates_UniqueRepresentation_AfterStateRestore(t *testing.T) {
   452  	ms := NewMockState(t)
   453  	ms2 := NewMockState(t)
   454  
   455  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   456  		Balance("f5", 4).
   457  		Balance("ff", 900234).
   458  		Balance("04", 1233).
   459  		Storage("04", "01", "0401").
   460  		Balance("ba", 065606).
   461  		Balance("00", 4).
   462  		Balance("01", 5).
   463  		Balance("02", 6).
   464  		Balance("03", 7).
   465  		Storage("03", "56", "050505").
   466  		Balance("05", 9).
   467  		Storage("03", "87", "060606").
   468  		Balance("b9", 6).
   469  		Nonce("ff", 169356).
   470  		Storage("05", "02", "8989").
   471  		Storage("f5", "04", "9898").
   472  		Build()
   473  
   474  	sequential := NewHexPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   475  	batch := NewHexPatriciaHashed(1, ms2.branchFn, ms2.accountFn, ms2.storageFn)
   476  
   477  	batch.Reset()
   478  	sequential.Reset()
   479  	sequential.SetTrace(true)
   480  	batch.SetTrace(true)
   481  
   482  	// single sequential update
   483  	roots := make([][]byte, 0)
   484  	prevState := make([]byte, 0)
   485  	fmt.Printf("1. Trie sequential update generated following branch updates\n")
   486  	for i := 0; i < len(updates); i++ {
   487  		if err := ms.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1]); err != nil {
   488  			t.Fatal(err)
   489  		}
   490  		if i == (len(updates) / 2) {
   491  			sequential.Reset()
   492  			sequential.ResetFns(ms.branchFn, ms.accountFn, ms.storageFn)
   493  			err := sequential.SetState(prevState)
   494  			require.NoError(t, err)
   495  		}
   496  
   497  		sequentialRoot, branchNodeUpdates, err := sequential.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1])
   498  		require.NoError(t, err)
   499  		roots = append(roots, sequentialRoot)
   500  
   501  		renderUpdates(branchNodeUpdates)
   502  		ms.applyBranchNodeUpdates(branchNodeUpdates)
   503  
   504  		if i == (len(updates)/2 - 1) {
   505  			prevState, err = sequential.EncodeCurrentState(nil)
   506  			require.NoError(t, err)
   507  		}
   508  	}
   509  
   510  	err := ms2.applyPlainUpdates(plainKeys, updates)
   511  	require.NoError(t, err)
   512  
   513  	fmt.Printf("\n2. Trie batch update generated following branch updates\n")
   514  	// batch update
   515  	batchRoot, branchNodeUpdatesTwo, err := batch.ReviewKeys(plainKeys, hashedKeys)
   516  	require.NoError(t, err)
   517  	renderUpdates(branchNodeUpdatesTwo)
   518  	ms2.applyBranchNodeUpdates(branchNodeUpdatesTwo)
   519  
   520  	require.EqualValues(t, batchRoot, roots[len(roots)-1],
   521  		"expected equal roots, got sequential [%v] != batch [%v]", hex.EncodeToString(roots[len(roots)-1]), hex.EncodeToString(batchRoot))
   522  	require.Lenf(t, batchRoot, 32, "root hash length should be equal to 32 bytes")
   523  }