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

     1  package commitment
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  	"golang.org/x/exp/slices"
    10  
    11  	"github.com/ledgerwatch/erigon-lib/common/length"
    12  )
    13  
    14  func Test_BinPatriciaTrie_UniqueRepresentation(t *testing.T) {
    15  	t.Skip()
    16  
    17  	ms := NewMockState(t)
    18  	ms2 := NewMockState(t)
    19  
    20  	trie := NewBinPatriciaHashed(length.Addr, ms.branchFn, ms.accountFn, ms.storageFn)
    21  	trieBatch := NewBinPatriciaHashed(length.Addr, ms2.branchFn, ms2.accountFn, ms2.storageFn)
    22  
    23  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
    24  		Balance("e25652aaa6b9417973d325f9a1246b48ff9420bf", 12).
    25  		Balance("cdd0a12034e978f7eccda72bd1bd89a8142b704e", 120000).
    26  		Balance("5bb6abae12c87592b940458437526cb6cad60d50", 170).
    27  		Nonce("5bb6abae12c87592b940458437526cb6cad60d50", 152512).
    28  		Balance("2fcb355beb0ea2b5fcf3b62a24e2faaff1c8d0c0", 100000).
    29  		Balance("463510be61a7ccde354509c0ab813e599ee3fc8a", 200000).
    30  		Balance("cd3e804beea486038609f88f399140dfbe059ef3", 200000).
    31  		Storage("cd3e804beea486038609f88f399140dfbe059ef3", "01023402", "98").
    32  		Balance("82c88c189d5deeba0ad11463b80b44139bd519c1", 300000).
    33  		Balance("0647e43e8f9ba3fb8b14ad30796b7553d667c858", 400000).
    34  		Delete("cdd0a12034e978f7eccda72bd1bd89a8142b704e").
    35  		Balance("06548d648c23b12f2e9bfd1bae274b658be208f4", 500000).
    36  		Balance("e5417f49640cf8a0b1d6e38f9dfdc00196e99e8b", 600000).
    37  		Nonce("825ac9fa5d015ec7c6b4cbbc50f78d619d255ea7", 184).
    38  		Build()
    39  
    40  	ms.applyPlainUpdates(plainKeys, updates)
    41  	ms2.applyPlainUpdates(plainKeys, updates)
    42  
    43  	fmt.Println("1. Running sequential updates over the bin trie")
    44  	var seqHash []byte
    45  	for i := 0; i < len(updates); i++ {
    46  		sh, branchNodeUpdates, err := trie.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1])
    47  		require.NoError(t, err)
    48  		require.Len(t, sh, length.Hash)
    49  		ms.applyBranchNodeUpdates(branchNodeUpdates)
    50  		// WARN! provided sequential branch updates are incorrect - lead to deletion of prefixes (afterMap is zero)
    51  		//       while root hashes are equal
    52  		renderUpdates(branchNodeUpdates)
    53  
    54  		fmt.Printf("h=%x\n", sh)
    55  		seqHash = sh
    56  	}
    57  
    58  	fmt.Println("2. Running batch updates over the bin trie")
    59  
    60  	batchHash, branchBatchUpdates, err := trieBatch.ReviewKeys(plainKeys, hashedKeys)
    61  	require.NoError(t, err)
    62  	ms2.applyBranchNodeUpdates(branchBatchUpdates)
    63  
    64  	renderUpdates(branchBatchUpdates)
    65  
    66  	require.EqualValues(t, seqHash, batchHash)
    67  	// require.EqualValues(t, seqHash, batchHash)
    68  
    69  	// expectedHash, _ := hex.DecodeString("3ed2b89c0f9c6ebc7fa11a181baac21aa0236b12bb4492c708562cb3e40c7c9e")
    70  	// require.EqualValues(t, expectedHash, seqHash)
    71  }
    72  
    73  func renderUpdates(branchNodeUpdates map[string]BranchData) {
    74  	keys := make([]string, 0, len(branchNodeUpdates))
    75  	for key := range branchNodeUpdates {
    76  		keys = append(keys, key)
    77  	}
    78  	slices.Sort(keys)
    79  	for _, key := range keys {
    80  		branchNodeUpdate := branchNodeUpdates[key]
    81  		fmt.Printf("%x => %s\n", CompactedKeyToHex([]byte(key)), branchNodeUpdate.String())
    82  	}
    83  }
    84  
    85  func Test_BinPatriciaHashed_UniqueRepresentation(t *testing.T) {
    86  	t.Skip()
    87  
    88  	ms := NewMockState(t)
    89  	ms2 := NewMockState(t)
    90  
    91  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
    92  		Balance("f5", 4).
    93  		Balance("ff", 900234).
    94  		Balance("04", 1233).
    95  		Storage("04", "01", "0401").
    96  		Balance("ba", 065606).
    97  		Balance("00", 4).
    98  		Balance("01", 5).
    99  		Balance("02", 6).
   100  		Balance("03", 7).
   101  		Storage("03", "56", "050505").
   102  		Balance("05", 9).
   103  		Storage("03", "87", "060606").
   104  		Balance("b9", 6).
   105  		Nonce("ff", 169356).
   106  		Storage("05", "02", "8989").
   107  		Storage("f5", "04", "9898").
   108  		Build()
   109  
   110  	trieOne := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   111  	trieTwo := NewBinPatriciaHashed(1, ms2.branchFn, ms2.accountFn, ms2.storageFn)
   112  
   113  	trieOne.SetTrace(true)
   114  	trieTwo.SetTrace(true)
   115  
   116  	// single sequential update
   117  	roots := make([][]byte, 0)
   118  	// branchNodeUpdatesOne := make(map[string]BranchData)
   119  	fmt.Printf("1. Trie sequential update generated following branch updates\n")
   120  	for i := 0; i < len(updates); i++ {
   121  		if err := ms.applyPlainUpdates(plainKeys[i:i+1], updates[i:i+1]); err != nil {
   122  			t.Fatal(err)
   123  		}
   124  
   125  		sequentialRoot, branchNodeUpdates, err := trieOne.ReviewKeys(plainKeys[i:i+1], hashedKeys[i:i+1])
   126  		require.NoError(t, err)
   127  		roots = append(roots, sequentialRoot)
   128  
   129  		ms.applyBranchNodeUpdates(branchNodeUpdates)
   130  		renderUpdates(branchNodeUpdates)
   131  	}
   132  
   133  	err := ms2.applyPlainUpdates(plainKeys, updates)
   134  	require.NoError(t, err)
   135  
   136  	fmt.Printf("\n2. Trie batch update generated following branch updates\n")
   137  	// batch update
   138  	batchRoot, branchNodeUpdatesTwo, err := trieTwo.ReviewKeys(plainKeys, hashedKeys)
   139  	require.NoError(t, err)
   140  	renderUpdates(branchNodeUpdatesTwo)
   141  
   142  	fmt.Printf("\n sequential roots:\n")
   143  	for i, rh := range roots {
   144  		fmt.Printf("%2d %+v\n", i, hex.EncodeToString(rh))
   145  	}
   146  
   147  	ms2.applyBranchNodeUpdates(branchNodeUpdatesTwo)
   148  
   149  	require.EqualValues(t, batchRoot, roots[len(roots)-1],
   150  		"expected equal roots, got sequential [%v] != batch [%v]", hex.EncodeToString(roots[len(roots)-1]), hex.EncodeToString(batchRoot))
   151  	require.Lenf(t, batchRoot, 32, "root hash length should be equal to 32 bytes")
   152  }
   153  func Test_BinPatriciaHashed_EmptyState(t *testing.T) {
   154  	ms := NewMockState(t)
   155  	hph := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   156  	hph.SetTrace(false)
   157  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   158  		Balance("00", 4).
   159  		Balance("01", 5).
   160  		Balance("02", 6).
   161  		Balance("03", 7).
   162  		Balance("04", 8).
   163  		Storage("04", "01", "0401").
   164  		Storage("03", "56", "050505").
   165  		Storage("03", "57", "060606").
   166  		Balance("05", 9).
   167  		Storage("05", "02", "8989").
   168  		Storage("05", "04", "9898").
   169  		Build()
   170  
   171  	err := ms.applyPlainUpdates(plainKeys, updates)
   172  	require.NoError(t, err)
   173  
   174  	firstRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   175  	require.NoError(t, err)
   176  
   177  	t.Logf("root hash %x\n", firstRootHash)
   178  
   179  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   180  
   181  	fmt.Printf("1. Generated updates\n")
   182  	renderUpdates(branchNodeUpdates)
   183  
   184  	// More updates
   185  	hph.Reset()
   186  	hph.SetTrace(false)
   187  	plainKeys, hashedKeys, updates = NewUpdateBuilder().
   188  		Storage("03", "58", "050505").
   189  		Build()
   190  	err = ms.applyPlainUpdates(plainKeys, updates)
   191  	require.NoError(t, err)
   192  
   193  	secondRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   194  	require.NoError(t, err)
   195  	require.NotEqualValues(t, firstRootHash, secondRootHash)
   196  
   197  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   198  	fmt.Printf("2. Generated single update\n")
   199  	renderUpdates(branchNodeUpdates)
   200  
   201  	// More updates
   202  	hph.Reset()
   203  	hph.SetTrace(false)
   204  	plainKeys, hashedKeys, updates = NewUpdateBuilder().
   205  		Storage("03", "58", "070807").
   206  		Build()
   207  	err = ms.applyPlainUpdates(plainKeys, updates)
   208  	require.NoError(t, err)
   209  
   210  	thirdRootHash, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   211  	require.NoError(t, err)
   212  	require.NotEqualValues(t, secondRootHash, thirdRootHash)
   213  
   214  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   215  	fmt.Printf("3. Generated single update\n")
   216  	renderUpdates(branchNodeUpdates)
   217  }
   218  
   219  func Test_BinPatriciaHashed_EmptyUpdateState(t *testing.T) {
   220  	ms := NewMockState(t)
   221  	hph := NewBinPatriciaHashed(1, ms.branchFn, ms.accountFn, ms.storageFn)
   222  	hph.SetTrace(false)
   223  	plainKeys, hashedKeys, updates := NewUpdateBuilder().
   224  		Balance("00", 4).
   225  		Nonce("00", 246462653).
   226  		Balance("01", 5).
   227  		CodeHash("03", "aaaaaaaaaaf7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a870").
   228  		Delete("00").
   229  		Storage("04", "01", "0401").
   230  		Storage("03", "56", "050505").
   231  		Build()
   232  
   233  	err := ms.applyPlainUpdates(plainKeys, updates)
   234  	require.NoError(t, err)
   235  
   236  	hashBeforeEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   237  	require.NoError(t, err)
   238  	require.NotEmpty(t, hashBeforeEmptyUpdate)
   239  
   240  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   241  
   242  	fmt.Println("1. Updates applied")
   243  	renderUpdates(branchNodeUpdates)
   244  
   245  	// generate empty updates and do NOT reset tree
   246  	hph.SetTrace(true)
   247  
   248  	plainKeys, hashedKeys, updates = NewUpdateBuilder().Build()
   249  
   250  	err = ms.applyPlainUpdates(plainKeys, updates)
   251  	require.NoError(t, err)
   252  
   253  	hashAfterEmptyUpdate, branchNodeUpdates, err := hph.ReviewKeys(plainKeys, hashedKeys)
   254  	require.NoError(t, err)
   255  
   256  	ms.applyBranchNodeUpdates(branchNodeUpdates)
   257  	fmt.Println("2. Empty updates applied without state reset")
   258  
   259  	require.EqualValues(t, hashBeforeEmptyUpdate, hashAfterEmptyUpdate)
   260  }