github.com/ethereum/go-ethereum@v1.16.1/triedb/pathdb/layertree_test.go (about)

     1  // Copyright 2024 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 pathdb
    18  
    19  import (
    20  	"errors"
    21  	"testing"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/core/rawdb"
    25  	"github.com/ethereum/go-ethereum/trie/trienode"
    26  )
    27  
    28  func newTestLayerTree() *layerTree {
    29  	db := New(rawdb.NewMemoryDatabase(), nil, false)
    30  	l := newDiskLayer(common.Hash{0x1}, 0, db, nil, nil, newBuffer(0, nil, nil, 0), nil)
    31  	t := newLayerTree(l)
    32  	return t
    33  }
    34  
    35  func TestLayerCap(t *testing.T) {
    36  	var cases = []struct {
    37  		init     func() *layerTree
    38  		head     common.Hash
    39  		layers   int
    40  		base     common.Hash
    41  		snapshot map[common.Hash]struct{}
    42  	}{
    43  		{
    44  			// Chain:
    45  			//   C1->C2->C3->C4 (HEAD)
    46  			init: func() *layerTree {
    47  				tr := newTestLayerTree()
    48  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    49  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    50  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    51  				return tr
    52  			},
    53  			// Chain:
    54  			//   C2->C3->C4 (HEAD)
    55  			head:   common.Hash{0x4},
    56  			layers: 2,
    57  			base:   common.Hash{0x2},
    58  			snapshot: map[common.Hash]struct{}{
    59  				common.Hash{0x2}: {},
    60  				common.Hash{0x3}: {},
    61  				common.Hash{0x4}: {},
    62  			},
    63  		},
    64  		{
    65  			// Chain:
    66  			//   C1->C2->C3->C4 (HEAD)
    67  			init: func() *layerTree {
    68  				tr := newTestLayerTree()
    69  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    70  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    71  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    72  				return tr
    73  			},
    74  			// Chain:
    75  			//   C3->C4 (HEAD)
    76  			head:   common.Hash{0x4},
    77  			layers: 1,
    78  			base:   common.Hash{0x3},
    79  			snapshot: map[common.Hash]struct{}{
    80  				common.Hash{0x3}: {},
    81  				common.Hash{0x4}: {},
    82  			},
    83  		},
    84  		{
    85  			// Chain:
    86  			//   C1->C2->C3->C4 (HEAD)
    87  			init: func() *layerTree {
    88  				tr := newTestLayerTree()
    89  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    90  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    91  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
    92  				return tr
    93  			},
    94  			// Chain:
    95  			//   C4 (HEAD)
    96  			head:   common.Hash{0x4},
    97  			layers: 0,
    98  			base:   common.Hash{0x4},
    99  			snapshot: map[common.Hash]struct{}{
   100  				common.Hash{0x4}: {},
   101  			},
   102  		},
   103  		{
   104  			// Chain:
   105  			//   C1->C2->C3->C4 (HEAD)
   106  			//     ->C2'->C3'->C4'
   107  			init: func() *layerTree {
   108  				tr := newTestLayerTree()
   109  				tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   110  				tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   111  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   112  				tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   113  				tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   114  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   115  				return tr
   116  			},
   117  			// Chain:
   118  			//   C2->C3->C4 (HEAD)
   119  			head:   common.Hash{0x4a},
   120  			layers: 2,
   121  			base:   common.Hash{0x2a},
   122  			snapshot: map[common.Hash]struct{}{
   123  				common.Hash{0x4a}: {},
   124  				common.Hash{0x3a}: {},
   125  				common.Hash{0x2a}: {},
   126  			},
   127  		},
   128  		{
   129  			// Chain:
   130  			//   C1->C2->C3->C4 (HEAD)
   131  			//     ->C2'->C3'->C4'
   132  			init: func() *layerTree {
   133  				tr := newTestLayerTree()
   134  				tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   135  				tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   136  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   137  				tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   138  				tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   139  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   140  				return tr
   141  			},
   142  			// Chain:
   143  			//   C3->C4 (HEAD)
   144  			head:   common.Hash{0x4a},
   145  			layers: 1,
   146  			base:   common.Hash{0x3a},
   147  			snapshot: map[common.Hash]struct{}{
   148  				common.Hash{0x4a}: {},
   149  				common.Hash{0x3a}: {},
   150  			},
   151  		},
   152  		{
   153  			// Chain:
   154  			//   C1->C2->C3->C4 (HEAD)
   155  			//         ->C3'->C4'
   156  			init: func() *layerTree {
   157  				tr := newTestLayerTree()
   158  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   159  				tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   160  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   161  				tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   162  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   163  				return tr
   164  			},
   165  			// Chain:
   166  			//   C2->C3->C4 (HEAD)
   167  			//     ->C3'->C4'
   168  			head:   common.Hash{0x4a},
   169  			layers: 2,
   170  			base:   common.Hash{0x2},
   171  			snapshot: map[common.Hash]struct{}{
   172  				common.Hash{0x4a}: {},
   173  				common.Hash{0x3a}: {},
   174  				common.Hash{0x4b}: {},
   175  				common.Hash{0x3b}: {},
   176  				common.Hash{0x2}:  {},
   177  			},
   178  		},
   179  	}
   180  	for _, c := range cases {
   181  		tr := c.init()
   182  		if err := tr.cap(c.head, c.layers); err != nil {
   183  			t.Fatalf("Failed to cap the layer tree %v", err)
   184  		}
   185  		if tr.bottom().root != c.base {
   186  			t.Fatalf("Unexpected bottom layer tree root, want %v, got %v", c.base, tr.bottom().root)
   187  		}
   188  		if len(c.snapshot) != len(tr.layers) {
   189  			t.Fatalf("Unexpected layer tree size, want %v, got %v", len(c.snapshot), len(tr.layers))
   190  		}
   191  		for h := range tr.layers {
   192  			if _, ok := c.snapshot[h]; !ok {
   193  				t.Fatalf("Unexpected layer %v", h)
   194  			}
   195  		}
   196  	}
   197  }
   198  
   199  func TestBaseLayer(t *testing.T) {
   200  	tr := newTestLayerTree()
   201  
   202  	var cases = []struct {
   203  		op   func()
   204  		base common.Hash
   205  	}{
   206  		// Chain:
   207  		//   C1 (HEAD)
   208  		{
   209  			func() {},
   210  			common.Hash{0x1},
   211  		},
   212  		// Chain:
   213  		//   C1->C2->C3 (HEAD)
   214  		{
   215  			func() {
   216  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   217  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   218  			},
   219  			common.Hash{0x1},
   220  		},
   221  		// Chain:
   222  		//   C3 (HEAD)
   223  		{
   224  			func() {
   225  				tr.cap(common.Hash{0x3}, 0)
   226  			},
   227  			common.Hash{0x3},
   228  		},
   229  		// Chain:
   230  		//   C4->C5->C6 (HEAD)
   231  		{
   232  			func() {
   233  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   234  				tr.add(common.Hash{0x5}, common.Hash{0x4}, 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   235  				tr.add(common.Hash{0x6}, common.Hash{0x5}, 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   236  				tr.cap(common.Hash{0x6}, 2)
   237  			},
   238  			common.Hash{0x4},
   239  		},
   240  	}
   241  	for _, c := range cases {
   242  		c.op()
   243  		if tr.base.rootHash() != c.base {
   244  			t.Fatalf("Unexpected base root, want %v, got: %v", c.base, tr.base.rootHash())
   245  		}
   246  	}
   247  }
   248  
   249  func TestDescendant(t *testing.T) {
   250  	var cases = []struct {
   251  		init      func() *layerTree
   252  		snapshotA map[common.Hash]map[common.Hash]struct{}
   253  		op        func(tr *layerTree)
   254  		snapshotB map[common.Hash]map[common.Hash]struct{}
   255  	}{
   256  		{
   257  			// Chain:
   258  			//   C1->C2 (HEAD)
   259  			init: func() *layerTree {
   260  				tr := newTestLayerTree()
   261  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   262  				return tr
   263  			},
   264  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   265  				common.Hash{0x1}: {
   266  					common.Hash{0x2}: {},
   267  				},
   268  			},
   269  			// Chain:
   270  			//   C1->C2->C3 (HEAD)
   271  			op: func(tr *layerTree) {
   272  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   273  			},
   274  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   275  				common.Hash{0x1}: {
   276  					common.Hash{0x2}: {},
   277  					common.Hash{0x3}: {},
   278  				},
   279  				common.Hash{0x2}: {
   280  					common.Hash{0x3}: {},
   281  				},
   282  			},
   283  		},
   284  		{
   285  			// Chain:
   286  			//   C1->C2->C3->C4 (HEAD)
   287  			init: func() *layerTree {
   288  				tr := newTestLayerTree()
   289  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   290  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   291  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   292  				return tr
   293  			},
   294  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   295  				common.Hash{0x1}: {
   296  					common.Hash{0x2}: {},
   297  					common.Hash{0x3}: {},
   298  					common.Hash{0x4}: {},
   299  				},
   300  				common.Hash{0x2}: {
   301  					common.Hash{0x3}: {},
   302  					common.Hash{0x4}: {},
   303  				},
   304  				common.Hash{0x3}: {
   305  					common.Hash{0x4}: {},
   306  				},
   307  			},
   308  			// Chain:
   309  			//   C2->C3->C4 (HEAD)
   310  			op: func(tr *layerTree) {
   311  				tr.cap(common.Hash{0x4}, 2)
   312  			},
   313  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   314  				common.Hash{0x2}: {
   315  					common.Hash{0x3}: {},
   316  					common.Hash{0x4}: {},
   317  				},
   318  				common.Hash{0x3}: {
   319  					common.Hash{0x4}: {},
   320  				},
   321  			},
   322  		},
   323  		{
   324  			// Chain:
   325  			//   C1->C2->C3->C4 (HEAD)
   326  			init: func() *layerTree {
   327  				tr := newTestLayerTree()
   328  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   329  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   330  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   331  				return tr
   332  			},
   333  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   334  				common.Hash{0x1}: {
   335  					common.Hash{0x2}: {},
   336  					common.Hash{0x3}: {},
   337  					common.Hash{0x4}: {},
   338  				},
   339  				common.Hash{0x2}: {
   340  					common.Hash{0x3}: {},
   341  					common.Hash{0x4}: {},
   342  				},
   343  				common.Hash{0x3}: {
   344  					common.Hash{0x4}: {},
   345  				},
   346  			},
   347  			// Chain:
   348  			//   C3->C4 (HEAD)
   349  			op: func(tr *layerTree) {
   350  				tr.cap(common.Hash{0x4}, 1)
   351  			},
   352  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   353  				common.Hash{0x3}: {
   354  					common.Hash{0x4}: {},
   355  				},
   356  			},
   357  		},
   358  		{
   359  			// Chain:
   360  			//   C1->C2->C3->C4 (HEAD)
   361  			init: func() *layerTree {
   362  				tr := newTestLayerTree()
   363  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   364  				tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   365  				tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   366  				return tr
   367  			},
   368  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   369  				common.Hash{0x1}: {
   370  					common.Hash{0x2}: {},
   371  					common.Hash{0x3}: {},
   372  					common.Hash{0x4}: {},
   373  				},
   374  				common.Hash{0x2}: {
   375  					common.Hash{0x3}: {},
   376  					common.Hash{0x4}: {},
   377  				},
   378  				common.Hash{0x3}: {
   379  					common.Hash{0x4}: {},
   380  				},
   381  			},
   382  			// Chain:
   383  			//   C4 (HEAD)
   384  			op: func(tr *layerTree) {
   385  				tr.cap(common.Hash{0x4}, 0)
   386  			},
   387  			snapshotB: map[common.Hash]map[common.Hash]struct{}{},
   388  		},
   389  		{
   390  			// Chain:
   391  			//   C1->C2->C3->C4 (HEAD)
   392  			//     ->C2'->C3'->C4'
   393  			init: func() *layerTree {
   394  				tr := newTestLayerTree()
   395  				tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   396  				tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   397  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   398  				tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   399  				tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   400  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   401  				return tr
   402  			},
   403  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   404  				common.Hash{0x1}: {
   405  					common.Hash{0x2a}: {},
   406  					common.Hash{0x3a}: {},
   407  					common.Hash{0x4a}: {},
   408  					common.Hash{0x2b}: {},
   409  					common.Hash{0x3b}: {},
   410  					common.Hash{0x4b}: {},
   411  				},
   412  				common.Hash{0x2a}: {
   413  					common.Hash{0x3a}: {},
   414  					common.Hash{0x4a}: {},
   415  				},
   416  				common.Hash{0x3a}: {
   417  					common.Hash{0x4a}: {},
   418  				},
   419  				common.Hash{0x2b}: {
   420  					common.Hash{0x3b}: {},
   421  					common.Hash{0x4b}: {},
   422  				},
   423  				common.Hash{0x3b}: {
   424  					common.Hash{0x4b}: {},
   425  				},
   426  			},
   427  			// Chain:
   428  			//   C2->C3->C4 (HEAD)
   429  			op: func(tr *layerTree) {
   430  				tr.cap(common.Hash{0x4a}, 2)
   431  			},
   432  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   433  				common.Hash{0x2a}: {
   434  					common.Hash{0x3a}: {},
   435  					common.Hash{0x4a}: {},
   436  				},
   437  				common.Hash{0x3a}: {
   438  					common.Hash{0x4a}: {},
   439  				},
   440  			},
   441  		},
   442  		{
   443  			// Chain:
   444  			//   C1->C2->C3->C4 (HEAD)
   445  			//     ->C2'->C3'->C4'
   446  			init: func() *layerTree {
   447  				tr := newTestLayerTree()
   448  				tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   449  				tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   450  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   451  				tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   452  				tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   453  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   454  				return tr
   455  			},
   456  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   457  				common.Hash{0x1}: {
   458  					common.Hash{0x2a}: {},
   459  					common.Hash{0x3a}: {},
   460  					common.Hash{0x4a}: {},
   461  					common.Hash{0x2b}: {},
   462  					common.Hash{0x3b}: {},
   463  					common.Hash{0x4b}: {},
   464  				},
   465  				common.Hash{0x2a}: {
   466  					common.Hash{0x3a}: {},
   467  					common.Hash{0x4a}: {},
   468  				},
   469  				common.Hash{0x3a}: {
   470  					common.Hash{0x4a}: {},
   471  				},
   472  				common.Hash{0x2b}: {
   473  					common.Hash{0x3b}: {},
   474  					common.Hash{0x4b}: {},
   475  				},
   476  				common.Hash{0x3b}: {
   477  					common.Hash{0x4b}: {},
   478  				},
   479  			},
   480  			// Chain:
   481  			//   C3->C4 (HEAD)
   482  			op: func(tr *layerTree) {
   483  				tr.cap(common.Hash{0x4a}, 1)
   484  			},
   485  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   486  				common.Hash{0x3a}: {
   487  					common.Hash{0x4a}: {},
   488  				},
   489  			},
   490  		},
   491  		{
   492  			// Chain:
   493  			//   C1->C2->C3->C4 (HEAD)
   494  			//         ->C3'->C4'
   495  			init: func() *layerTree {
   496  				tr := newTestLayerTree()
   497  				tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   498  				tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   499  				tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   500  				tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   501  				tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false))
   502  				return tr
   503  			},
   504  			snapshotA: map[common.Hash]map[common.Hash]struct{}{
   505  				common.Hash{0x1}: {
   506  					common.Hash{0x2}:  {},
   507  					common.Hash{0x3a}: {},
   508  					common.Hash{0x4a}: {},
   509  					common.Hash{0x3b}: {},
   510  					common.Hash{0x4b}: {},
   511  				},
   512  				common.Hash{0x2}: {
   513  					common.Hash{0x3a}: {},
   514  					common.Hash{0x4a}: {},
   515  					common.Hash{0x3b}: {},
   516  					common.Hash{0x4b}: {},
   517  				},
   518  				common.Hash{0x3a}: {
   519  					common.Hash{0x4a}: {},
   520  				},
   521  				common.Hash{0x3b}: {
   522  					common.Hash{0x4b}: {},
   523  				},
   524  			},
   525  			// Chain:
   526  			//   C2->C3->C4 (HEAD)
   527  			//     ->C3'->C4'
   528  			op: func(tr *layerTree) {
   529  				tr.cap(common.Hash{0x4a}, 2)
   530  			},
   531  			snapshotB: map[common.Hash]map[common.Hash]struct{}{
   532  				common.Hash{0x2}: {
   533  					common.Hash{0x3a}: {},
   534  					common.Hash{0x4a}: {},
   535  					common.Hash{0x3b}: {},
   536  					common.Hash{0x4b}: {},
   537  				},
   538  				common.Hash{0x3a}: {
   539  					common.Hash{0x4a}: {},
   540  				},
   541  				common.Hash{0x3b}: {
   542  					common.Hash{0x4b}: {},
   543  				},
   544  			},
   545  		},
   546  	}
   547  	check := func(setA, setB map[common.Hash]map[common.Hash]struct{}) bool {
   548  		if len(setA) != len(setB) {
   549  			return false
   550  		}
   551  		for h, subA := range setA {
   552  			subB, ok := setB[h]
   553  			if !ok {
   554  				return false
   555  			}
   556  			if len(subA) != len(subB) {
   557  				return false
   558  			}
   559  			for hh := range subA {
   560  				if _, ok := subB[hh]; !ok {
   561  					return false
   562  				}
   563  			}
   564  		}
   565  		return true
   566  	}
   567  	for _, c := range cases {
   568  		tr := c.init()
   569  		if !check(c.snapshotA, tr.descendants) {
   570  			t.Fatalf("Unexpected descendants")
   571  		}
   572  		c.op(tr)
   573  		if !check(c.snapshotB, tr.descendants) {
   574  			t.Fatalf("Unexpected descendants")
   575  		}
   576  	}
   577  }
   578  
   579  func TestAccountLookup(t *testing.T) {
   580  	// Chain:
   581  	//   C1->C2->C3->C4 (HEAD)
   582  	tr := newTestLayerTree() // base = 0x1
   583  	tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(),
   584  		NewStateSetWithOrigin(randomAccountSet("0xa"), nil, nil, nil, false))
   585  	tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(),
   586  		NewStateSetWithOrigin(randomAccountSet("0xb"), nil, nil, nil, false))
   587  	tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(),
   588  		NewStateSetWithOrigin(randomAccountSet("0xa", "0xc"), nil, nil, nil, false))
   589  
   590  	var cases = []struct {
   591  		account common.Hash
   592  		state   common.Hash
   593  		expect  common.Hash
   594  	}{
   595  		{
   596  			// unknown account
   597  			common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x1},
   598  		},
   599  		/*
   600  			lookup account from the top
   601  		*/
   602  		{
   603  			common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4},
   604  		},
   605  		{
   606  			common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3},
   607  		},
   608  		{
   609  			common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4},
   610  		},
   611  		/*
   612  			lookup account from the middle
   613  		*/
   614  		{
   615  			common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x2},
   616  		},
   617  		{
   618  			common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3},
   619  		},
   620  		{
   621  			common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x1}, // not found
   622  		},
   623  		{
   624  			common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{0x2},
   625  		},
   626  		{
   627  			common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{0x1}, // not found
   628  		},
   629  		{
   630  			common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{0x1}, // not found
   631  		},
   632  		/*
   633  			lookup account from the bottom
   634  		*/
   635  		{
   636  			common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{0x1}, // not found
   637  		},
   638  		{
   639  			common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{0x1}, // not found
   640  		},
   641  		{
   642  			common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{0x1}, // not found
   643  		},
   644  	}
   645  	for i, c := range cases {
   646  		l, err := tr.lookupAccount(c.account, c.state)
   647  		if err != nil {
   648  			t.Fatalf("%d: %v", i, err)
   649  		}
   650  		if l.rootHash() != c.expect {
   651  			t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash())
   652  		}
   653  	}
   654  
   655  	// Chain:
   656  	//   C3->C4 (HEAD)
   657  	tr.cap(common.Hash{0x4}, 1)
   658  
   659  	cases2 := []struct {
   660  		account   common.Hash
   661  		state     common.Hash
   662  		expect    common.Hash
   663  		expectErr error
   664  	}{
   665  		{
   666  			// unknown account
   667  			common.HexToHash("0xd"), common.Hash{0x4}, common.Hash{0x3}, nil,
   668  		},
   669  		/*
   670  			lookup account from the top
   671  		*/
   672  		{
   673  			common.HexToHash("0xa"), common.Hash{0x4}, common.Hash{0x4}, nil,
   674  		},
   675  		{
   676  			common.HexToHash("0xb"), common.Hash{0x4}, common.Hash{0x3}, nil,
   677  		},
   678  		{
   679  			common.HexToHash("0xc"), common.Hash{0x4}, common.Hash{0x4}, nil,
   680  		},
   681  		/*
   682  			lookup account from the bottom
   683  		*/
   684  		{
   685  			common.HexToHash("0xa"), common.Hash{0x3}, common.Hash{0x3}, nil,
   686  		},
   687  		{
   688  			common.HexToHash("0xb"), common.Hash{0x3}, common.Hash{0x3}, nil,
   689  		},
   690  		{
   691  			common.HexToHash("0xc"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found
   692  		},
   693  		/*
   694  			stale states
   695  		*/
   696  		{
   697  			common.HexToHash("0xa"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   698  		},
   699  		{
   700  			common.HexToHash("0xb"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   701  		},
   702  		{
   703  			common.HexToHash("0xc"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   704  		},
   705  		{
   706  			common.HexToHash("0xa"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   707  		},
   708  		{
   709  			common.HexToHash("0xb"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   710  		},
   711  		{
   712  			common.HexToHash("0xc"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   713  		},
   714  	}
   715  	for i, c := range cases2 {
   716  		l, err := tr.lookupAccount(c.account, c.state)
   717  		if c.expectErr != nil {
   718  			if !errors.Is(err, c.expectErr) {
   719  				t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err)
   720  			}
   721  		}
   722  		if c.expectErr == nil {
   723  			if err != nil {
   724  				t.Fatalf("%d: %v", i, err)
   725  			}
   726  			if l.rootHash() != c.expect {
   727  				t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash())
   728  			}
   729  		}
   730  	}
   731  }
   732  
   733  func TestStorageLookup(t *testing.T) {
   734  	// Chain:
   735  	//   C1->C2->C3->C4 (HEAD)
   736  	tr := newTestLayerTree() // base = 0x1
   737  	tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(),
   738  		NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1"}}, nil), nil, nil, false))
   739  	tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(),
   740  		NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x2"}}, nil), nil, nil, false))
   741  	tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(),
   742  		NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1", "0x3"}}, nil), nil, nil, false))
   743  
   744  	var cases = []struct {
   745  		storage common.Hash
   746  		state   common.Hash
   747  		expect  common.Hash
   748  	}{
   749  		{
   750  			// unknown storage slot
   751  			common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x1},
   752  		},
   753  		/*
   754  			lookup storage slot from the top
   755  		*/
   756  		{
   757  			common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4},
   758  		},
   759  		{
   760  			common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3},
   761  		},
   762  		{
   763  			common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4},
   764  		},
   765  		/*
   766  			lookup storage slot from the middle
   767  		*/
   768  		{
   769  			common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x2},
   770  		},
   771  		{
   772  			common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3},
   773  		},
   774  		{
   775  			common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x1}, // not found
   776  		},
   777  		{
   778  			common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{0x2},
   779  		},
   780  		{
   781  			common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{0x1}, // not found
   782  		},
   783  		{
   784  			common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{0x1}, // not found
   785  		},
   786  		/*
   787  			lookup storage slot from the bottom
   788  		*/
   789  		{
   790  			common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{0x1}, // not found
   791  		},
   792  		{
   793  			common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{0x1}, // not found
   794  		},
   795  		{
   796  			common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{0x1}, // not found
   797  		},
   798  	}
   799  	for i, c := range cases {
   800  		l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state)
   801  		if err != nil {
   802  			t.Fatalf("%d: %v", i, err)
   803  		}
   804  		if l.rootHash() != c.expect {
   805  			t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash())
   806  		}
   807  	}
   808  
   809  	// Chain:
   810  	//   C3->C4 (HEAD)
   811  	tr.cap(common.Hash{0x4}, 1)
   812  
   813  	cases2 := []struct {
   814  		storage   common.Hash
   815  		state     common.Hash
   816  		expect    common.Hash
   817  		expectErr error
   818  	}{
   819  		{
   820  			// unknown storage slot
   821  			common.HexToHash("0x4"), common.Hash{0x4}, common.Hash{0x3}, nil,
   822  		},
   823  		/*
   824  			lookup account from the top
   825  		*/
   826  		{
   827  			common.HexToHash("0x1"), common.Hash{0x4}, common.Hash{0x4}, nil,
   828  		},
   829  		{
   830  			common.HexToHash("0x2"), common.Hash{0x4}, common.Hash{0x3}, nil,
   831  		},
   832  		{
   833  			common.HexToHash("0x3"), common.Hash{0x4}, common.Hash{0x4}, nil,
   834  		},
   835  		/*
   836  			lookup account from the bottom
   837  		*/
   838  		{
   839  			common.HexToHash("0x1"), common.Hash{0x3}, common.Hash{0x3}, nil,
   840  		},
   841  		{
   842  			common.HexToHash("0x2"), common.Hash{0x3}, common.Hash{0x3}, nil,
   843  		},
   844  		{
   845  			common.HexToHash("0x3"), common.Hash{0x3}, common.Hash{0x3}, nil, // not found
   846  		},
   847  		/*
   848  			stale states
   849  		*/
   850  		{
   851  			common.HexToHash("0x1"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   852  		},
   853  		{
   854  			common.HexToHash("0x2"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   855  		},
   856  		{
   857  			common.HexToHash("0x3"), common.Hash{0x2}, common.Hash{}, errSnapshotStale,
   858  		},
   859  		{
   860  			common.HexToHash("0x1"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   861  		},
   862  		{
   863  			common.HexToHash("0x2"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   864  		},
   865  		{
   866  			common.HexToHash("0x3"), common.Hash{0x1}, common.Hash{}, errSnapshotStale,
   867  		},
   868  	}
   869  	for i, c := range cases2 {
   870  		l, err := tr.lookupStorage(common.HexToHash("0xa"), c.storage, c.state)
   871  		if c.expectErr != nil {
   872  			if !errors.Is(err, c.expectErr) {
   873  				t.Fatalf("%d: unexpected error, want %v, got %v", i, c.expectErr, err)
   874  			}
   875  		}
   876  		if c.expectErr == nil {
   877  			if err != nil {
   878  				t.Fatalf("%d: %v", i, err)
   879  			}
   880  			if l.rootHash() != c.expect {
   881  				t.Errorf("Unexpected tiphash, %d, want: %x, got: %x", i, c.expect, l.rootHash())
   882  			}
   883  		}
   884  	}
   885  }