github.com/leovct/zkevm-bridge-service@v0.4.4/bridgectrl/merkletree_test.go (about)

     1  package bridgectrl
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"fmt"
     8  	"math/big"
     9  	"os"
    10  	"path"
    11  	"runtime"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/0xPolygonHermez/zkevm-bridge-service/db/pgstorage"
    16  	"github.com/0xPolygonHermez/zkevm-bridge-service/etherman"
    17  	"github.com/0xPolygonHermez/zkevm-bridge-service/log"
    18  	"github.com/0xPolygonHermez/zkevm-bridge-service/test/vectors"
    19  	"github.com/ethereum/go-ethereum/common"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  )
    23  
    24  func init() {
    25  	// Change dir to project root
    26  	// This is important because we have relative paths to files containing test vectors
    27  	_, filename, _, _ := runtime.Caller(0)
    28  	dir := path.Join(path.Dir(filename), "../")
    29  	err := os.Chdir(dir)
    30  	if err != nil {
    31  		panic(err)
    32  	}
    33  }
    34  
    35  func formatBytes32String(text string) ([KeyLen]byte, error) {
    36  	bText, err := hex.DecodeString(text)
    37  	if err != nil {
    38  		return [KeyLen]byte{}, err
    39  	}
    40  
    41  	if len(bText) > 32 {
    42  		return [KeyLen]byte{}, fmt.Errorf("text is more than 32 bytes long")
    43  	}
    44  	var res [KeyLen]byte
    45  	copy(res[:], bText)
    46  	return res, nil
    47  }
    48  
    49  func TestLeafHash(t *testing.T) {
    50  	data, err := os.ReadFile("test/vectors/src/mt-bridge/leaf-vectors.json")
    51  	require.NoError(t, err)
    52  
    53  	var leafVectors []vectors.DepositVectorRaw
    54  	err = json.Unmarshal(data, &leafVectors)
    55  	require.NoError(t, err)
    56  
    57  	for ti, testVector := range leafVectors {
    58  		t.Run(fmt.Sprintf("Test vector %d", ti), func(t *testing.T) {
    59  			amount, err := new(big.Int).SetString(testVector.Amount, 0)
    60  			require.True(t, err)
    61  
    62  			deposit := &etherman.Deposit{
    63  				OriginalNetwork:    testVector.OriginalNetwork,
    64  				OriginalAddress:    common.HexToAddress(testVector.TokenAddress),
    65  				Amount:             amount,
    66  				DestinationNetwork: testVector.DestinationNetwork,
    67  				DestinationAddress: common.HexToAddress(testVector.DestinationAddress),
    68  				BlockNumber:        0,
    69  				DepositCount:       uint(ti + 1),
    70  				Metadata:           common.FromHex(testVector.Metadata),
    71  			}
    72  			leafHash := hashDeposit(deposit)
    73  			assert.Equal(t, testVector.ExpectedHash[2:], hex.EncodeToString(leafHash[:]))
    74  		})
    75  	}
    76  }
    77  
    78  func TestMTAddLeaf(t *testing.T) {
    79  	data, err := os.ReadFile("test/vectors/src/mt-bridge/root-vectors.json")
    80  	require.NoError(t, err)
    81  
    82  	var mtTestVectors []vectors.MTRootVectorRaw
    83  	err = json.Unmarshal(data, &mtTestVectors)
    84  	require.NoError(t, err)
    85  
    86  	dbCfg := pgstorage.NewConfigFromEnv()
    87  	ctx := context.Background()
    88  
    89  	for ti, testVector := range mtTestVectors {
    90  		t.Run(fmt.Sprintf("Test vector %d", ti), func(t *testing.T) {
    91  			err = pgstorage.InitOrReset(dbCfg)
    92  			require.NoError(t, err)
    93  
    94  			store, err := pgstorage.NewPostgresStorage(dbCfg)
    95  			require.NoError(t, err)
    96  
    97  			mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
    98  			require.NoError(t, err)
    99  
   100  			amount, result := new(big.Int).SetString(testVector.NewLeaf.Amount, 0)
   101  			require.True(t, result)
   102  			var (
   103  				depositIDs []uint64
   104  				deposit    *etherman.Deposit
   105  			)
   106  			for i := 0; i <= ti; i++ {
   107  				deposit = &etherman.Deposit{
   108  					OriginalNetwork:    testVector.NewLeaf.OriginalNetwork,
   109  					OriginalAddress:    common.HexToAddress(testVector.NewLeaf.TokenAddress),
   110  					Amount:             amount,
   111  					DestinationNetwork: testVector.NewLeaf.DestinationNetwork,
   112  					DestinationAddress: common.HexToAddress(testVector.NewLeaf.DestinationAddress),
   113  					BlockNumber:        0,
   114  					DepositCount:       uint(i),
   115  					Metadata:           common.FromHex(testVector.NewLeaf.Metadata),
   116  				}
   117  				depositID, err := store.AddDeposit(ctx, deposit, nil)
   118  				require.NoError(t, err)
   119  				depositIDs = append(depositIDs, depositID)
   120  			}
   121  
   122  			for i, leaf := range testVector.ExistingLeaves {
   123  				leafValue, err := formatBytes32String(leaf[2:])
   124  				require.NoError(t, err)
   125  
   126  				err = mt.addLeaf(ctx, depositIDs[i], leafValue, uint(i), nil)
   127  				require.NoError(t, err)
   128  			}
   129  			curRoot, err := mt.getRoot(ctx, nil)
   130  			require.NoError(t, err)
   131  			assert.Equal(t, hex.EncodeToString(curRoot), testVector.CurrentRoot[2:])
   132  
   133  			leafHash := hashDeposit(deposit)
   134  			err = mt.addLeaf(ctx, depositIDs[len(depositIDs)-1], leafHash, uint(len(testVector.ExistingLeaves)), nil)
   135  			require.NoError(t, err)
   136  			newRoot, err := mt.getRoot(ctx, nil)
   137  			require.NoError(t, err)
   138  			assert.Equal(t, hex.EncodeToString(newRoot), testVector.NewRoot[2:])
   139  		})
   140  	}
   141  }
   142  
   143  func TestMTGetProof(t *testing.T) {
   144  	data, err := os.ReadFile("test/vectors/src/mt-bridge/claim-vectors.json")
   145  	require.NoError(t, err)
   146  
   147  	var mtTestVectors []vectors.MTClaimVectorRaw
   148  	err = json.Unmarshal(data, &mtTestVectors)
   149  	require.NoError(t, err)
   150  
   151  	dbCfg := pgstorage.NewConfigFromEnv()
   152  	ctx := context.Background()
   153  
   154  	for ti, testVector := range mtTestVectors {
   155  		t.Run(fmt.Sprintf("Test vector %d", ti), func(t *testing.T) {
   156  			err = pgstorage.InitOrReset(dbCfg)
   157  			require.NoError(t, err)
   158  
   159  			store, err := pgstorage.NewPostgresStorage(dbCfg)
   160  			require.NoError(t, err)
   161  
   162  			mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   163  			require.NoError(t, err)
   164  			var cur, sibling [KeyLen]byte
   165  			for li, leaf := range testVector.Deposits {
   166  				amount, result := new(big.Int).SetString(leaf.Amount, 0)
   167  				require.True(t, result)
   168  				block := &etherman.Block{
   169  					BlockNumber: uint64(li + 1),
   170  					BlockHash:   common.HexToHash("0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9fc"),
   171  					ParentHash:  common.Hash{},
   172  				}
   173  				blockID, err := store.AddBlock(context.TODO(), block, nil)
   174  				require.NoError(t, err)
   175  				deposit := &etherman.Deposit{
   176  					OriginalNetwork:    leaf.OriginalNetwork,
   177  					OriginalAddress:    common.HexToAddress(leaf.TokenAddress),
   178  					Amount:             amount,
   179  					DestinationNetwork: leaf.DestinationNetwork,
   180  					DestinationAddress: common.HexToAddress(leaf.DestinationAddress),
   181  					BlockID:            blockID,
   182  					DepositCount:       uint(li),
   183  					Metadata:           common.FromHex(leaf.Metadata),
   184  				}
   185  				depositID, err := store.AddDeposit(ctx, deposit, nil)
   186  				require.NoError(t, err)
   187  				leafHash := hashDeposit(deposit)
   188  				if li == int(testVector.Index) {
   189  					cur = leafHash
   190  				}
   191  				err = mt.addLeaf(ctx, depositID, leafHash, uint(li), nil)
   192  				require.NoError(t, err)
   193  			}
   194  			root, err := mt.getRoot(ctx, nil)
   195  			require.NoError(t, err)
   196  			assert.Equal(t, hex.EncodeToString(root), testVector.ExpectedRoot[2:])
   197  
   198  			for h := 0; h < int(mt.height); h++ {
   199  				copy(sibling[:], common.FromHex(testVector.MerkleProof[h]))
   200  				if testVector.Index&(1<<h) != 0 {
   201  					cur = Hash(sibling, cur)
   202  				} else {
   203  					cur = Hash(cur, sibling)
   204  				}
   205  			}
   206  			assert.Equal(t, hex.EncodeToString(cur[:]), testVector.ExpectedRoot[2:])
   207  		})
   208  	}
   209  }
   210  
   211  func TestUpdateMT(t *testing.T) {
   212  	data, err := os.ReadFile("test/vectors/src/mt-bridge/root-vectors.json")
   213  	require.NoError(t, err)
   214  
   215  	var mtTestVectors []vectors.MTRootVectorRaw
   216  	err = json.Unmarshal(data, &mtTestVectors)
   217  	require.NoError(t, err)
   218  	for ti, testVector := range mtTestVectors {
   219  		input := testVector.ExistingLeaves
   220  		log.Debug("input: ", input)
   221  		dbCfg := pgstorage.NewConfigFromEnv()
   222  		ctx := context.Background()
   223  		err := pgstorage.InitOrReset(dbCfg)
   224  		require.NoError(t, err)
   225  
   226  		store, err := pgstorage.NewPostgresStorage(dbCfg)
   227  		require.NoError(t, err)
   228  
   229  		mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   230  		require.NoError(t, err)
   231  
   232  		amount, result := new(big.Int).SetString(testVector.NewLeaf.Amount, 0)
   233  		require.True(t, result)
   234  		for i := 0; i <= ti; i++ {
   235  			deposit := &etherman.Deposit{
   236  				OriginalNetwork:    testVector.NewLeaf.OriginalNetwork,
   237  				OriginalAddress:    common.HexToAddress(testVector.NewLeaf.TokenAddress),
   238  				Amount:             amount,
   239  				DestinationNetwork: testVector.NewLeaf.DestinationNetwork,
   240  				DestinationAddress: common.HexToAddress(testVector.NewLeaf.DestinationAddress),
   241  				BlockNumber:        0,
   242  				DepositCount:       uint(i),
   243  				Metadata:           common.FromHex(testVector.NewLeaf.Metadata),
   244  			}
   245  			_, err := store.AddDeposit(ctx, deposit, nil)
   246  			require.NoError(t, err)
   247  		}
   248  
   249  		var leaves [][KeyLen]byte
   250  		for _, v := range input {
   251  			var res [KeyLen]byte
   252  			copy(res[:], common.Hex2Bytes(v[2:]))
   253  			leaves = append(leaves, res)
   254  		}
   255  
   256  		depositID := uint64(len(leaves))
   257  		if depositID != 0 {
   258  			err = mt.updateLeaf(ctx, depositID, leaves, nil)
   259  			require.NoError(t, err)
   260  			// Check root
   261  			newRoot, err := mt.getRoot(ctx, nil)
   262  			require.NoError(t, err)
   263  			require.Equal(t, testVector.CurrentRoot[2:], hex.EncodeToString(newRoot[:]))
   264  		}
   265  
   266  		var res [KeyLen]byte
   267  		copy(res[:], common.Hex2Bytes(testVector.NewLeaf.CurrentHash[2:]))
   268  		leaves = append(leaves, res)
   269  		depositID = uint64(len(leaves))
   270  		err = mt.updateLeaf(ctx, depositID, leaves, nil)
   271  		require.NoError(t, err)
   272  		// Check new root
   273  		newRoot, err := mt.getRoot(ctx, nil)
   274  		require.NoError(t, err)
   275  		require.Equal(t, testVector.NewRoot[2:], hex.EncodeToString(newRoot[:]))
   276  	}
   277  }
   278  
   279  func TestGetLeaves(t *testing.T) {
   280  	data, err := os.ReadFile("test/vectors/src/mt-bridge/fullmt-vector.sql")
   281  	require.NoError(t, err)
   282  	dbCfg := pgstorage.NewConfigFromEnv()
   283  	ctx := context.Background()
   284  	err = pgstorage.InitOrReset(dbCfg)
   285  	require.NoError(t, err)
   286  
   287  	store, err := pgstorage.NewPostgresStorage(dbCfg)
   288  	require.NoError(t, err)
   289  	_, err = store.Exec(ctx, string(data))
   290  	require.NoError(t, err)
   291  
   292  	mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   293  	require.NoError(t, err)
   294  	leaves, err := mt.getLeaves(ctx, nil)
   295  	require.NoError(t, err)
   296  	require.Equal(t, 26, len(leaves))
   297  	log.Debug("leaves: %+v", leaves)
   298  }
   299  
   300  func TestBuildMTRootAndStore(t *testing.T) {
   301  	data, err := os.ReadFile("test/vectors/src/mt-bridge/root-vectors.json")
   302  	require.NoError(t, err)
   303  
   304  	var mtTestVectors []vectors.MTRootVectorRaw
   305  	err = json.Unmarshal(data, &mtTestVectors)
   306  	require.NoError(t, err)
   307  	for _, testVector := range mtTestVectors {
   308  		input := testVector.ExistingLeaves
   309  		log.Debug("input: ", input)
   310  		dbCfg := pgstorage.NewConfigFromEnv()
   311  		ctx := context.Background()
   312  		err := pgstorage.InitOrReset(dbCfg)
   313  		require.NoError(t, err)
   314  
   315  		store, err := pgstorage.NewPostgresStorage(dbCfg)
   316  		require.NoError(t, err)
   317  
   318  		mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   319  		require.NoError(t, err)
   320  
   321  		var leaves [][KeyLen]byte
   322  		for _, v := range input {
   323  			var res [KeyLen]byte
   324  			copy(res[:], common.Hex2Bytes(v[2:]))
   325  			leaves = append(leaves, res)
   326  		}
   327  
   328  		if len(leaves) != 0 {
   329  			root, err := mt.buildMTRoot(leaves)
   330  			require.NoError(t, err)
   331  			require.Equal(t, testVector.CurrentRoot, root.String())
   332  		}
   333  
   334  		var res [KeyLen]byte
   335  		copy(res[:], common.Hex2Bytes(testVector.NewLeaf.CurrentHash[2:]))
   336  		leaves = append(leaves, res)
   337  		newRoot, err := mt.buildMTRoot(leaves)
   338  		require.NoError(t, err)
   339  		require.Equal(t, testVector.NewRoot, newRoot.String())
   340  
   341  		// Insert values into db
   342  		var blockNumber uint64
   343  		err = mt.storeLeaves(ctx, leaves, blockNumber, nil)
   344  		require.NoError(t, err)
   345  		result, err := mt.store.GetRollupExitLeavesByRoot(ctx, newRoot, nil)
   346  		require.NoError(t, err)
   347  		for i := range leaves {
   348  			require.Equal(t, len(leaves), len(result))
   349  			require.Equal(t, leaves[i][:], result[i].Leaf.Bytes())
   350  			require.Equal(t, newRoot, result[i].Root)
   351  			require.Equal(t, uint(i+1), result[i].RollupId)
   352  		}
   353  	}
   354  }
   355  
   356  func TestComputeSiblings(t *testing.T) {
   357  	data, err := os.ReadFile("test/vectors/src/mt-bridge/fullmt-vector.sql")
   358  	require.NoError(t, err)
   359  	dbCfg := pgstorage.NewConfigFromEnv()
   360  	ctx := context.Background()
   361  	err = pgstorage.InitOrReset(dbCfg)
   362  	require.NoError(t, err)
   363  
   364  	store, err := pgstorage.NewPostgresStorage(dbCfg)
   365  	require.NoError(t, err)
   366  	_, err = store.Exec(ctx, string(data))
   367  	require.NoError(t, err)
   368  
   369  	mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   370  	require.NoError(t, err)
   371  	leaves, err := mt.getLeaves(ctx, nil)
   372  	require.NoError(t, err)
   373  	require.Equal(t, 26, len(leaves))
   374  	siblings, root, err := ComputeSiblings(1, leaves, mt.height)
   375  	require.NoError(t, err)
   376  	require.Equal(t, "0x4ed479841384358f765966486782abb598ece1d4f834a22474050d66a18ad296", root.String())
   377  	expectedProof := []string{"0x83fc198de31e1b2b1a8212d2430fbb7766c13d9ad305637dea3759065606475d", "0x2815e0bbb1ec18b8b1bc64454a86d072e12ee5d43bb559b44059e01edff0af7a", "0x7fb6cc0f2120368a845cf435da7102ff6e369280f787bc51b8a989fc178f7252", "0x407db5edcdc0ddd4f7327f208f46db40c4c4dbcc46c94a757e1d1654acbd8b72", "0xce2cdd1ef2e87e82264532285998ff37024404ab3a2b77b50eb1ad856ae83e14", "0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d", "0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968", "0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83", "0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af", "0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0", "0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5", "0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892", "0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c", "0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb", "0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc", "0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2", "0x2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f", "0xe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a", "0x5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0", "0xb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0", "0xc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2", "0xf4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9", "0x5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377", "0x4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652", "0xcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef", "0x0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d", "0xb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0", "0x838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e", "0x662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e", "0x388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322", "0x93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735", "0x8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9"}
   378  	for i := 0; i < len(siblings); i++ {
   379  		require.Equal(t, expectedProof[i], "0x"+hex.EncodeToString(siblings[i][:]))
   380  	}
   381  }
   382  
   383  func TestCheckMerkleProof(t *testing.T) {
   384  	expectedRoot := common.HexToHash("0x5ba002329b53c11a2f1dfe90b11e031771842056cf2125b43da8103c199dcd7f")
   385  	var index uint
   386  	var height uint8 = 32
   387  	amount, _ := big.NewInt(0).SetString("10000000000000000000", 0)
   388  	deposit := &etherman.Deposit{
   389  		OriginalNetwork:    0,
   390  		OriginalAddress:    common.Address{},
   391  		Amount:             amount,
   392  		DestinationNetwork: 1,
   393  		DestinationAddress: common.HexToAddress("0xc949254d682d8c9ad5682521675b8f43b102aec4"),
   394  		BlockNumber:        0,
   395  		DepositCount:       0,
   396  		Metadata:           []byte{},
   397  	}
   398  	leafHash := hashDeposit(deposit)
   399  	smtProof := [][KeyLen]byte{
   400  		common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
   401  		common.HexToHash("0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"),
   402  		common.HexToHash("0xb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30"),
   403  		common.HexToHash("0x21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85"),
   404  		common.HexToHash("0xe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344"),
   405  		common.HexToHash("0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d"),
   406  		common.HexToHash("0x887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968"),
   407  		common.HexToHash("0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83"),
   408  		common.HexToHash("0x9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af"),
   409  		common.HexToHash("0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0"),
   410  		common.HexToHash("0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5"),
   411  		common.HexToHash("0xf8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892"),
   412  		common.HexToHash("0x3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c"),
   413  		common.HexToHash("0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb"),
   414  		common.HexToHash("0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc"),
   415  		common.HexToHash("0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2"),
   416  		common.HexToHash("0x2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f"),
   417  		common.HexToHash("0xe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a"),
   418  		common.HexToHash("0x5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0"),
   419  		common.HexToHash("0xb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0"),
   420  		common.HexToHash("0xc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2"),
   421  		common.HexToHash("0xf4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9"),
   422  		common.HexToHash("0x5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377"),
   423  		common.HexToHash("0x4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652"),
   424  		common.HexToHash("0xcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef"),
   425  		common.HexToHash("0x0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d"),
   426  		common.HexToHash("0xb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0"),
   427  		common.HexToHash("0x838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e"),
   428  		common.HexToHash("0x662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e"),
   429  		common.HexToHash("0x388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322"),
   430  		common.HexToHash("0x93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735"),
   431  		common.HexToHash("0x8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9"),
   432  	}
   433  	root := calculateRoot(leafHash, smtProof, index, height)
   434  	assert.Equal(t, expectedRoot, root)
   435  }
   436  
   437  func TestPerformanceComputeRoot(t *testing.T) {
   438  	ctx := context.Background()
   439  	dbCfg := pgstorage.NewConfigFromEnv()
   440  	err := pgstorage.InitOrReset(dbCfg)
   441  	require.NoError(t, err)
   442  	store, err := pgstorage.NewPostgresStorage(dbCfg)
   443  	require.NoError(t, err)
   444  	mt, err := NewMerkleTree(ctx, store, uint8(32), 0)
   445  	require.NoError(t, err)
   446  	var leaves [][KeyLen]byte
   447  	initTime := time.Now().Unix()
   448  	log.Debug("Init creating leaves: ", initTime)
   449  	for i := 0; i < 10000000; i++ {
   450  		leaves = append(leaves, common.Hash{})
   451  	}
   452  	log.Debug("End creating leaves: ", time.Now().Unix()-initTime)
   453  	initTime = time.Now().Unix()
   454  	log.Debug("Init computing root: ", initTime)
   455  	_, err = mt.buildMTRoot(leaves)
   456  	require.NoError(t, err)
   457  	log.Debug("End creating leaves: ", time.Now().Unix()-initTime)
   458  }