github.com/klaytn/klaytn@v1.12.1/node/sc/bridge_manager_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package sc
    18  
    19  import (
    20  	"context"
    21  	"encoding/hex"
    22  	"log"
    23  	"math/big"
    24  	"math/rand"
    25  	"os"
    26  	"path"
    27  	"strconv"
    28  	"sync"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/golang/mock/gomock"
    33  	"github.com/klaytn/klaytn/accounts"
    34  	"github.com/klaytn/klaytn/accounts/abi/bind"
    35  	"github.com/klaytn/klaytn/accounts/abi/bind/backends"
    36  	"github.com/klaytn/klaytn/accounts/keystore"
    37  	"github.com/klaytn/klaytn/blockchain"
    38  	"github.com/klaytn/klaytn/blockchain/types"
    39  	"github.com/klaytn/klaytn/blockchain/vm"
    40  	"github.com/klaytn/klaytn/common"
    41  	"github.com/klaytn/klaytn/contracts/bridge"
    42  	sctoken "github.com/klaytn/klaytn/contracts/sc_erc20"
    43  	scnft "github.com/klaytn/klaytn/contracts/sc_erc721"
    44  	scnft_no_uri "github.com/klaytn/klaytn/contracts/sc_erc721_no_uri"
    45  	"github.com/klaytn/klaytn/crypto"
    46  	"github.com/klaytn/klaytn/node/sc/bridgepool"
    47  	"github.com/klaytn/klaytn/params"
    48  	"github.com/klaytn/klaytn/rlp"
    49  	"github.com/klaytn/klaytn/storage/database"
    50  	"github.com/stretchr/testify/assert"
    51  )
    52  
    53  // WaitGroupWithTimeOut waits the given wait group until the timout duration.
    54  func WaitGroupWithTimeOut(wg *sync.WaitGroup, duration time.Duration, t *testing.T) {
    55  	c := make(chan struct{})
    56  	go func() {
    57  		wg.Wait()
    58  		c <- struct{}{}
    59  	}()
    60  	t.Log("start to wait group")
    61  	select {
    62  	case <-c:
    63  		t.Log("waiting group is done")
    64  	case <-time.After(duration):
    65  		t.Fatal("timed out waiting group")
    66  	}
    67  }
    68  
    69  // CheckReceipt can check if the tx receipt has expected status.
    70  func CheckReceipt(b bind.DeployBackend, tx *types.Transaction, duration time.Duration, expectedStatus uint, t *testing.T) {
    71  	timeoutContext, cancelTimeout := context.WithTimeout(context.Background(), duration)
    72  	defer cancelTimeout()
    73  
    74  	receipt, err := bind.WaitMined(timeoutContext, b, tx)
    75  	assert.Equal(t, nil, err)
    76  	assert.Equal(t, expectedStatus, receipt.Status)
    77  }
    78  
    79  func handleValueTransfer(t *testing.T, ev IRequestValueTransferEvent, bridgeInfo *BridgeInfo, wg *sync.WaitGroup, backend *backends.SimulatedBackend) {
    80  	var (
    81  		tokenType      = ev.GetTokenType()
    82  		valueOrTokenId = ev.GetValueOrTokenId()
    83  		from           = ev.GetFrom()
    84  		to             = ev.GetTo()
    85  		contractAddr   = ev.GetRaw().Address
    86  		tokenAddr      = ev.GetTokenAddress()
    87  		requestNonce   = ev.GetRequestNonce()
    88  		txHash         = ev.GetRaw().TxHash
    89  	)
    90  	t.Log("Request Event",
    91  		"type", tokenType,
    92  		"amount", valueOrTokenId,
    93  		"from", from.String(),
    94  		"to", to.String(),
    95  		"contract", contractAddr.String(),
    96  		"token", tokenAddr.String(),
    97  		"requestNonce", requestNonce)
    98  
    99  	bridge := bridgeInfo.bridge
   100  	done, err := bridge.HandledRequestTx(nil, txHash)
   101  	assert.NoError(t, err)
   102  	assert.Equal(t, false, done)
   103  
   104  	// insert the value transfer request event to the bridge info's event list.
   105  	bridgeInfo.AddRequestValueTransferEvents([]IRequestValueTransferEvent{ev})
   106  
   107  	// handle the value transfer request event in the event list.
   108  	bridgeInfo.processingPendingRequestEvents()
   109  
   110  	backend.Commit() // block
   111  	wg.Done()
   112  	done, err = bridge.HandledRequestTx(nil, txHash)
   113  	assert.NoError(t, err)
   114  	assert.Equal(t, true, done)
   115  }
   116  
   117  // TestBridgeManager tests the event/method of Token/NFT/Bridge contracts.
   118  // TODO-Klaytn-Servicechain needs to refine this test.
   119  // - consider parent/child chain simulated backend.
   120  // - separate each test
   121  func TestBridgeManager(t *testing.T) {
   122  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
   123  	assert.NoError(t, err)
   124  	defer func() {
   125  		if err := os.RemoveAll(tempDir); err != nil {
   126  			t.Fatalf("fail to delete file %v", err)
   127  		}
   128  	}()
   129  
   130  	wg := sync.WaitGroup{}
   131  	wg.Add(10)
   132  
   133  	// Config Bridge Account Manager
   134  	config := &SCConfig{}
   135  	config.DataDir = tempDir
   136  	bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
   137  	bacc.pAccount.chainID = big.NewInt(0)
   138  	bacc.cAccount.chainID = big.NewInt(0)
   139  
   140  	pAuth := bacc.cAccount.GenerateTransactOpts()
   141  	cAuth := bacc.pAccount.GenerateTransactOpts()
   142  
   143  	// Generate a new random account and a funded simulator
   144  	aliceKey, _ := crypto.GenerateKey()
   145  	alice := bind.NewKeyedTransactor(aliceKey)
   146  
   147  	bobKey, _ := crypto.GenerateKey()
   148  	bob := bind.NewKeyedTransactor(bobKey)
   149  
   150  	// Create Simulated backend
   151  	alloc := blockchain.GenesisAlloc{
   152  		alice.From:            {Balance: big.NewInt(params.KLAY)},
   153  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
   154  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
   155  	}
   156  	sim := backends.NewSimulatedBackend(alloc)
   157  	defer sim.Close()
   158  
   159  	sc := &SubBridge{
   160  		chainDB:        database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}),
   161  		config:         config,
   162  		peers:          newBridgePeerSet(),
   163  		bridgeAccounts: bacc,
   164  		localBackend:   sim,
   165  		remoteBackend:  sim,
   166  	}
   167  	sc.handler, err = NewSubBridgeHandler(sc)
   168  	if err != nil {
   169  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
   170  		return
   171  	}
   172  
   173  	bridgeManager, err := NewBridgeManager(sc)
   174  	assert.NoError(t, err)
   175  
   176  	testToken := big.NewInt(123)
   177  	testKLAY := big.NewInt(321)
   178  
   179  	// 1. Deploy Bridge Contract
   180  	addr, err := bridgeManager.DeployBridgeTest(sim, 10000, false)
   181  	if err != nil {
   182  		log.Fatalf("Failed to deploy new bridge contract: %v", err)
   183  	}
   184  	bridgeInfo, _ := bridgeManager.GetBridgeInfo(addr)
   185  	bridge := bridgeInfo.bridge
   186  	t.Log("===== BridgeContract Addr ", addr.Hex())
   187  	sim.Commit() // block
   188  
   189  	// 2. Deploy Token Contract
   190  	tokenAddr, tx, token, err := sctoken.DeployServiceChainToken(alice, sim, addr)
   191  	if err != nil {
   192  		log.Fatalf("Failed to DeployGXToken: %v", err)
   193  	}
   194  	sim.Commit() // block
   195  
   196  	// 3. Deploy NFT Contract
   197  	nftAddr, tx, nft, err := scnft.DeployServiceChainNFT(alice, sim, addr)
   198  	if err != nil {
   199  		log.Fatalf("Failed to DeployServiceChainNFT: %v", err)
   200  	}
   201  	sim.Commit() // block
   202  
   203  	// Register the owner as a signer
   204  	_, err = bridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From)
   205  	assert.NoError(t, err)
   206  	sim.Commit() // block
   207  
   208  	// Register tokens on the bridgeInfo
   209  	bridgeInfo.RegisterToken(tokenAddr, tokenAddr)
   210  	bridgeInfo.RegisterToken(nftAddr, nftAddr)
   211  
   212  	// Register tokens on the bridge
   213  	bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, tokenAddr)
   214  	bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, nftAddr, nftAddr)
   215  	sim.Commit() // block
   216  
   217  	cTokenAddr, err := bridge.RegisteredTokens(nil, tokenAddr)
   218  	assert.Equal(t, err, nil)
   219  	assert.Equal(t, cTokenAddr, tokenAddr)
   220  	cNftAddr, err := bridge.RegisteredTokens(nil, nftAddr)
   221  	assert.Equal(t, err, nil)
   222  	assert.Equal(t, cNftAddr, nftAddr)
   223  
   224  	balance, _ := sim.BalanceAt(context.Background(), pAuth.From, nil)
   225  	t.Logf("auth(%v) KLAY balance : %v\n", pAuth.From.String(), balance)
   226  
   227  	balance, _ = sim.BalanceAt(context.Background(), cAuth.From, nil)
   228  	t.Logf("auth2(%v) KLAY balance : %v\n", cAuth.From.String(), balance)
   229  
   230  	balance, _ = sim.BalanceAt(context.Background(), alice.From, nil)
   231  	t.Logf("auth3(%v) KLAY balance : %v\n", alice.From.String(), balance)
   232  
   233  	balance, _ = sim.BalanceAt(context.Background(), bob.From, nil)
   234  	t.Logf("auth4(%v) KLAY balance : %v\n", bob.From.String(), balance)
   235  
   236  	// 4. Subscribe Bridge Contract
   237  	bridgeManager.SubscribeEvent(addr)
   238  
   239  	reqVTevCh := make(chan RequestValueTransferEvent)
   240  	reqVTencodedEvCh := make(chan RequestValueTransferEncodedEvent)
   241  	handleValueTransferEventCh := make(chan *HandleValueTransferEvent)
   242  	bridgeManager.SubscribeReqVTev(reqVTevCh)
   243  	bridgeManager.SubscribeReqVTencodedEv(reqVTencodedEvCh)
   244  	bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh)
   245  
   246  	go func() {
   247  		for {
   248  			select {
   249  			case ev := <-reqVTevCh:
   250  				handleValueTransfer(t, ev, bridgeInfo, &wg, sim)
   251  			case ev := <-reqVTencodedEvCh:
   252  				handleValueTransfer(t, ev, bridgeInfo, &wg, sim)
   253  			case ev := <-handleValueTransferEventCh:
   254  				t.Log("Handle value transfer event",
   255  					"bridgeAddr", ev.Raw.Address.Hex(),
   256  					"type", ev.TokenType,
   257  					"amount", ev.ValueOrTokenId,
   258  					"owner", ev.To.String(),
   259  					"contract", ev.Raw.Address.String(),
   260  					"token", ev.TokenAddress.String(),
   261  					"handleNonce", ev.HandleNonce)
   262  				wg.Done()
   263  			}
   264  		}
   265  	}()
   266  
   267  	nftTokenIDs := []uint64{4437, 4438, 4439}
   268  	testURIs := []string{"", "testURI", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
   269  	// 6. Register (Mint) an NFT to Alice
   270  	{
   271  		for i := 0; i < len(nftTokenIDs); i++ {
   272  			tx, err = nft.MintWithTokenURI(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, alice.From, big.NewInt(int64(nftTokenIDs[i])), testURIs[i])
   273  			assert.NoError(t, err)
   274  			t.Log("Register NFT Transaction", tx.Hash().Hex())
   275  			sim.Commit() // block
   276  			CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   277  
   278  			owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenIDs[i])))
   279  			assert.Equal(t, nil, err)
   280  			assert.Equal(t, alice.From, owner)
   281  		}
   282  	}
   283  
   284  	// 7. Request ERC20 Transfer from Alice to Bob
   285  	{
   286  		tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, testToken, bob.From, big.NewInt(0), nil)
   287  		assert.NoError(t, err)
   288  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   289  		sim.Commit() // block
   290  
   291  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   292  	}
   293  
   294  	// 8. RequestKLAYTransfer from Alice to Bob
   295  	{
   296  		tx, err = bridge.RequestKLAYTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, Value: testKLAY, GasLimit: testGasLimit}, bob.From, testKLAY, nil)
   297  		assert.NoError(t, err)
   298  		t.Log("DepositKLAY Transaction", tx.Hash().Hex())
   299  
   300  		sim.Commit() // block
   301  
   302  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   303  	}
   304  
   305  	// 9. Request NFT transfer from Alice to Bob
   306  	{
   307  		for i := 0; i < len(nftTokenIDs); i++ {
   308  			tx, err = nft.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, big.NewInt(int64(nftTokenIDs[i])), bob.From, nil)
   309  			assert.NoError(t, err)
   310  			t.Log("nft.RequestValueTransfer Transaction", tx.Hash().Hex())
   311  			sim.Commit() // block
   312  			CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   313  
   314  			uri, err := nft.TokenURI(nil, big.NewInt(int64(nftTokenIDs[i])))
   315  			assert.NoError(t, err)
   316  			assert.Equal(t, testURIs[i], uri)
   317  			t.Log("URI length: ", len(testURIs[i]), len(uri))
   318  		}
   319  	}
   320  
   321  	// Wait a few second for wait group
   322  	WaitGroupWithTimeOut(&wg, 3*time.Second, t)
   323  
   324  	// 10. Check Token balance
   325  	{
   326  		balance, err = token.BalanceOf(nil, bob.From)
   327  		assert.Equal(t, nil, err)
   328  		assert.Equal(t, testToken.String(), balance.String())
   329  	}
   330  
   331  	// 11. Check KLAY balance
   332  	{
   333  		balance, err = sim.BalanceAt(context.Background(), bob.From, nil)
   334  		assert.Equal(t, nil, err)
   335  		assert.Equal(t, testKLAY.String(), balance.String())
   336  	}
   337  
   338  	// 12. Check NFT owner sent by RequestValueTransfer()
   339  	{
   340  		for i := 0; i < len(nftTokenIDs); i++ {
   341  			owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenIDs[i])))
   342  			assert.Equal(t, nil, err)
   343  			assert.Equal(t, bob.From, owner)
   344  		}
   345  	}
   346  	bridgeManager.Stop()
   347  }
   348  
   349  // TestBridgeManagerERC721_notSupportURI tests if bridge can handle an ERC721 which does not support URI.
   350  func TestBridgeManagerERC721_notSupportURI(t *testing.T) {
   351  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
   352  	assert.NoError(t, err)
   353  	defer func() {
   354  		if err := os.RemoveAll(tempDir); err != nil {
   355  			t.Fatalf("fail to delete file %v", err)
   356  		}
   357  	}()
   358  
   359  	wg := sync.WaitGroup{}
   360  	wg.Add(2)
   361  
   362  	// Config Bridge Account Manager
   363  	config := &SCConfig{}
   364  	config.DataDir = tempDir
   365  	bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
   366  	bacc.pAccount.chainID = big.NewInt(0)
   367  	bacc.cAccount.chainID = big.NewInt(0)
   368  
   369  	// pAuth := bacc.cAccount.GenerateTransactOpts()
   370  	cAuth := bacc.pAccount.GenerateTransactOpts()
   371  
   372  	// Generate a new random account and a funded simulator
   373  	aliceKey, _ := crypto.GenerateKey()
   374  	alice := bind.NewKeyedTransactor(aliceKey)
   375  
   376  	bobKey, _ := crypto.GenerateKey()
   377  	bob := bind.NewKeyedTransactor(bobKey)
   378  
   379  	// Create Simulated backend
   380  	alloc := blockchain.GenesisAlloc{
   381  		alice.From:            {Balance: big.NewInt(params.KLAY)},
   382  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
   383  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
   384  	}
   385  	sim := backends.NewSimulatedBackend(alloc)
   386  	defer sim.Close()
   387  
   388  	sc := &SubBridge{
   389  		chainDB:        database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}),
   390  		config:         config,
   391  		peers:          newBridgePeerSet(),
   392  		bridgeAccounts: bacc,
   393  		localBackend:   sim,
   394  		remoteBackend:  sim,
   395  	}
   396  
   397  	sc.handler, err = NewSubBridgeHandler(sc)
   398  	if err != nil {
   399  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
   400  		return
   401  	}
   402  
   403  	bridgeManager, err := NewBridgeManager(sc)
   404  	assert.NoError(t, err)
   405  
   406  	// Deploy Bridge Contract
   407  	addr, err := bridgeManager.DeployBridgeTest(sim, 10000, false)
   408  	if err != nil {
   409  		log.Fatalf("Failed to deploy new bridge contract: %v", err)
   410  	}
   411  	bridgeInfo, _ := bridgeManager.GetBridgeInfo(addr)
   412  	bridge := bridgeInfo.bridge
   413  	t.Log("===== BridgeContract Addr ", addr.Hex())
   414  	sim.Commit() // block
   415  
   416  	// Deploy NFT Contract
   417  	nftTokenID := uint64(4438)
   418  	nftAddr, tx, nft, err := scnft_no_uri.DeployServiceChainNFTNoURI(alice, sim, addr)
   419  	if err != nil {
   420  		log.Fatalf("Failed to DeployServiceChainNFT: %v", err)
   421  	}
   422  
   423  	nft_uri, err := scnft.NewServiceChainNFT(nftAddr, sim)
   424  	if err != nil {
   425  		log.Fatalf("Failed to get NFT object: %v", err)
   426  	}
   427  
   428  	sim.Commit() // block
   429  
   430  	// Register the owner as a signer
   431  	_, err = bridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From)
   432  	assert.NoError(t, err)
   433  	sim.Commit() // block
   434  
   435  	// Register tokens on the bridgeInfo
   436  	bridgeInfo.RegisterToken(nftAddr, nftAddr)
   437  
   438  	// Register tokens on the bridge
   439  	bridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, nftAddr, nftAddr)
   440  	sim.Commit() // block
   441  
   442  	cNftAddr, err := bridge.RegisteredTokens(nil, nftAddr)
   443  	assert.Equal(t, err, nil)
   444  	assert.Equal(t, cNftAddr, nftAddr)
   445  
   446  	// Subscribe Bridge Contract
   447  	bridgeManager.SubscribeEvent(addr)
   448  
   449  	reqVTevCh := make(chan RequestValueTransferEvent)
   450  	reqVTencodedEvCh := make(chan RequestValueTransferEncodedEvent)
   451  	handleValueTransferEventCh := make(chan *HandleValueTransferEvent)
   452  	bridgeManager.SubscribeReqVTev(reqVTevCh)
   453  	bridgeManager.SubscribeReqVTencodedEv(reqVTencodedEvCh)
   454  	bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh)
   455  
   456  	go func() {
   457  		for {
   458  			select {
   459  			case ev := <-reqVTevCh:
   460  				handleValueTransfer(t, ev, bridgeInfo, &wg, sim)
   461  			case ev := <-reqVTencodedEvCh:
   462  				handleValueTransfer(t, ev, bridgeInfo, &wg, sim)
   463  			case ev := <-handleValueTransferEventCh:
   464  				t.Log("Handle value transfer event",
   465  					"bridgeAddr", ev.Raw.Address.Hex(),
   466  					"type", ev.TokenType,
   467  					"amount", ev.ValueOrTokenId,
   468  					"owner", ev.To.String(),
   469  					"contract", ev.Raw.Address.String(),
   470  					"token", ev.TokenAddress.String(),
   471  					"handleNonce", ev.HandleNonce)
   472  				wg.Done()
   473  			}
   474  		}
   475  	}()
   476  
   477  	// Register (Mint) an NFT to Alice
   478  	{
   479  		tx, err = nft.Mint(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, alice.From, big.NewInt(int64(nftTokenID)))
   480  		assert.NoError(t, err)
   481  		t.Log("Register NFT Transaction", tx.Hash().Hex())
   482  		sim.Commit() // block
   483  
   484  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   485  
   486  		owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenID)))
   487  		assert.Equal(t, nil, err)
   488  		assert.Equal(t, alice.From, owner)
   489  	}
   490  
   491  	// Request NFT transfer from Alice to Bob
   492  	{
   493  		tx, err = nft.RequestValueTransfer(&bind.TransactOpts{From: alice.From, Signer: alice.Signer, GasLimit: testGasLimit}, big.NewInt(int64(nftTokenID)), bob.From, nil)
   494  		assert.NoError(t, err)
   495  		t.Log("nft.RequestValueTransfer Transaction", tx.Hash().Hex())
   496  
   497  		sim.Commit() // block
   498  
   499  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   500  		uri, err := nft_uri.TokenURI(nil, big.NewInt(int64(nftTokenID)))
   501  		assert.Equal(t, vm.ErrExecutionReverted, err)
   502  		assert.Equal(t, "", uri)
   503  	}
   504  
   505  	// Wait a few second for wait group
   506  	WaitGroupWithTimeOut(&wg, 3*time.Second, t)
   507  
   508  	// Check NFT owner
   509  	{
   510  		owner, err := nft.OwnerOf(nil, big.NewInt(int64(nftTokenID)))
   511  		assert.Equal(t, nil, err)
   512  		assert.Equal(t, bob.From, owner)
   513  	}
   514  
   515  	bridgeManager.Stop()
   516  }
   517  
   518  // TestBridgeManagerWithFee tests the KLAY/ERC20 transfer with fee.
   519  func TestBridgeManagerWithFee(t *testing.T) {
   520  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
   521  	assert.NoError(t, err)
   522  	defer func() {
   523  		if err := os.RemoveAll(tempDir); err != nil {
   524  			t.Fatalf("fail to delete file %v", err)
   525  		}
   526  	}()
   527  
   528  	wg := sync.WaitGroup{}
   529  	wg.Add(7 * 2)
   530  
   531  	// Generate a new random account and a funded simulator
   532  	AliceKey, _ := crypto.GenerateKey()
   533  	Alice := bind.NewKeyedTransactor(AliceKey)
   534  
   535  	BobKey, _ := crypto.GenerateKey()
   536  	Bob := bind.NewKeyedTransactor(BobKey)
   537  
   538  	receiverKey, _ := crypto.GenerateKey()
   539  	receiver := bind.NewKeyedTransactor(receiverKey)
   540  
   541  	// Config Bridge Account Manager
   542  	config := &SCConfig{}
   543  	config.DataDir = tempDir
   544  	bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
   545  	bacc.pAccount.chainID = big.NewInt(0)
   546  	bacc.cAccount.chainID = big.NewInt(0)
   547  
   548  	pAuth := bacc.cAccount.GenerateTransactOpts()
   549  	cAuth := bacc.pAccount.GenerateTransactOpts()
   550  
   551  	// Create Simulated backend
   552  	initialValue := int64(10000000000)
   553  	alloc := blockchain.GenesisAlloc{
   554  		Alice.From:            {Balance: big.NewInt(initialValue)},
   555  		bacc.cAccount.address: {Balance: big.NewInt(initialValue)},
   556  		bacc.pAccount.address: {Balance: big.NewInt(initialValue)},
   557  	}
   558  	sim := backends.NewSimulatedBackend(alloc)
   559  	defer sim.Close()
   560  
   561  	sc := &SubBridge{
   562  		chainDB:        database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}),
   563  		config:         config,
   564  		peers:          newBridgePeerSet(),
   565  		bridgeAccounts: bacc,
   566  	}
   567  	sc.handler, err = NewSubBridgeHandler(sc)
   568  	if err != nil {
   569  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
   570  		return
   571  	}
   572  
   573  	bridgeManager, err := NewBridgeManager(sc)
   574  
   575  	testToken := int64(100000)
   576  	testKLAY := int64(100000)
   577  	KLAYFee := int64(500)
   578  	ERC20Fee := int64(500)
   579  
   580  	// 1. Deploy Bridge Contract
   581  	pBridgeAddr, err := bridgeManager.DeployBridgeTest(sim, 10000, false)
   582  	assert.NoError(t, err)
   583  	pBridgeInfo, _ := bridgeManager.GetBridgeInfo(pBridgeAddr)
   584  	pBridge := pBridgeInfo.bridge
   585  	t.Log("===== BridgeContract Addr ", pBridgeAddr.Hex())
   586  	sim.Commit() // block
   587  
   588  	// 2. Deploy Token Contract
   589  	tokenAddr, tx, token, err := sctoken.DeployServiceChainToken(pAuth, sim, pBridgeAddr)
   590  	assert.NoError(t, err)
   591  	sim.Commit() // block
   592  
   593  	// Set value transfer fee
   594  	{
   595  		nilReceiver, err := pBridge.FeeReceiver(nil)
   596  		assert.Equal(t, nil, err)
   597  		assert.Equal(t, common.Address{}, nilReceiver)
   598  	}
   599  
   600  	pBridge.SetFeeReceiver(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, receiver.From)
   601  	sim.Commit() // block
   602  
   603  	{
   604  		recv, err := pBridge.FeeReceiver(nil)
   605  		assert.Equal(t, nil, err)
   606  		assert.Equal(t, receiver.From, recv)
   607  	}
   608  
   609  	{
   610  		fee, err := pBridge.FeeOfKLAY(nil)
   611  		assert.Equal(t, nil, err)
   612  		assert.Equal(t, big.NewInt(0).String(), fee.String())
   613  	}
   614  
   615  	{
   616  		fee, err := pBridge.FeeOfERC20(nil, tokenAddr)
   617  		assert.Equal(t, nil, err)
   618  		assert.Equal(t, big.NewInt(0).String(), fee.String())
   619  	}
   620  
   621  	cn, err := pBridge.ConfigurationNonce(nil)
   622  	assert.NoError(t, err)
   623  	_, err = pBridge.RegisterOperator(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, cAuth.From)
   624  	assert.NoError(t, err)
   625  	pBridge.SetKLAYFee(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, big.NewInt(KLAYFee), cn)
   626  	pBridge.SetERC20Fee(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, big.NewInt(ERC20Fee), cn+1)
   627  	sim.Commit() // block
   628  
   629  	{
   630  		fee, err := pBridge.FeeOfKLAY(nil)
   631  		assert.Equal(t, nil, err)
   632  		assert.Equal(t, KLAYFee, fee.Int64())
   633  	}
   634  
   635  	{
   636  		fee, err := pBridge.FeeOfERC20(nil, tokenAddr)
   637  		assert.Equal(t, nil, err)
   638  		assert.Equal(t, ERC20Fee, fee.Int64())
   639  	}
   640  
   641  	// Register tokens on the bridgeInfo
   642  	pBridgeInfo.RegisterToken(tokenAddr, tokenAddr)
   643  
   644  	// Register tokens on the bridge
   645  	pBridge.RegisterToken(&bind.TransactOpts{From: cAuth.From, Signer: cAuth.Signer, GasLimit: testGasLimit}, tokenAddr, tokenAddr)
   646  	sim.Commit() // block
   647  
   648  	cTokenAddr, err := pBridge.RegisteredTokens(nil, tokenAddr)
   649  	assert.Equal(t, err, nil)
   650  	assert.Equal(t, cTokenAddr, tokenAddr)
   651  
   652  	balance, _ := sim.BalanceAt(context.Background(), Alice.From, nil)
   653  	t.Logf("Alice(%v) KLAY balance : %v\n", Alice.From.String(), balance)
   654  
   655  	balance, _ = sim.BalanceAt(context.Background(), Bob.From, nil)
   656  	t.Logf("Bob(%v) KLAY balance : %v\n", Bob.From.String(), balance)
   657  
   658  	// 4. Subscribe Bridge Contract
   659  	bridgeManager.SubscribeEvent(pBridgeAddr)
   660  
   661  	reqVTevCh := make(chan RequestValueTransferEvent)
   662  	handleValueTransferEventCh := make(chan *HandleValueTransferEvent)
   663  	bridgeManager.SubscribeReqVTev(reqVTevCh)
   664  	bridgeManager.SubscribeHandleVTev(handleValueTransferEventCh)
   665  
   666  	go func() {
   667  		for {
   668  			select {
   669  			case ev := <-reqVTevCh:
   670  				t.Log("Request value transfer event",
   671  					"type", ev.GetTokenType(),
   672  					"amount", ev.GetValueOrTokenId(),
   673  					"from", ev.GetFrom().String(),
   674  					"to", ev.GetTo().String(),
   675  					"contract", ev.GetRaw().Address.String(),
   676  					"token", ev.GetTokenAddress().String(),
   677  					"requestNonce", ev.GetRequestNonce(),
   678  					"fee", ev.GetFee().String())
   679  
   680  				// insert the value transfer request event to the bridge info's event list.
   681  				pBridgeInfo.AddRequestValueTransferEvents([]IRequestValueTransferEvent{ev})
   682  
   683  				// handle the value transfer request event in the event list.
   684  				pBridgeInfo.processingPendingRequestEvents()
   685  
   686  				sim.Commit() // block
   687  				wg.Done()
   688  
   689  			case ev := <-handleValueTransferEventCh:
   690  				t.Log("Handle value transfer event",
   691  					"bridgeAddr", ev.Raw.Address.Hex(),
   692  					"type", ev.TokenType,
   693  					"amount", ev.ValueOrTokenId,
   694  					"owner", ev.To.String(),
   695  					"contract", ev.Raw.Address.String(),
   696  					"token", ev.TokenAddress.String(),
   697  					"handleNonce", ev.HandleNonce)
   698  				wg.Done()
   699  			}
   700  		}
   701  	}()
   702  
   703  	// 5. transfer from parentAcc to Alice for charging and check balances
   704  	{
   705  		tx, err = token.Transfer(&bind.TransactOpts{From: pAuth.From, Signer: pAuth.Signer, GasLimit: testGasLimit}, Alice.From, big.NewInt(initialValue))
   706  		if err != nil {
   707  			log.Fatalf("Failed to Transfer for charging: %v", err)
   708  		}
   709  		t.Log("Transfer Transaction", tx.Hash().Hex())
   710  		sim.Commit() // block
   711  
   712  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   713  
   714  		balance, err = token.BalanceOf(nil, pAuth.From)
   715  		assert.Equal(t, nil, err)
   716  		t.Log("parentAcc token balance", balance.String())
   717  
   718  		balance, err = token.BalanceOf(nil, Alice.From)
   719  		assert.Equal(t, nil, err)
   720  		t.Log("Alice token balance", balance.String())
   721  
   722  		balance, err = token.BalanceOf(nil, Bob.From)
   723  		assert.Equal(t, nil, err)
   724  		t.Log("Bob token balance", balance.String())
   725  	}
   726  
   727  	// 7-1. Request ERC20 Transfer from Alice to Bob with same feeLimit with fee
   728  	{
   729  		tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee), nil)
   730  		assert.NoError(t, err)
   731  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   732  		sim.Commit() // block
   733  
   734  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   735  	}
   736  
   737  	// 7-2. Request ERC20 Transfer from Alice to Bob with insufficient zero feeLimit
   738  	{
   739  		tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(0), nil)
   740  		assert.Equal(t, nil, err)
   741  
   742  		sim.Commit() // block
   743  
   744  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   745  	}
   746  
   747  	// 7-3. Request ERC20 Transfer from Alice to Bob with insufficient feeLimit
   748  	{
   749  		tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee-1), nil)
   750  		assert.Equal(t, nil, err)
   751  
   752  		sim.Commit() // block
   753  
   754  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   755  	}
   756  
   757  	// 7-4. Request ERC20 Transfer from Alice to Bob with enough feeLimit
   758  	{
   759  		tx, err = token.RequestValueTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, big.NewInt(testToken), Bob.From, big.NewInt(ERC20Fee+1), nil)
   760  		assert.Equal(t, nil, err)
   761  
   762  		sim.Commit() // block
   763  
   764  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   765  	}
   766  
   767  	// 8-1. Approve/Request ERC20 Transfer from Alice to Bob with same feeLimit with fee
   768  	{
   769  		tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee))
   770  		assert.Equal(t, nil, err)
   771  
   772  		tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee), nil)
   773  		assert.Equal(t, nil, err)
   774  
   775  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   776  		sim.Commit() // block
   777  
   778  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   779  	}
   780  
   781  	// 8-2. Approve/Request ERC20 Transfer from Alice to Bob with insufficient zero feeLimit
   782  	{
   783  		tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken))
   784  		assert.Equal(t, nil, err)
   785  
   786  		tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(0), nil)
   787  		assert.Equal(t, nil, err)
   788  
   789  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   790  		sim.Commit() // block
   791  
   792  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   793  	}
   794  
   795  	// 8-3. Approve/Request ERC20 Transfer from Alice to Bob with insufficient feeLimit
   796  	{
   797  		tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee-1))
   798  		assert.Equal(t, nil, err)
   799  
   800  		tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee-1), nil)
   801  		assert.Equal(t, nil, err)
   802  
   803  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   804  		sim.Commit() // block
   805  
   806  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   807  	}
   808  
   809  	// 8-4. Approve/Request ERC20 Transfer from Alice to Bob with enough feeLimit
   810  	{
   811  		tx, err = token.Approve(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, pBridgeAddr, big.NewInt(testToken+ERC20Fee+1))
   812  		assert.Equal(t, nil, err)
   813  
   814  		tx, err = pBridge.RequestERC20Transfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, GasLimit: testGasLimit}, tokenAddr, Bob.From, big.NewInt(testToken), big.NewInt(ERC20Fee+1), nil)
   815  		assert.Equal(t, nil, err)
   816  
   817  		t.Log("RequestValueTransfer Transaction", tx.Hash().Hex())
   818  		sim.Commit() // block
   819  
   820  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   821  	}
   822  
   823  	// 9-1. Request KLAY transfer from Alice to Bob with same feeLimit with fee
   824  	{
   825  		tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + KLAYFee), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil)
   826  		if err != nil {
   827  			log.Fatalf("Failed to RequestKLAYTransfer: %v", err)
   828  		}
   829  		t.Log("RequestKLAYTransfer Transaction", tx.Hash().Hex())
   830  
   831  		sim.Commit() // block
   832  
   833  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   834  	}
   835  
   836  	// 9-2. Request KLAY transfer from Alice to Bob with zero feeLimit
   837  	{
   838  		tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil)
   839  		assert.Equal(t, nil, err)
   840  
   841  		sim.Commit() // block
   842  
   843  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   844  	}
   845  
   846  	// 9-3. Request KLAY transfer from Alice to Bob with insufficient feeLimit
   847  	{
   848  		tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + (KLAYFee - 1)), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil)
   849  		assert.Equal(t, nil, err)
   850  
   851  		sim.Commit() // block
   852  
   853  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusErrExecutionReverted, t)
   854  	}
   855  
   856  	// 9-4. Request KLAY transfer from Alice to Bob with enough feeLimit
   857  	{
   858  		tx, err = pBridge.RequestKLAYTransfer(&bind.TransactOpts{From: Alice.From, Signer: Alice.Signer, Value: big.NewInt(testKLAY + (KLAYFee + 1)), GasLimit: testGasLimit}, Bob.From, big.NewInt(testKLAY), nil)
   859  		assert.Equal(t, nil, err)
   860  
   861  		sim.Commit() // block
   862  
   863  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   864  	}
   865  
   866  	// 9-4. Request KLAY transfer from Alice to Alice through () payable method
   867  	{
   868  		nonce, _ := sim.PendingNonceAt(context.Background(), Alice.From)
   869  		gasPrice, _ := sim.SuggestGasPrice(context.Background())
   870  		unsignedTx := types.NewTransaction(nonce, pBridgeAddr, big.NewInt(testKLAY+KLAYFee), testGasLimit, gasPrice, []byte{})
   871  
   872  		chainID, _ := sim.ChainID(context.Background())
   873  		tx, err = types.SignTx(unsignedTx, types.LatestSignerForChainID(chainID), AliceKey)
   874  		sim.SendTransaction(context.Background(), tx)
   875  		assert.Equal(t, nil, err)
   876  
   877  		sim.Commit() // block
   878  
   879  		CheckReceipt(sim, tx, 1*time.Second, types.ReceiptStatusSuccessful, t)
   880  	}
   881  
   882  	// Wait a few second for wait group
   883  	WaitGroupWithTimeOut(&wg, 3*time.Second, t)
   884  
   885  	// 10. Check Token balance
   886  	{
   887  		balance, err = token.BalanceOf(nil, Alice.From)
   888  		assert.Equal(t, nil, err)
   889  		t.Log("Alice token balance", balance.String())
   890  		assert.Equal(t, initialValue-(testToken+ERC20Fee)*4, balance.Int64())
   891  
   892  		balance, err = token.BalanceOf(nil, Bob.From)
   893  		assert.Equal(t, nil, err)
   894  		t.Log("Bob token balance", balance.String())
   895  		assert.Equal(t, testToken*4, balance.Int64())
   896  
   897  		balance, err = token.BalanceOf(nil, receiver.From)
   898  		assert.Equal(t, nil, err)
   899  		t.Log("Fee receiver token balance", balance.String())
   900  		assert.Equal(t, ERC20Fee*4, balance.Int64())
   901  	}
   902  
   903  	// 11. Check KLAY balance
   904  	{
   905  		balance, _ = sim.BalanceAt(context.Background(), Alice.From, nil)
   906  		t.Log("Alice KLAY balance :", balance)
   907  		assert.Equal(t, initialValue-(testKLAY+KLAYFee)*2-KLAYFee, balance.Int64())
   908  
   909  		balance, _ = sim.BalanceAt(context.Background(), Bob.From, nil)
   910  		t.Log("Bob KLAY balance :", balance)
   911  		assert.Equal(t, big.NewInt(testKLAY*2).String(), balance.String())
   912  
   913  		balance, _ = sim.BalanceAt(context.Background(), receiver.From, nil)
   914  		t.Log("receiver KLAY balance :", balance)
   915  		assert.Equal(t, KLAYFee*3, balance.Int64())
   916  	}
   917  
   918  	bridgeManager.Stop()
   919  }
   920  
   921  // TestBasicJournal tests basic journal functionality.
   922  func TestBasicJournal(t *testing.T) {
   923  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
   924  	assert.NoError(t, err)
   925  	defer func() {
   926  		if err := os.RemoveAll(tempDir); err != nil {
   927  			t.Fatalf("fail to delete file %v", err)
   928  		}
   929  	}()
   930  
   931  	wg := sync.WaitGroup{}
   932  	wg.Add(2)
   933  
   934  	// Generate a new random account and a funded simulator
   935  	key, _ := crypto.GenerateKey()
   936  	auth := bind.NewKeyedTransactor(key)
   937  
   938  	key2, _ := crypto.GenerateKey()
   939  	auth2 := bind.NewKeyedTransactor(key2)
   940  
   941  	key4, _ := crypto.GenerateKey()
   942  	auth4 := bind.NewKeyedTransactor(key4)
   943  
   944  	config := &SCConfig{}
   945  	config.DataDir = tempDir
   946  	config.VTRecovery = true
   947  
   948  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
   949  	bacc.pAccount.chainID = big.NewInt(0)
   950  	bacc.cAccount.chainID = big.NewInt(0)
   951  
   952  	alloc := blockchain.GenesisAlloc{
   953  		auth.From:             {Balance: big.NewInt(params.KLAY)},
   954  		auth2.From:            {Balance: big.NewInt(params.KLAY)},
   955  		auth4.From:            {Balance: big.NewInt(params.KLAY)},
   956  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
   957  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
   958  	}
   959  	sim := backends.NewSimulatedBackend(alloc)
   960  	defer sim.Close()
   961  
   962  	sc := &SubBridge{
   963  		config:         config,
   964  		peers:          newBridgePeerSet(),
   965  		localBackend:   sim,
   966  		remoteBackend:  sim,
   967  		bridgeAccounts: bacc,
   968  	}
   969  	sc.handler, err = NewSubBridgeHandler(sc)
   970  	if err != nil {
   971  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
   972  		return
   973  	}
   974  
   975  	// Prepare manager and deploy bridge contract.
   976  	bm, err := NewBridgeManager(sc)
   977  	assert.NoError(t, err)
   978  
   979  	localAddr, err := bm.DeployBridgeTest(sim, 10000, true)
   980  	assert.NoError(t, err)
   981  	remoteAddr, err := bm.DeployBridgeTest(sim, 10000, false)
   982  	assert.NoError(t, err)
   983  
   984  	bm.SetJournal("", localAddr, remoteAddr)
   985  
   986  	ps := sc.BridgePeerSet()
   987  	ps.peers["test"] = nil
   988  
   989  	if err := bm.RestoreBridges(); err != nil {
   990  		t.Fatal("bm restoring bridges failed")
   991  	}
   992  
   993  	localInfo, ok := bm.GetBridgeInfo(localAddr)
   994  	assert.Equal(t, true, ok)
   995  	assert.Equal(t, false, localInfo.subscribed)
   996  
   997  	remoteInfo, ok := bm.GetBridgeInfo(remoteAddr)
   998  	assert.Equal(t, true, ok)
   999  	assert.Equal(t, false, remoteInfo.subscribed)
  1000  }
  1001  
  1002  // TestMethodRestoreBridges tests restoring bridges from the journal.
  1003  func TestMethodRestoreBridges(t *testing.T) {
  1004  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1005  	assert.NoError(t, err)
  1006  	defer func() {
  1007  		if err := os.RemoveAll(tempDir); err != nil {
  1008  			t.Fatalf("fail to delete file %v", err)
  1009  		}
  1010  	}()
  1011  
  1012  	wg := sync.WaitGroup{}
  1013  	wg.Add(2)
  1014  
  1015  	// Generate a new random account and a funded simulator
  1016  	key, _ := crypto.GenerateKey()
  1017  	auth := bind.NewKeyedTransactor(key)
  1018  
  1019  	key2, _ := crypto.GenerateKey()
  1020  	auth2 := bind.NewKeyedTransactor(key2)
  1021  
  1022  	key4, _ := crypto.GenerateKey()
  1023  	auth4 := bind.NewKeyedTransactor(key4)
  1024  	config := &SCConfig{}
  1025  	config.DataDir = tempDir
  1026  	config.VTRecovery = true
  1027  	config.VTRecoveryInterval = 60
  1028  
  1029  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1030  	bacc.pAccount.chainID = big.NewInt(0)
  1031  	bacc.cAccount.chainID = big.NewInt(0)
  1032  
  1033  	alloc := blockchain.GenesisAlloc{
  1034  		auth.From:             {Balance: big.NewInt(params.KLAY)},
  1035  		auth2.From:            {Balance: big.NewInt(params.KLAY)},
  1036  		auth4.From:            {Balance: big.NewInt(params.KLAY)},
  1037  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  1038  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  1039  	}
  1040  	sim := backends.NewSimulatedBackend(alloc)
  1041  	defer sim.Close()
  1042  
  1043  	sc := &SubBridge{
  1044  		config:         config,
  1045  		peers:          newBridgePeerSet(),
  1046  		localBackend:   sim,
  1047  		remoteBackend:  sim,
  1048  		bridgeAccounts: bacc,
  1049  	}
  1050  
  1051  	sc.handler, err = NewSubBridgeHandler(sc)
  1052  	if err != nil {
  1053  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1054  		return
  1055  	}
  1056  
  1057  	// Prepare manager and deploy bridge contract.
  1058  	bm, err := NewBridgeManager(sc)
  1059  	assert.NoError(t, err)
  1060  
  1061  	var bridgeAddrs [4]common.Address
  1062  	for i := 0; i < 4; i++ {
  1063  		if i%2 == 0 {
  1064  			bridgeAddrs[i], err = bm.DeployBridgeTest(sim, 10000, true)
  1065  		} else {
  1066  			bridgeAddrs[i], err = bm.DeployBridgeTest(sim, 10000, false)
  1067  		}
  1068  		if err != nil {
  1069  			t.Fatal("deploy bridge test failed", bridgeAddrs[i])
  1070  		}
  1071  		bm.DeleteBridgeInfo(bridgeAddrs[i])
  1072  	}
  1073  	sim.Commit()
  1074  
  1075  	// Set journal
  1076  	bm.SetJournal("", bridgeAddrs[0], bridgeAddrs[1])
  1077  	bm.journal.cache[bridgeAddrs[0]].Subscribed = true
  1078  	bm.SetJournal("", bridgeAddrs[2], bridgeAddrs[3])
  1079  	bm.journal.cache[bridgeAddrs[2]].Subscribed = true
  1080  
  1081  	ps := sc.BridgePeerSet()
  1082  	ps.peers["test"] = nil
  1083  
  1084  	// Call RestoreBridges
  1085  	if err := bm.RestoreBridges(); err != nil {
  1086  		t.Fatal("bm restoring bridges failed")
  1087  	}
  1088  
  1089  	// Duplicated RestoreBridges
  1090  	if err := bm.RestoreBridges(); err != nil {
  1091  		t.Fatal("bm restoring bridges failed")
  1092  	}
  1093  
  1094  	// Case 1: check bridge contract creation.
  1095  	for i := 0; i < 4; i++ {
  1096  		info, _ := bm.GetBridgeInfo(bridgeAddrs[i])
  1097  		assert.NotEqual(t, nil, info.bridge)
  1098  	}
  1099  
  1100  	// Case 2: check subscription
  1101  	for i := 0; i < 4; i++ {
  1102  		info, _ := bm.GetBridgeInfo(bridgeAddrs[i])
  1103  		assert.Equal(t, true, info.subscribed)
  1104  	}
  1105  
  1106  	// Case 3: check recovery
  1107  	recovery1 := bm.recoveries[bridgeAddrs[0]]
  1108  	assert.NotEqual(t, nil, recovery1)
  1109  	recovery1.Start()
  1110  	assert.Equal(t, nil, recovery1.WaitRunningStatus(true, 5*time.Second))
  1111  	recovery2 := bm.recoveries[bridgeAddrs[2]]
  1112  	assert.NotEqual(t, nil, recovery2)
  1113  	recovery2.Start()
  1114  	assert.Equal(t, nil, recovery2.WaitRunningStatus(true, 5*time.Second))
  1115  
  1116  	bm.stopAllRecoveries()
  1117  	bm.Stop()
  1118  }
  1119  
  1120  // TestMethodGetAllBridge tests a method GetAllBridge.
  1121  func TestMethodGetAllBridge(t *testing.T) {
  1122  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1123  	assert.NoError(t, err)
  1124  	defer func() {
  1125  		if err := os.RemoveAll(tempDir); err != nil {
  1126  			t.Fatalf("fail to delete file %v", err)
  1127  		}
  1128  	}()
  1129  
  1130  	sc := &SubBridge{
  1131  		config: &SCConfig{DataDir: tempDir, VTRecovery: true},
  1132  		peers:  newBridgePeerSet(),
  1133  	}
  1134  	bm, err := NewBridgeManager(sc)
  1135  	if err != nil {
  1136  		t.Fatalf("fail to create bridge manager %v", err)
  1137  	}
  1138  
  1139  	testBridge1 := common.BytesToAddress([]byte("test1"))
  1140  	testBridge2 := common.BytesToAddress([]byte("test2"))
  1141  
  1142  	bm.journal.insert("", testBridge1, testBridge2)
  1143  	bm.journal.insert("", testBridge2, testBridge1)
  1144  
  1145  	bridges := bm.GetAllBridge()
  1146  	assert.Equal(t, 2, len(bridges))
  1147  
  1148  	bm.Stop()
  1149  }
  1150  
  1151  // TestErrorDuplication tests if duplication of journal insertion is ignored or not.
  1152  func TestErrorDuplication(t *testing.T) {
  1153  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1154  	assert.NoError(t, err)
  1155  	defer func() {
  1156  		if err := os.RemoveAll(tempDir); err != nil {
  1157  			t.Fatalf("fail to delete file %v", err)
  1158  		}
  1159  	}()
  1160  
  1161  	sc := &SubBridge{
  1162  		config: &SCConfig{DataDir: tempDir, VTRecovery: true},
  1163  		peers:  newBridgePeerSet(),
  1164  	}
  1165  	bm, err := NewBridgeManager(sc)
  1166  	if err != nil {
  1167  		t.Fatalf("fail to create bridge manager %v", err)
  1168  	}
  1169  
  1170  	localAddr := common.BytesToAddress([]byte("test1"))
  1171  	remoteAddr := common.BytesToAddress([]byte("test2"))
  1172  
  1173  	err = bm.journal.insert("", localAddr, remoteAddr)
  1174  	assert.Equal(t, nil, err)
  1175  	err = bm.journal.insert("", remoteAddr, localAddr)
  1176  	assert.Equal(t, nil, err)
  1177  
  1178  	// try duplicated insert.
  1179  	err = bm.journal.insert("", localAddr, remoteAddr)
  1180  	assert.NotEqual(t, nil, err)
  1181  	err = bm.journal.insert("", remoteAddr, localAddr)
  1182  	assert.NotEqual(t, nil, err)
  1183  
  1184  	// check cache size for checking duplication
  1185  	bridges := bm.GetAllBridge()
  1186  	assert.Equal(t, 2, len(bridges))
  1187  
  1188  	bm.Stop()
  1189  }
  1190  
  1191  // TestMethodSetJournal tests if duplication of journal insertion is ignored or not.
  1192  func TestMethodSetJournal(t *testing.T) {
  1193  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1194  	assert.NoError(t, err)
  1195  	defer func() {
  1196  		if err := os.RemoveAll(tempDir); err != nil {
  1197  			t.Fatalf("fail to delete file %v", err)
  1198  		}
  1199  	}()
  1200  
  1201  	sc := &SubBridge{
  1202  		config: &SCConfig{DataDir: tempDir, VTRecovery: true},
  1203  		peers:  newBridgePeerSet(),
  1204  	}
  1205  	bm, err := NewBridgeManager(sc)
  1206  	if err != nil {
  1207  		t.Fatalf("fail to create bridge manager %v", err)
  1208  	}
  1209  
  1210  	localAddr := common.BytesToAddress([]byte("test1"))
  1211  	remoteAddr := common.BytesToAddress([]byte("test2"))
  1212  
  1213  	// Simple insert case
  1214  	err = bm.SetJournal("", localAddr, remoteAddr)
  1215  	assert.Equal(t, nil, err)
  1216  
  1217  	// Error case
  1218  	err = bm.SetJournal("", localAddr, remoteAddr)
  1219  	assert.NotEqual(t, nil, err)
  1220  
  1221  	// Check the number of bridge elements for checking duplication
  1222  	bridges := bm.GetAllBridge()
  1223  	assert.Equal(t, 1, len(bridges))
  1224  
  1225  	bm.Stop()
  1226  }
  1227  
  1228  // TestErrorDuplicatedSetBridgeInfo tests if duplication of bridge info insertion.
  1229  func TestErrorDuplicatedSetBridgeInfo(t *testing.T) {
  1230  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1231  	assert.NoError(t, err)
  1232  	defer func() {
  1233  		if err := os.RemoveAll(tempDir); err != nil {
  1234  			t.Fatalf("fail to delete file %v", err)
  1235  		}
  1236  	}()
  1237  
  1238  	wg := sync.WaitGroup{}
  1239  	wg.Add(2)
  1240  
  1241  	// Generate a new random account and a funded simulator
  1242  	key, _ := crypto.GenerateKey()
  1243  	auth := bind.NewKeyedTransactor(key)
  1244  
  1245  	key2, _ := crypto.GenerateKey()
  1246  	auth2 := bind.NewKeyedTransactor(key2)
  1247  
  1248  	key4, _ := crypto.GenerateKey()
  1249  	auth4 := bind.NewKeyedTransactor(key4)
  1250  	config := &SCConfig{}
  1251  	config.DataDir = tempDir
  1252  	config.VTRecovery = true
  1253  
  1254  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1255  	bacc.pAccount.chainID = big.NewInt(0)
  1256  	bacc.cAccount.chainID = big.NewInt(0)
  1257  
  1258  	alloc := blockchain.GenesisAlloc{
  1259  		auth.From:             {Balance: big.NewInt(params.KLAY)},
  1260  		auth2.From:            {Balance: big.NewInt(params.KLAY)},
  1261  		auth4.From:            {Balance: big.NewInt(params.KLAY)},
  1262  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  1263  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  1264  	}
  1265  	sim := backends.NewSimulatedBackend(alloc)
  1266  	defer sim.Close()
  1267  
  1268  	sc := &SubBridge{
  1269  		config:         config,
  1270  		peers:          newBridgePeerSet(),
  1271  		localBackend:   sim,
  1272  		remoteBackend:  sim,
  1273  		bridgeAccounts: bacc,
  1274  	}
  1275  
  1276  	sc.handler, err = NewSubBridgeHandler(sc)
  1277  	if err != nil {
  1278  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1279  		return
  1280  	}
  1281  
  1282  	// Prepare manager
  1283  	bm, err := NewBridgeManager(sc)
  1284  	assert.NoError(t, err)
  1285  	addr, err := bm.DeployBridgeTest(sim, 10000, false)
  1286  	assert.NoError(t, err)
  1287  	bridgeInfo, _ := bm.GetBridgeInfo(addr)
  1288  
  1289  	// Try to call duplicated SetBridgeInfo
  1290  	err = bm.SetBridgeInfo(addr, bridgeInfo.bridge, common.Address{}, nil, sc.bridgeAccounts.pAccount, false, false)
  1291  	assert.NotEqual(t, nil, err)
  1292  	bm.Stop()
  1293  }
  1294  
  1295  // TestScenarioSubUnsub tests subscription and unsubscription scenario.
  1296  func TestScenarioSubUnsub(t *testing.T) {
  1297  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1298  	assert.NoError(t, err)
  1299  	defer func() {
  1300  		if err := os.RemoveAll(tempDir); err != nil {
  1301  			t.Fatalf("fail to delete file %v", err)
  1302  		}
  1303  	}()
  1304  
  1305  	wg := sync.WaitGroup{}
  1306  	wg.Add(2)
  1307  
  1308  	// Generate a new random account and a funded simulator
  1309  	key, _ := crypto.GenerateKey()
  1310  	auth := bind.NewKeyedTransactor(key)
  1311  
  1312  	key2, _ := crypto.GenerateKey()
  1313  	auth2 := bind.NewKeyedTransactor(key2)
  1314  
  1315  	key4, _ := crypto.GenerateKey()
  1316  	auth4 := bind.NewKeyedTransactor(key4)
  1317  	config := &SCConfig{}
  1318  	config.DataDir = tempDir
  1319  	config.VTRecovery = true
  1320  
  1321  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1322  	bacc.pAccount.chainID = big.NewInt(0)
  1323  	bacc.cAccount.chainID = big.NewInt(0)
  1324  
  1325  	alloc := blockchain.GenesisAlloc{
  1326  		auth.From:             {Balance: big.NewInt(params.KLAY)},
  1327  		auth2.From:            {Balance: big.NewInt(params.KLAY)},
  1328  		auth4.From:            {Balance: big.NewInt(params.KLAY)},
  1329  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  1330  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  1331  	}
  1332  	sim := backends.NewSimulatedBackend(alloc)
  1333  	defer sim.Close()
  1334  
  1335  	sc := &SubBridge{
  1336  		config:         config,
  1337  		peers:          newBridgePeerSet(),
  1338  		localBackend:   sim,
  1339  		remoteBackend:  sim,
  1340  		bridgeAccounts: bacc,
  1341  	}
  1342  
  1343  	sc.handler, err = NewSubBridgeHandler(sc)
  1344  	if err != nil {
  1345  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1346  		return
  1347  	}
  1348  
  1349  	// Prepare manager and deploy bridge contract.
  1350  	bm, err := NewBridgeManager(sc)
  1351  	assert.NoError(t, err)
  1352  
  1353  	localAddr, err := bm.DeployBridgeTest(sim, 10000, true)
  1354  	if err != nil {
  1355  		t.Fatal("deploy bridge test failed", localAddr)
  1356  	}
  1357  
  1358  	bm.SubscribeEvent(localAddr)
  1359  	bridgeInfo, ok := bm.GetBridgeInfo(localAddr)
  1360  	assert.Equal(t, true, ok)
  1361  	assert.Equal(t, true, bridgeInfo.subscribed)
  1362  	bm.UnsubscribeEvent(localAddr)
  1363  	assert.Equal(t, false, bridgeInfo.subscribed)
  1364  
  1365  	// Journal is irrelevant to the bridge unsubscription.
  1366  	journal := bm.journal.cache[localAddr]
  1367  	assert.NotEqual(t, nil, journal)
  1368  }
  1369  
  1370  // TestErrorEmptyAccount tests empty account error in case of journal insertion.
  1371  func TestErrorEmptyAccount(t *testing.T) {
  1372  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1373  	assert.NoError(t, err)
  1374  	defer func() {
  1375  		if err := os.RemoveAll(tempDir); err != nil {
  1376  			t.Fatalf("fail to delete file %v", err)
  1377  		}
  1378  	}()
  1379  
  1380  	sc := &SubBridge{
  1381  		config: &SCConfig{DataDir: tempDir, VTRecovery: true},
  1382  		peers:  newBridgePeerSet(),
  1383  	}
  1384  	bm, err := NewBridgeManager(sc)
  1385  	if err != nil {
  1386  		t.Fatalf("fail to create bridge manager %v", err)
  1387  	}
  1388  
  1389  	localAddr := common.BytesToAddress([]byte("test1"))
  1390  	remoteAddr := common.BytesToAddress([]byte("test2"))
  1391  
  1392  	err = bm.journal.insert("", localAddr, common.Address{})
  1393  	assert.NotEqual(t, nil, err)
  1394  
  1395  	err = bm.journal.insert("", common.Address{}, remoteAddr)
  1396  	assert.NotEqual(t, nil, err)
  1397  
  1398  	bm.Stop()
  1399  }
  1400  
  1401  // TestErrorDupSubscription tests duplicated subscription error.
  1402  func TestErrorDupSubscription(t *testing.T) {
  1403  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  1404  	assert.NoError(t, err)
  1405  	defer func() {
  1406  		if err := os.RemoveAll(tempDir); err != nil {
  1407  			t.Fatalf("fail to delete file %v", err)
  1408  		}
  1409  	}()
  1410  
  1411  	wg := sync.WaitGroup{}
  1412  	wg.Add(2)
  1413  
  1414  	// Generate a new random account and a funded simulator
  1415  	key, _ := crypto.GenerateKey()
  1416  	auth := bind.NewKeyedTransactor(key)
  1417  
  1418  	key2, _ := crypto.GenerateKey()
  1419  	auth2 := bind.NewKeyedTransactor(key2)
  1420  
  1421  	key4, _ := crypto.GenerateKey()
  1422  	auth4 := bind.NewKeyedTransactor(key4)
  1423  	config := &SCConfig{}
  1424  	config.DataDir = tempDir
  1425  	config.VTRecovery = true
  1426  
  1427  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1428  	bacc.pAccount.chainID = big.NewInt(0)
  1429  	bacc.cAccount.chainID = big.NewInt(0)
  1430  
  1431  	alloc := blockchain.GenesisAlloc{
  1432  		auth.From:             {Balance: big.NewInt(params.KLAY)},
  1433  		auth2.From:            {Balance: big.NewInt(params.KLAY)},
  1434  		auth4.From:            {Balance: big.NewInt(params.KLAY)},
  1435  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  1436  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  1437  	}
  1438  	sim := backends.NewSimulatedBackend(alloc)
  1439  	defer sim.Close()
  1440  
  1441  	sc := &SubBridge{
  1442  		config:         config,
  1443  		peers:          newBridgePeerSet(),
  1444  		localBackend:   sim,
  1445  		remoteBackend:  sim,
  1446  		bridgeAccounts: bacc,
  1447  	}
  1448  
  1449  	sc.handler, err = NewSubBridgeHandler(sc)
  1450  	if err != nil {
  1451  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1452  		return
  1453  	}
  1454  
  1455  	// 1. Prepare manager and subscribe event
  1456  	bm, err := NewBridgeManager(sc)
  1457  	assert.NoError(t, err)
  1458  
  1459  	addr, err := bm.DeployBridgeTest(sim, 10000, false)
  1460  	bridgeInfo, _ := bm.GetBridgeInfo(addr)
  1461  	bridge := bridgeInfo.bridge
  1462  	t.Log("===== BridgeContract Addr ", addr.Hex())
  1463  	sim.Commit() // block
  1464  
  1465  	bm.bridges[addr], err = NewBridgeInfo(sc, addr, bridge, common.Address{}, nil, bacc.cAccount, true, true, sim)
  1466  
  1467  	bm.journal.cache[addr] = &BridgeJournal{"", addr, addr, true, false}
  1468  
  1469  	bm.SubscribeEvent(addr)
  1470  	err = bm.SubscribeEvent(addr)
  1471  	assert.NotEqual(t, nil, err)
  1472  
  1473  	bm.Stop()
  1474  }
  1475  
  1476  // TestAnchoringBasic tests the following:
  1477  // 1. generate anchoring tx
  1478  // 2. decode anchoring tx
  1479  // 3. start anchoring from the current block
  1480  // 4. accumulated tx counts
  1481  func TestAnchoringBasic(t *testing.T) {
  1482  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoring")
  1483  	assert.NoError(t, err)
  1484  	defer func() {
  1485  		if err := os.RemoveAll(tempDir); err != nil {
  1486  			t.Fatalf("fail to delete file %v", err)
  1487  		}
  1488  	}()
  1489  
  1490  	sim, sc, bAcc, _, _, _ := generateAnchoringEnv(t, tempDir)
  1491  	defer sim.Close()
  1492  
  1493  	assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber)
  1494  	assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber)
  1495  	assert.Equal(t, uint64(1), sc.handler.chainTxPeriod)
  1496  
  1497  	auth := bAcc.pAccount.GenerateTransactOpts()
  1498  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1499  	sim.Commit()
  1500  	curBlk := sim.BlockChain().CurrentBlock()
  1501  
  1502  	// nil block
  1503  	{
  1504  		err := sc.handler.blockAnchoringManager(nil)
  1505  		assert.Error(t, ErrInvalidBlock, err)
  1506  	}
  1507  
  1508  	{
  1509  		err := sc.handler.generateAndAddAnchoringTxIntoTxPool(nil)
  1510  		assert.Error(t, ErrInvalidBlock, err)
  1511  	}
  1512  	// Generate anchoring tx again for the curBlk.
  1513  	err = sc.handler.blockAnchoringManager(curBlk)
  1514  	assert.NoError(t, err)
  1515  
  1516  	pending := sc.GetBridgeTxPool().Pending()
  1517  	assert.Equal(t, 1, len(pending))
  1518  	var tx *types.Transaction
  1519  	for _, v := range pending {
  1520  		assert.Equal(t, 1, len(v))
  1521  		tx = v[0]
  1522  	}
  1523  	assert.Equal(t, uint64(0), sc.handler.txCount)
  1524  
  1525  	assert.Equal(t, curBlk.NumberU64(), sc.handler.latestTxCountAddedBlockNumber)
  1526  	compareBlockAndAnchoringTx(t, curBlk, tx)
  1527  }
  1528  
  1529  // TestAnchoringBasicWithFeePayer tests the following with feePayer:
  1530  // 1. generate anchoring tx
  1531  // 2. decode anchoring tx
  1532  // 3. start anchoring from the current block
  1533  // 4. accumulated tx counts
  1534  func TestAnchoringBasicWithFeePayer(t *testing.T) {
  1535  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoring")
  1536  	assert.NoError(t, err)
  1537  	defer func() {
  1538  		if err := os.RemoveAll(tempDir); err != nil {
  1539  			t.Fatalf("fail to delete file %v", err)
  1540  		}
  1541  	}()
  1542  
  1543  	sim, sc, bAcc, parentOperator, feePayer, tester := generateAnchoringEnv(t, tempDir)
  1544  	defer sim.Close()
  1545  
  1546  	invalidAccount := common.HexToAddress("0x1")
  1547  	bAcc.SetParentOperatorFeePayer(feePayer.Address)
  1548  
  1549  	assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber)
  1550  	assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber)
  1551  	assert.Equal(t, uint64(1), sc.handler.chainTxPeriod)
  1552  
  1553  	// fail to generate anchoring tx with invalid parent operator
  1554  	{
  1555  		pAccBackup := bAcc.pAccount.address
  1556  		bAcc.pAccount.address = invalidAccount
  1557  
  1558  		curBlk := sim.BlockChain().CurrentBlock()
  1559  		err = sc.handler.generateAndAddAnchoringTxIntoTxPool(curBlk)
  1560  		assert.Error(t, err, accounts.ErrUnknownAccount)
  1561  
  1562  		bAcc.pAccount.address = pAccBackup
  1563  	}
  1564  
  1565  	// fail to generate anchoring tx with invalid feePayer
  1566  	{
  1567  		bAcc.SetParentOperatorFeePayer(invalidAccount)
  1568  
  1569  		curBlk := sim.BlockChain().CurrentBlock()
  1570  		err = sc.handler.generateAndAddAnchoringTxIntoTxPool(curBlk)
  1571  		assert.Error(t, err, accounts.ErrUnknownAccount)
  1572  
  1573  		bAcc.SetParentOperatorFeePayer(feePayer.Address)
  1574  	}
  1575  
  1576  	_, _, _, err = bridge.DeployBridge(tester, sim, true) // dummy tx
  1577  	sim.Commit()
  1578  	curBlk := sim.BlockChain().CurrentBlock()
  1579  
  1580  	// Generate anchoring tx again for the curBlk.
  1581  	sc.handler.blockAnchoringManager(curBlk)
  1582  	pending := sc.GetBridgeTxPool().Pending()
  1583  	assert.Equal(t, 1, len(pending))
  1584  	var tx *types.Transaction
  1585  	for _, v := range pending {
  1586  		assert.Equal(t, 1, len(v))
  1587  		tx = v[0]
  1588  
  1589  		// Check Balance
  1590  		feePayerBalanceBefore, err := sim.BalanceAt(context.Background(), feePayer.Address, nil)
  1591  		assert.NoError(t, err)
  1592  		parentOperatorBalanceBefore, err := sim.BalanceAt(context.Background(), parentOperator.address, nil)
  1593  		assert.NoError(t, err)
  1594  
  1595  		sim.SendTransaction(context.Background(), tx)
  1596  		sim.Commit()
  1597  
  1598  		// Check Balance
  1599  		feePayerBalanceAfter, err := sim.BalanceAt(context.Background(), feePayer.Address, nil)
  1600  		assert.NoError(t, err)
  1601  		parentOperatorBalanceAfter, err := sim.BalanceAt(context.Background(), parentOperator.address, nil)
  1602  		assert.NoError(t, err)
  1603  
  1604  		receipt, err := sim.TransactionReceipt(context.Background(), tx.Hash())
  1605  		assert.NoError(t, err)
  1606  
  1607  		fee := new(big.Int).SetUint64(receipt.GasUsed * params.DefaultUnitPrice)
  1608  
  1609  		assert.Equal(t, new(big.Int).Sub(feePayerBalanceBefore, fee).String(), feePayerBalanceAfter.String())
  1610  		t.Log("feePayer paid ", fee)
  1611  		assert.Equal(t, parentOperatorBalanceBefore, parentOperatorBalanceAfter)
  1612  	}
  1613  
  1614  	assert.Equal(t, uint64(0), sc.handler.txCount)
  1615  	assert.Equal(t, curBlk.NumberU64(), sc.handler.latestTxCountAddedBlockNumber)
  1616  	compareBlockAndAnchoringTx(t, curBlk, tx)
  1617  }
  1618  
  1619  // TestAnchoringBasicWithBridgeTxPoolMock tests the following :
  1620  // - BridgeTxPool addLocal() fail case.
  1621  func TestAnchoringBasicWithBridgeTxPoolMock(t *testing.T) {
  1622  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoring")
  1623  	assert.NoError(t, err)
  1624  	defer func() {
  1625  		if err := os.RemoveAll(tempDir); err != nil {
  1626  			t.Fatalf("fail to delete file %v", err)
  1627  		}
  1628  	}()
  1629  
  1630  	sim, sc, bAcc, _, feePayer, _ := generateAnchoringEnv(t, tempDir)
  1631  	defer sim.Close()
  1632  
  1633  	// mock BridgeTxPool
  1634  	{
  1635  		mockCtrl := gomock.NewController(t)
  1636  		defer mockCtrl.Finish()
  1637  		mockBridgeTxPool := NewMockBridgeTxPool(mockCtrl)
  1638  		sc.bridgeTxPool = mockBridgeTxPool
  1639  		mockBridgeTxPool.EXPECT().AddLocal(gomock.Any()).Return(bridgepool.ErrKnownTx)
  1640  	}
  1641  
  1642  	bAcc.SetParentOperatorFeePayer(feePayer.Address)
  1643  
  1644  	assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber)
  1645  	assert.Equal(t, uint64(0), sc.handler.latestTxCountAddedBlockNumber)
  1646  	assert.Equal(t, uint64(1), sc.handler.chainTxPeriod)
  1647  
  1648  	curBlk := sim.BlockChain().CurrentBlock()
  1649  
  1650  	// Generate anchoring tx with mocked BridgeTxPool returns a error
  1651  	err = sc.handler.blockAnchoringManager(curBlk)
  1652  	assert.Equal(t, bridgepool.ErrKnownTx, err)
  1653  }
  1654  
  1655  func generateAnchoringEnv(t *testing.T, tempDir string) (*backends.SimulatedBackend, *SubBridge, *BridgeAccounts, *accountInfo, accounts.Account, *bind.TransactOpts) {
  1656  	config := &SCConfig{AnchoringPeriod: 1}
  1657  	config.DataDir = tempDir
  1658  	config.VTRecovery = true
  1659  
  1660  	ks := keystore.NewKeyStore(tempDir, keystore.StandardScryptN, keystore.StandardScryptP)
  1661  	back := []accounts.Backend{
  1662  		ks,
  1663  	}
  1664  	am := accounts.NewManager(back...)
  1665  	bAcc, _ := NewBridgeAccounts(am, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1666  	bAcc.pAccount.chainID = big.NewInt(0)
  1667  	bAcc.cAccount.chainID = big.NewInt(0)
  1668  	parentOperator := bAcc.pAccount
  1669  
  1670  	aliceKey, _ := crypto.GenerateKey()
  1671  	alice := bind.NewKeyedTransactor(aliceKey)
  1672  
  1673  	initBal := new(big.Int).Exp(big.NewInt(10), big.NewInt(50), nil)
  1674  
  1675  	feePayer, err := ks.NewAccount("pwd")
  1676  	assert.NoError(t, err)
  1677  	ks.TimedUnlock(feePayer, "pwd", 0)
  1678  
  1679  	alloc := blockchain.GenesisAlloc{
  1680  		alice.From:             {Balance: initBal},
  1681  		feePayer.Address:       {Balance: initBal},
  1682  		parentOperator.address: {Balance: initBal},
  1683  	}
  1684  	sim := backends.NewSimulatedBackendWithGasPrice(alloc, params.DefaultUnitPrice)
  1685  
  1686  	sc := &SubBridge{
  1687  		config:         config,
  1688  		peers:          newBridgePeerSet(),
  1689  		localBackend:   sim,
  1690  		remoteBackend:  sim,
  1691  		bridgeAccounts: bAcc,
  1692  	}
  1693  	sc.blockchain = sim.BlockChain()
  1694  
  1695  	sc.handler, err = NewSubBridgeHandler(sc)
  1696  	if err != nil {
  1697  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1698  	}
  1699  
  1700  	sc.handler.setRemoteGasPrice(params.DefaultUnitPrice)
  1701  
  1702  	sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{
  1703  		Journal:     path.Join(tempDir, "bridge_transactions.rlp"),
  1704  		GlobalQueue: 1024,
  1705  	})
  1706  
  1707  	return sim, sc, bAcc, parentOperator, feePayer, alice
  1708  }
  1709  
  1710  func compareBlockAndAnchoringTx(t *testing.T, block *types.Block, tx *types.Transaction) {
  1711  	// Decoding the anchoring tx.
  1712  	assert.Equal(t, true, tx.Type().IsChainDataAnchoring())
  1713  	anchoringData := new(types.AnchoringData)
  1714  	data, err := tx.AnchoredData()
  1715  	assert.NoError(t, err)
  1716  
  1717  	err = rlp.DecodeBytes(data, anchoringData)
  1718  	assert.NoError(t, err)
  1719  	assert.Equal(t, types.AnchoringDataType0, anchoringData.Type)
  1720  	anchoringDataInternal := new(types.AnchoringDataInternalType0)
  1721  	if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil {
  1722  		logger.Error("writeChildChainTxHashFromBlock : failed to decode anchoring data")
  1723  	}
  1724  
  1725  	// Check the current block is anchored.
  1726  	assert.Equal(t, new(big.Int).SetUint64(block.NumberU64()).String(), anchoringDataInternal.BlockNumber.String())
  1727  	assert.Equal(t, block.Hash(), anchoringDataInternal.BlockHash)
  1728  	assert.Equal(t, big.NewInt(1).String(), anchoringDataInternal.BlockCount.String())
  1729  	assert.Equal(t, big.NewInt(1).String(), anchoringDataInternal.TxCount.String())
  1730  }
  1731  
  1732  // TestAnchoringStart tests the following:
  1733  // 1. set anchoring period 4
  1734  // 2. check if tx counting started immediately and accumulated correctly
  1735  func TestAnchoringStart(t *testing.T) {
  1736  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoringPeriod")
  1737  	assert.NoError(t, err)
  1738  	defer func() {
  1739  		if err := os.RemoveAll(tempDir); err != nil {
  1740  			t.Fatalf("fail to delete file %v", err)
  1741  		}
  1742  	}()
  1743  
  1744  	config := &SCConfig{AnchoringPeriod: 4}
  1745  	config.DataDir = tempDir
  1746  	config.VTRecovery = true
  1747  
  1748  	bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1749  	bAcc.pAccount.chainID = big.NewInt(0)
  1750  	bAcc.cAccount.chainID = big.NewInt(0)
  1751  
  1752  	alloc := blockchain.GenesisAlloc{}
  1753  	sim := backends.NewSimulatedBackend(alloc)
  1754  	defer sim.Close()
  1755  
  1756  	sc := &SubBridge{
  1757  		config:         config,
  1758  		peers:          newBridgePeerSet(),
  1759  		localBackend:   sim,
  1760  		remoteBackend:  sim,
  1761  		bridgeAccounts: bAcc,
  1762  	}
  1763  	sc.blockchain = sim.BlockChain()
  1764  
  1765  	sc.handler, err = NewSubBridgeHandler(sc)
  1766  	if err != nil {
  1767  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1768  		return
  1769  	}
  1770  	sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{
  1771  		Journal:     path.Join(tempDir, "bridge_transactions.rlp"),
  1772  		GlobalQueue: 1024,
  1773  	})
  1774  
  1775  	assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber)
  1776  	assert.Equal(t, uint64(4), sc.handler.chainTxPeriod)
  1777  
  1778  	sim.Commit() // start with arbitrary block number.
  1779  
  1780  	// 1. Fresh start with dummy tx and check tx count
  1781  	auth := bAcc.pAccount.GenerateTransactOpts()
  1782  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1783  	sim.Commit()
  1784  	curBlk := sim.BlockChain().CurrentBlock()
  1785  	sc.handler.blockAnchoringManager(curBlk)
  1786  	assert.Equal(t, uint64(1), sc.handler.txCount)
  1787  	pending := sc.GetBridgeTxPool().Pending()
  1788  	assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached.
  1789  
  1790  	// 2. Generate dummy txs and check tx count
  1791  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1792  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1793  	sim.Commit()
  1794  	curBlk = sim.BlockChain().CurrentBlock()
  1795  	sc.handler.blockAnchoringManager(curBlk)
  1796  	assert.Equal(t, uint64(3), sc.handler.txCount)
  1797  	assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached.
  1798  
  1799  	// 3. Generate dummy blocks and check anchoring tx
  1800  	sim.Commit() // block number 4
  1801  	curBlk = sim.BlockChain().CurrentBlock()
  1802  	sc.handler.blockAnchoringManager(curBlk)
  1803  	assert.Equal(t, uint64(0), sc.handler.txCount)
  1804  	pending = sc.GetBridgeTxPool().Pending()
  1805  	assert.Equal(t, 1, len(pending))
  1806  	for _, v := range pending {
  1807  		decodeAndCheckAnchoringTx(t, v[0], curBlk, 3, 3)
  1808  		break
  1809  	}
  1810  }
  1811  
  1812  // TestAnchoringPeriod tests the following:
  1813  // 1. set anchoring period 4
  1814  // 2. accumulate tx counts
  1815  func TestAnchoringPeriod(t *testing.T) {
  1816  	const (
  1817  		startTxCount = 100
  1818  	)
  1819  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoringPeriod")
  1820  	assert.NoError(t, err)
  1821  	defer func() {
  1822  		if err := os.RemoveAll(tempDir); err != nil {
  1823  			t.Fatalf("fail to delete file %v", err)
  1824  		}
  1825  	}()
  1826  
  1827  	config := &SCConfig{AnchoringPeriod: 4}
  1828  	config.DataDir = tempDir
  1829  	config.VTRecovery = true
  1830  
  1831  	bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1832  	bAcc.pAccount.chainID = big.NewInt(0)
  1833  	bAcc.cAccount.chainID = big.NewInt(0)
  1834  
  1835  	alloc := blockchain.GenesisAlloc{}
  1836  	sim := backends.NewSimulatedBackend(alloc)
  1837  	defer sim.Close()
  1838  
  1839  	sc := &SubBridge{
  1840  		config:         config,
  1841  		peers:          newBridgePeerSet(),
  1842  		localBackend:   sim,
  1843  		remoteBackend:  sim,
  1844  		bridgeAccounts: bAcc,
  1845  	}
  1846  	sc.blockchain = sim.BlockChain()
  1847  
  1848  	sc.handler, err = NewSubBridgeHandler(sc)
  1849  	if err != nil {
  1850  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1851  		return
  1852  	}
  1853  	sc.bridgeTxPool = bridgepool.NewBridgeTxPool(bridgepool.BridgeTxPoolConfig{
  1854  		Journal:     path.Join(tempDir, "bridge_transactions.rlp"),
  1855  		GlobalQueue: 1024,
  1856  	})
  1857  
  1858  	assert.Equal(t, uint64(0), sc.handler.txCountStartingBlockNumber)
  1859  	assert.Equal(t, uint64(4), sc.handler.chainTxPeriod)
  1860  
  1861  	// Period 1
  1862  	sim.Commit()
  1863  	auth := bAcc.pAccount.GenerateTransactOpts()
  1864  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1865  	sim.Commit()
  1866  	curBlk := sim.BlockChain().CurrentBlock()
  1867  
  1868  	sc.handler.txCountStartingBlockNumber = curBlk.NumberU64() - 1
  1869  	sc.handler.txCount = startTxCount
  1870  	sc.handler.blockAnchoringManager(curBlk)
  1871  	assert.Equal(t, uint64(startTxCount+1), sc.handler.txCount)
  1872  	pending := sc.GetBridgeTxPool().Pending()
  1873  	assert.Equal(t, 0, len(pending)) // the anchoring period has not yet been reached.
  1874  
  1875  	// Generate anchoring tx for the curBlk.
  1876  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1877  	sim.Commit()
  1878  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1879  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1880  	sim.Commit()
  1881  	curBlk = sim.BlockChain().CurrentBlock()
  1882  	sc.handler.blockAnchoringManager(curBlk)
  1883  	pending = sc.GetBridgeTxPool().Pending()
  1884  	assert.Equal(t, 1, len(pending))
  1885  
  1886  	for _, v := range pending {
  1887  		decodeAndCheckAnchoringTx(t, v[0], curBlk, 4, startTxCount+4)
  1888  		break
  1889  	}
  1890  
  1891  	// Period 2:
  1892  	assert.Equal(t, uint64(0), sc.handler.txCount)
  1893  	assert.Equal(t, uint64(5), sc.handler.txCountStartingBlockNumber)
  1894  
  1895  	// Generate anchoring tx.
  1896  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1897  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1898  	sim.Commit()
  1899  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1900  	sim.Commit()
  1901  	sim.Commit()
  1902  	sim.Commit()
  1903  
  1904  	curBlk = sim.BlockChain().CurrentBlock()
  1905  	sc.handler.blockAnchoringManager(curBlk)
  1906  	pending = sc.GetBridgeTxPool().Pending()
  1907  	for _, v := range pending {
  1908  		decodeAndCheckAnchoringTx(t, v[1], curBlk, 4, 3)
  1909  		break
  1910  	}
  1911  }
  1912  
  1913  // decodeAndCheckAnchoringTx decodes anchoring tx and check with a block.
  1914  func decodeAndCheckAnchoringTx(t *testing.T, tx *types.Transaction, blk *types.Block, blockCount, txCounts int64) {
  1915  	assert.Equal(t, types.TxTypeChainDataAnchoring, tx.Type())
  1916  	anchoringData := new(types.AnchoringData)
  1917  	data, err := tx.AnchoredData()
  1918  	assert.NoError(t, err)
  1919  
  1920  	err = rlp.DecodeBytes(data, anchoringData)
  1921  	assert.NoError(t, err)
  1922  	assert.Equal(t, types.AnchoringDataType0, anchoringData.Type)
  1923  	anchoringDataInternal := new(types.AnchoringDataInternalType0)
  1924  	if err := rlp.DecodeBytes(anchoringData.Data, anchoringDataInternal); err != nil {
  1925  		logger.Error("writeChildChainTxHashFromBlock : failed to decode anchoring data")
  1926  	}
  1927  
  1928  	// Check the current block is anchored.
  1929  	assert.Equal(t, new(big.Int).SetUint64(blk.NumberU64()).String(), anchoringDataInternal.BlockNumber.String())
  1930  	assert.Equal(t, blk.Hash(), anchoringDataInternal.BlockHash)
  1931  	assert.Equal(t, big.NewInt(blockCount).String(), anchoringDataInternal.BlockCount.String())
  1932  	assert.Equal(t, big.NewInt(txCounts).String(), anchoringDataInternal.TxCount.String())
  1933  }
  1934  
  1935  // TestDecodingLegacyAnchoringTx tests the following:
  1936  // 1. generate AnchoringDataLegacy anchoring tx
  1937  // 2. decode AnchoringDataLegacy with a decoding method of a sub-bridge handler.
  1938  func TestDecodingLegacyAnchoringTx(t *testing.T) {
  1939  	const (
  1940  		startBlkNum  = 10
  1941  		startTxCount = 100
  1942  	)
  1943  	tempDir, err := os.MkdirTemp(os.TempDir(), "anchoring")
  1944  	assert.NoError(t, err)
  1945  	defer func() {
  1946  		if err := os.RemoveAll(tempDir); err != nil {
  1947  			t.Fatalf("fail to delete file %v", err)
  1948  		}
  1949  	}()
  1950  
  1951  	config := &SCConfig{AnchoringPeriod: 1}
  1952  	config.DataDir = tempDir
  1953  	config.VTRecovery = true
  1954  
  1955  	bAcc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  1956  	bAcc.pAccount.chainID = big.NewInt(0)
  1957  	bAcc.cAccount.chainID = big.NewInt(0)
  1958  
  1959  	alloc := blockchain.GenesisAlloc{}
  1960  	sim := backends.NewSimulatedBackend(alloc)
  1961  	defer sim.Close()
  1962  
  1963  	sc := &SubBridge{
  1964  		config:         config,
  1965  		peers:          newBridgePeerSet(),
  1966  		localBackend:   sim,
  1967  		remoteBackend:  sim,
  1968  		bridgeAccounts: bAcc,
  1969  	}
  1970  	sc.blockchain = sim.BlockChain()
  1971  
  1972  	sc.handler, err = NewSubBridgeHandler(sc)
  1973  	if err != nil {
  1974  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  1975  		return
  1976  	}
  1977  
  1978  	// Encoding anchoring tx.
  1979  	auth := bAcc.pAccount.GenerateTransactOpts()
  1980  	_, _, _, err = bridge.DeployBridge(auth, sim, true) // dummy tx
  1981  	sim.Commit()
  1982  	curBlk := sim.BlockChain().CurrentBlock()
  1983  
  1984  	anchoringData := &types.AnchoringDataLegacy{
  1985  		BlockHash:     curBlk.Hash(),
  1986  		TxHash:        curBlk.Header().TxHash,
  1987  		ParentHash:    curBlk.Header().ParentHash,
  1988  		ReceiptHash:   curBlk.Header().ReceiptHash,
  1989  		StateRootHash: curBlk.Header().Root,
  1990  		BlockNumber:   curBlk.Header().Number,
  1991  	}
  1992  	data, err := rlp.EncodeToBytes(anchoringData)
  1993  	assert.NoError(t, err)
  1994  
  1995  	// Decoding the anchoring tx.
  1996  	decodedData, err := types.DecodeAnchoringData(data)
  1997  	assert.Equal(t, curBlk.Hash(), decodedData.GetBlockHash())
  1998  	assert.Equal(t, curBlk.Header().Number.String(), decodedData.GetBlockNumber().String())
  1999  }
  2000  
  2001  func TestBridgeAliasAPIs(t *testing.T) {
  2002  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  2003  	assert.NoError(t, err)
  2004  	defer func() {
  2005  		if err := os.RemoveAll(tempDir); err != nil {
  2006  			t.Fatalf("fail to delete file %v", err)
  2007  		}
  2008  	}()
  2009  
  2010  	// Generate a new random account and a funded simulator
  2011  	aliceKey, _ := crypto.GenerateKey()
  2012  	alice := bind.NewKeyedTransactor(aliceKey)
  2013  	bobKey, _ := crypto.GenerateKey()
  2014  	bob := bind.NewKeyedTransactor(bobKey)
  2015  
  2016  	config := &SCConfig{}
  2017  	config.DataDir = tempDir
  2018  
  2019  	bacc, _ := NewBridgeAccounts(nil, tempDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  2020  	bacc.pAccount.chainID = big.NewInt(0)
  2021  	bacc.cAccount.chainID = big.NewInt(0)
  2022  
  2023  	alloc := blockchain.GenesisAlloc{
  2024  		alice.From:            {Balance: big.NewInt(params.KLAY)},
  2025  		bob.From:              {Balance: big.NewInt(params.KLAY)},
  2026  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  2027  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  2028  	}
  2029  	sim := backends.NewSimulatedBackend(alloc)
  2030  	defer sim.Close()
  2031  
  2032  	sc := &SubBridge{
  2033  		config:         config,
  2034  		peers:          newBridgePeerSet(),
  2035  		localBackend:   sim,
  2036  		remoteBackend:  sim,
  2037  		bridgeAccounts: bacc,
  2038  	}
  2039  
  2040  	sc.APIBackend = &SubBridgeAPI{sc}
  2041  	sc.handler, err = NewSubBridgeHandler(sc)
  2042  	assert.NoError(t, err)
  2043  
  2044  	// Prepare manager and deploy bridge contract.
  2045  	bm, err := NewBridgeManager(sc)
  2046  	assert.NoError(t, err)
  2047  	sc.handler.subbridge.bridgeManager = bm
  2048  
  2049  	// 1. Deploy bridge contracts and register them
  2050  	cBridgeAddr := deployBridge(t, bm, sim, true)
  2051  	pBridgeAddr := deployBridge(t, bm, sim, false)
  2052  
  2053  	// 2. Deploy token Contracts
  2054  	cTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, cBridgeAddr)
  2055  	assert.NoError(t, err)
  2056  	pTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, pBridgeAddr)
  2057  	assert.NoError(t, err)
  2058  	sim.Commit() // block
  2059  
  2060  	cBridgeAddrStr := cBridgeAddr.String()
  2061  	pBridgeAddrStr := pBridgeAddr.String()
  2062  	cTokenAddrStr := cTokenAddr.String()
  2063  	pTokenAddrStr := pTokenAddr.String()
  2064  	// -------------------------- Done prepration --------------------------
  2065  
  2066  	// -------------------------- API test with the raw addresss format --------------------------
  2067  	{
  2068  		// TEST 1-1 - Success (Register bridge, tokens and subscribe registered bridges)
  2069  		bridgePairs := bm.subBridge.APIBackend.ListBridge()
  2070  		assert.Equal(t, len(bridgePairs), 0)
  2071  
  2072  		testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, nil, cTokenAddr, pTokenAddr)
  2073  
  2074  		bridgePairs = bm.subBridge.APIBackend.ListBridge()
  2075  		assert.Equal(t, len(bridgePairs), 1)
  2076  		assert.Equal(t, bridgePairs[0].Subscribed, true)
  2077  	}
  2078  
  2079  	{
  2080  		// TEST 1-2 - Failure
  2081  		// Duplicated journal
  2082  		testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, nil)
  2083  
  2084  		// Duplicated token
  2085  		testDuplicatedToken(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr)
  2086  
  2087  		// Already subscribed
  2088  		testAlreadySubscribed(t, bm, &cBridgeAddrStr, &pBridgeAddrStr)
  2089  	}
  2090  
  2091  	{
  2092  		// TEST 1-3 - Success (Unsubscribe bridge, deregister bridges and tokens)
  2093  		testUnsubscribeAndDeRegister(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr)
  2094  	}
  2095  
  2096  	// -------------------------- API test with the bridge format --------------------------
  2097  	alias := "MYBRIDGE"
  2098  	changedAlias := "MYBRIDGE_v2"
  2099  	invalidBridgeAlias := "0xMYBRIDGE"
  2100  	{
  2101  		// TEST 2-1 - Success (Register bridge, tokens and subscribe registered bridges)
  2102  		bridgePairs := bm.subBridge.APIBackend.ListBridge()
  2103  		assert.Equal(t, len(bridgePairs), 0)
  2104  
  2105  		testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, &alias, cTokenAddr, pTokenAddr)
  2106  
  2107  		bridgePairs = bm.subBridge.APIBackend.ListBridge()
  2108  		assert.Equal(t, len(bridgePairs), 1)
  2109  		assert.Equal(t, bridgePairs[0].Subscribed, true)
  2110  		bridgePair := bm.subBridge.APIBackend.GetBridgePairByAlias(alias)
  2111  		assert.Equal(t, bridgePair.BridgeAlias, alias)
  2112  	}
  2113  
  2114  	{
  2115  		// TEST 2-2 - Failure
  2116  		// Duplicated bridge alias
  2117  		testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, &alias)
  2118  
  2119  		// Duplicated token
  2120  		testDuplicatedToken(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil)
  2121  
  2122  		// Already subscribed
  2123  		testAlreadySubscribed(t, bm, &alias, nil)
  2124  	}
  2125  
  2126  	{
  2127  		// TEST 2-3 - Success (change bridge alias)
  2128  		err = bm.subBridge.APIBackend.ChangeBridgeAlias(alias, changedAlias)
  2129  		assert.NoError(t, err)
  2130  
  2131  		// Try to deregister with empty bridge alias
  2132  		err = bm.subBridge.APIBackend.DeregisterBridge(&alias, nil)
  2133  		assert.Equal(t, err, ErrEmptyBridgeAlias)
  2134  
  2135  		bridgePair := bm.subBridge.APIBackend.GetBridgePairByAlias(alias)
  2136  		assert.Nil(t, bridgePair)
  2137  
  2138  		bridgePair = bm.subBridge.APIBackend.GetBridgePairByAlias(changedAlias)
  2139  		assert.Equal(t, bridgePair.BridgeAlias, changedAlias)
  2140  	}
  2141  
  2142  	{
  2143  		// TEST 2-4 - Success (Unsubscribe bridge, deregister bridges and tokens)
  2144  		testUnsubscribeAndDeRegister(t, bm, &changedAlias, &cTokenAddrStr, &pTokenAddrStr, nil)
  2145  
  2146  		// TEST 2-5 - Failure (Unsubscribe register bridge already unsubscribed)
  2147  		err := bm.subBridge.APIBackend.UnsubscribeBridge(&changedAlias, nil)
  2148  		assert.Equal(t, err, ErrEmptyBridgeAlias)
  2149  	}
  2150  
  2151  	{
  2152  		// TEST 2-6 - Failure (Try to create a bridge alias with invalid bridge alias name)
  2153  		err = bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, &invalidBridgeAlias)
  2154  		assert.Equal(t, err, ErrNotAllowedAliasFormat)
  2155  	}
  2156  
  2157  	{
  2158  		// TEST 3 - Concurrent API Call
  2159  		contractPairLen := 10
  2160  		bridgeAddrs := make([]common.Address, contractPairLen)
  2161  		tokenAddrs := make([]common.Address, contractPairLen)
  2162  		t.Logf("Prepare %d contracts\n", contractPairLen)
  2163  		// Preparation: Deploy bridge and token contracts
  2164  		for i := 0; i < contractPairLen/2; i++ {
  2165  			cBridgeAddr, pBridgeAddr = deployBridge(t, bm, sim, true), deployBridge(t, bm, sim, false)
  2166  			cIdx, pIdx := i*2, i*2+1
  2167  			bridgeAddrs[cIdx], bridgeAddrs[pIdx] = cBridgeAddr, pBridgeAddr
  2168  
  2169  			cTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, cBridgeAddr)
  2170  			assert.NoError(t, err)
  2171  			pTokenAddr, _, _, err := sctoken.DeployServiceChainToken(alice, sim, pBridgeAddr)
  2172  			assert.NoError(t, err)
  2173  			tokenAddrs[cIdx], tokenAddrs[pIdx] = cTokenAddr, pTokenAddr
  2174  
  2175  			t.Logf("Deployed bridge contracts %d, %d\n", cIdx, pIdx)
  2176  		}
  2177  
  2178  		// Declare another bridge and token contracts that did not initialize
  2179  		fixedChildBridgeAddr, fixedParentBridgeAddr := deployBridge(t, bm, sim, true), deployBridge(t, bm, sim, false)
  2180  
  2181  		const (
  2182  			BRIDGE_SETUP = iota
  2183  			FAILURE
  2184  			CLEANUP_BRIDGE
  2185  			ALIAS_BRIDGE_SETUP
  2186  			ALIAS_FAILURE
  2187  			ALIAS_CLEANUP_BRIDGE
  2188  			REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE
  2189  		)
  2190  		// DO NOT CHANGE THE TEST ORDER
  2191  		testCases := map[uint8]string{
  2192  			BRIDGE_SETUP:         "BRIDGE_SETUP",
  2193  			FAILURE:              "FAILURE",
  2194  			CLEANUP_BRIDGE:       "CLEANUP_BRIDGE",
  2195  			ALIAS_BRIDGE_SETUP:   "ALIAS_BRIDGE_SETUP",
  2196  			ALIAS_FAILURE:        "ALIAS_FAILURE",
  2197  			ALIAS_CLEANUP_BRIDGE: "ALIAS_CLEANUP_BRIDGE",
  2198  			REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE: "REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE",
  2199  		}
  2200  
  2201  		for testNum := 0; testNum < len(testCases); testNum++ {
  2202  			wg := sync.WaitGroup{}
  2203  			wg.Add(contractPairLen / 2)
  2204  			for i := 0; i < len(bridgeAddrs); i += 2 {
  2205  				cIdx, pIdx := i, i+1
  2206  				go func(cIdx, pIdx int) {
  2207  					cBridgeAddr, pBridgeAddr := bridgeAddrs[cIdx], bridgeAddrs[pIdx]
  2208  					cBridgeAddrStr, pBridgeAddrStr := cBridgeAddr.String(), pBridgeAddr.String()
  2209  					cTokenAddr, pTokenAddr := tokenAddrs[cIdx], tokenAddrs[pIdx]
  2210  					cTokenAddrStr, pTokenAddrStr := cTokenAddr.String(), pTokenAddr.String()
  2211  					alias := "MYBRIDGE_v3" + strconv.Itoa(cIdx)
  2212  
  2213  					switch testNum {
  2214  					case BRIDGE_SETUP:
  2215  						// TEST 3-1. `testBridgeAPIBasic` again with concurrent calls using raw-address-format APIS
  2216  						testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, nil, cTokenAddr, pTokenAddr)
  2217  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2218  					case FAILURE:
  2219  						// TEST 3-2 - Failure
  2220  						testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, nil)
  2221  						testDuplicatedToken(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr)
  2222  						testAlreadySubscribed(t, bm, &cBridgeAddrStr, &pBridgeAddrStr)
  2223  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2224  					case ALIAS_BRIDGE_SETUP:
  2225  						// TEST 3-3. `testBridgeAPIBasic` again with concurrent calls using alias APIS
  2226  						testBridgeAPIBasic(t, bm, cBridgeAddr, pBridgeAddr, &alias, cTokenAddr, pTokenAddr)
  2227  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2228  					case ALIAS_FAILURE:
  2229  						// TEST 3-4 - Failure
  2230  						testDuplicatedJournal(t, bm, cBridgeAddr, pBridgeAddr, &alias)
  2231  						testDuplicatedToken(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil)
  2232  						testAlreadySubscribed(t, bm, &alias, nil)
  2233  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2234  					case CLEANUP_BRIDGE:
  2235  						// TEST 3-5 - Success (Unsubscribe bridge, deregister bridges and tokens)
  2236  						testUnsubscribeAndDeRegister(t, bm, &cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr)
  2237  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2238  					case ALIAS_CLEANUP_BRIDGE:
  2239  						// TEST 3-6 - Success (Unsubscribe bridge, deregister bridges and tokens)
  2240  						testUnsubscribeAndDeRegister(t, bm, &alias, &cTokenAddrStr, &pTokenAddrStr, nil)
  2241  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2242  					case REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE:
  2243  						// TEST 3-7 - Use the fresh bridge that did not register any token contracts
  2244  						cbAddr, pbAddr := fixedChildBridgeAddr.String(), fixedParentBridgeAddr.String()
  2245  						testRegisterToken(t, bm, &cbAddr, &pbAddr, &cTokenAddrStr, &pTokenAddrStr)
  2246  						t.Log("passed:", testCases[uint8(testNum)], cIdx, pIdx)
  2247  					}
  2248  					wg.Done()
  2249  				}(cIdx, pIdx)
  2250  			}
  2251  			wg.Wait()
  2252  			t.Log("Test Done: ", testCases[uint8(testNum)])
  2253  			// Check the status of conccurent calls with a signle thread
  2254  			switch testNum {
  2255  			case BRIDGE_SETUP:
  2256  				checkBridgeSetup(t, bm, true, 1, contractPairLen/2)
  2257  			case CLEANUP_BRIDGE:
  2258  				checkBridgeSetup(t, bm, false, 0, 0)
  2259  			case ALIAS_BRIDGE_SETUP:
  2260  				checkBridgeSetup(t, bm, true, 1, contractPairLen/2)
  2261  			case ALIAS_CLEANUP_BRIDGE:
  2262  				checkBridgeSetup(t, bm, false, 0, 0)
  2263  				// Initiailize another two bridge contracts for the test `REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE`
  2264  				err = bm.subBridge.APIBackend.RegisterBridge(fixedChildBridgeAddr, fixedParentBridgeAddr, nil)
  2265  				assert.NoError(t, err)
  2266  			case REGISTER_MULTIPLE_TOKEN_WITH_SINGLE_BRIDGE:
  2267  				checkRegisterMultipleToken(t, bm, fixedChildBridgeAddr, fixedParentBridgeAddr, contractPairLen/2)
  2268  			}
  2269  		}
  2270  		t.Log("All Done")
  2271  	}
  2272  }
  2273  
  2274  func testBridgeAPIBasic(t *testing.T, bm *BridgeManager,
  2275  	cBridgeAddr, pBridgeAddr common.Address,
  2276  	alias *string,
  2277  	cTokenAddr, pTokenAddr common.Address,
  2278  ) {
  2279  	// TEST 1 - Success (Register bridge, tokens and subscribe registered bridges)
  2280  	cBridgeAddrStr := cBridgeAddr.String()
  2281  	pBridgeAddrStr := pBridgeAddr.String()
  2282  	cTokenAddrStr := cTokenAddr.String()
  2283  	pTokenAddrStr := pTokenAddr.String()
  2284  
  2285  	// Register Bridge
  2286  	err := bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, alias)
  2287  	assert.NoError(t, err)
  2288  
  2289  	// Register tokens
  2290  	if alias != nil {
  2291  		err = bm.subBridge.APIBackend.RegisterToken(alias, &cTokenAddrStr, &pTokenAddrStr, nil)
  2292  	} else {
  2293  		err = bm.subBridge.APIBackend.RegisterToken(&cBridgeAddrStr, &pBridgeAddrStr, &cTokenAddrStr, &pTokenAddrStr)
  2294  	}
  2295  	assert.NoError(t, err)
  2296  
  2297  	// Subscribe bridges
  2298  	if alias != nil {
  2299  		err = bm.subBridge.APIBackend.SubscribeBridge(alias, nil)
  2300  	} else {
  2301  		err = bm.subBridge.APIBackend.SubscribeBridge(&cBridgeAddrStr, &pBridgeAddrStr)
  2302  	}
  2303  	assert.NoError(t, err)
  2304  }
  2305  
  2306  func testDuplicatedJournal(t *testing.T, bm *BridgeManager, cBridgeAddr, pBridgeAddr common.Address, alias *string) {
  2307  	err := bm.subBridge.APIBackend.RegisterBridge(cBridgeAddr, pBridgeAddr, alias)
  2308  	if err != ErrDuplicatedJournal && err != ErrDuplicatedAlias {
  2309  		t.Fatal("Unexpected error", err)
  2310  	}
  2311  }
  2312  
  2313  func testDuplicatedToken(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string) {
  2314  	err := bm.subBridge.APIBackend.RegisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr)
  2315  	assert.Equal(t, err, ErrDuplicatedToken)
  2316  }
  2317  
  2318  func testAlreadySubscribed(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr *string) {
  2319  	err := bm.subBridge.APIBackend.SubscribeBridge(cBridgeAddrStr, pBridgeAddrStr)
  2320  	assert.Equal(t, err, ErrAlreadySubscribed)
  2321  }
  2322  
  2323  func testRegisterToken(t *testing.T, bm *BridgeManager, cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string) {
  2324  	err := bm.subBridge.APIBackend.RegisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr)
  2325  	assert.NoError(t, err)
  2326  }
  2327  
  2328  func testUnsubscribeAndDeRegister(t *testing.T, bm *BridgeManager,
  2329  	cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr *string,
  2330  ) {
  2331  	findBridgePair := func(addrStr string) *BridgeJournal {
  2332  		bridgePairs := bm.subBridge.APIBackend.ListBridge()
  2333  		for _, bridgePair := range bridgePairs {
  2334  			if bridgePair.ChildAddress.String() == addrStr || bridgePair.BridgeAlias == addrStr {
  2335  				return bridgePair
  2336  			}
  2337  		}
  2338  		return nil
  2339  	}
  2340  	bridgePairLen := len(bm.subBridge.APIBackend.ListBridge())
  2341  	defer func() {
  2342  		err := bm.subBridge.APIBackend.DeregisterBridge(cBridgeAddrStr, pBridgeAddrStr)
  2343  		assert.NoError(t, err)
  2344  		assert.Equal(t, len(bm.subBridge.APIBackend.ListBridge()) < bridgePairLen, true)
  2345  	}()
  2346  
  2347  	bridgePair := findBridgePair(*cBridgeAddrStr)
  2348  	assert.NotNil(t, bridgePair)
  2349  	assert.Equal(t, bridgePair.Subscribed, true)
  2350  	err := bm.subBridge.APIBackend.UnsubscribeBridge(cBridgeAddrStr, pBridgeAddrStr)
  2351  	assert.NoError(t, err)
  2352  	assert.Equal(t, bridgePair.Subscribed, false)
  2353  
  2354  	cBi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress)
  2355  	assert.Equal(t, ok, true)
  2356  	assert.Equal(t, len(cBi.counterpartToken), 1)
  2357  	pBi, ok := bm.GetBridgeInfo(bridgePair.ParentAddress)
  2358  	assert.Equal(t, ok, true)
  2359  	assert.Equal(t, len(pBi.counterpartToken), 1)
  2360  
  2361  	err = bm.subBridge.APIBackend.DeregisterToken(cBridgeAddrStr, pBridgeAddrStr, cTokenAddrStr, pTokenAddrStr)
  2362  	assert.NoError(t, err)
  2363  	assert.Equal(t, len(cBi.counterpartToken), 0)
  2364  	assert.Equal(t, len(pBi.counterpartToken), 0)
  2365  }
  2366  
  2367  func TestLegacyBridgeJournalDecode(t *testing.T) {
  2368  	// `encodedJournalHexStr` is an encoded legacy bridge journals. The code below generate the following hex.
  2369  	encodedJournalHexStr := "eb9485564429cce278d4399436f1af2f91e1be6f0bd494c12701e0cb09d6600f774be1dbb585ddc749f9da80eb9485564429cce278d4399436f1af2f91e1be6f0bd594c12701e0cb09d6600f774be1dbb585ddc749f9db01eb9485564429cce278d4399436f1af2f91e1be6f0bd694c12701e0cb09d6600f774be1dbb585ddc749f9dc01"
  2370  	/*
  2371  		legacyJournals := []BridgeJournal{
  2372  			{
  2373  				ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd4"),
  2374  				ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9da"),
  2375  				Subscribed:    false,
  2376  			},
  2377  			{
  2378  				ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd5"),
  2379  				ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9db"),
  2380  				Subscribed:    true,
  2381  			},
  2382  			{
  2383  				ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd6"),
  2384  				ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9dc"),
  2385  				Subscribed:    true,
  2386  			},
  2387  		}
  2388  			encodedBuf := new(bytes.Buffer)
  2389  			for i := 0; i < len(journals); i++ {
  2390  				err := rlp.Encode(encodedBuf, &journals[i])
  2391  				assert.NoError(t, err)
  2392  			}
  2393  			encodedString := hex.EncodeToString(encodedBuf.Bytes())
  2394  			fmt.Println(encodedString)
  2395  	*/
  2396  
  2397  	legacyJournals := []BridgeJournal{
  2398  		{
  2399  			ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd4"),
  2400  			ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9da"),
  2401  			Subscribed:    false,
  2402  		},
  2403  		{
  2404  			ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd5"),
  2405  			ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9db"),
  2406  			Subscribed:    true,
  2407  		},
  2408  		{
  2409  			ChildAddress:  common.HexToAddress("0x85564429cce278d4399436f1af2f91e1be6f0bd6"),
  2410  			ParentAddress: common.HexToAddress("0xc12701e0cb09d6600f774be1dbb585ddc749f9dc"),
  2411  			Subscribed:    true,
  2412  		},
  2413  	}
  2414  
  2415  	tempJournalPath := "legacy-journal-decoding-test"
  2416  	tempFile, err := os.CreateTemp(".", tempJournalPath)
  2417  	assert.NoError(t, err)
  2418  
  2419  	encodedHex, err := hex.DecodeString(encodedJournalHexStr)
  2420  	assert.NoError(t, err)
  2421  
  2422  	_, err = tempFile.Write(encodedHex)
  2423  	assert.NoError(t, err)
  2424  	defer os.Remove(tempFile.Name())
  2425  
  2426  	readJournalIdx := 0
  2427  	load := func(gwjournal BridgeJournal) error {
  2428  		assert.Equal(t, len(gwjournal.BridgeAlias), 0)
  2429  		assert.Equal(t, gwjournal.ChildAddress.String(), legacyJournals[readJournalIdx].ChildAddress.String())
  2430  		assert.Equal(t, gwjournal.ParentAddress.String(), legacyJournals[readJournalIdx].ParentAddress.String())
  2431  		assert.Equal(t, gwjournal.Subscribed, legacyJournals[readJournalIdx].Subscribed)
  2432  		readJournalIdx++
  2433  		return nil
  2434  	}
  2435  	journalAddr := newBridgeAddrJournal(tempFile.Name())
  2436  	err = journalAddr.load(load)
  2437  	assert.NoError(t, err)
  2438  }
  2439  
  2440  func checkBridgeSetup(t *testing.T, bm *BridgeManager, expectedSubscribed bool, expectedNumberOfToken, expectedBridgeLen int) {
  2441  	bridgePairs := bm.subBridge.APIBackend.ListBridge()
  2442  	assert.Equal(t, len(bridgePairs), expectedBridgeLen)
  2443  	for _, bridgePair := range bridgePairs {
  2444  		assert.Equal(t, bridgePair.Subscribed, expectedSubscribed)
  2445  		cbi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress)
  2446  		assert.Equal(t, ok, true)
  2447  		pbi, ok := bm.GetBridgeInfo(bridgePair.ChildAddress)
  2448  		assert.Equal(t, ok, true)
  2449  		assert.Equal(t, len(cbi.counterpartToken), expectedNumberOfToken)
  2450  		assert.Equal(t, len(pbi.counterpartToken), expectedNumberOfToken)
  2451  	}
  2452  }
  2453  
  2454  func checkRegisterMultipleToken(t *testing.T, bm *BridgeManager, cBridgeAddr, pBridgeAddr common.Address, expectedLen int) {
  2455  	cbi, ok := bm.GetBridgeInfo(cBridgeAddr)
  2456  	assert.Equal(t, ok, true)
  2457  	pbi, ok := bm.GetBridgeInfo(pBridgeAddr)
  2458  	assert.Equal(t, ok, true)
  2459  	assert.Equal(t, len(cbi.counterpartToken), expectedLen)
  2460  	assert.Equal(t, len(pbi.counterpartToken), expectedLen)
  2461  }
  2462  
  2463  func randomHex(n int) (string, error) {
  2464  	bytes := make([]byte, n)
  2465  	if _, err := rand.Read(bytes); err != nil {
  2466  		return "", err
  2467  	}
  2468  	return hex.EncodeToString(bytes), nil
  2469  }
  2470  
  2471  func TestBridgeAddressType(t *testing.T) {
  2472  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  2473  	assert.NoError(t, err)
  2474  	defer func() {
  2475  		if err := os.RemoveAll(tempDir); err != nil {
  2476  			t.Fatalf("fail to delete file %v", err)
  2477  		}
  2478  	}()
  2479  
  2480  	// Config Bridge Account Manager
  2481  	config := &SCConfig{}
  2482  	config.DataDir = tempDir
  2483  	bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  2484  	bacc.pAccount.chainID = big.NewInt(0)
  2485  	bacc.cAccount.chainID = big.NewInt(0)
  2486  
  2487  	// Create Simulated backend
  2488  	alloc := blockchain.GenesisAlloc{
  2489  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  2490  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  2491  	}
  2492  	sim := backends.NewSimulatedBackend(alloc)
  2493  	defer sim.Close()
  2494  
  2495  	sc := &SubBridge{
  2496  		chainDB:        database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}),
  2497  		config:         config,
  2498  		peers:          newBridgePeerSet(),
  2499  		bridgeAccounts: bacc,
  2500  		localBackend:   sim,
  2501  		remoteBackend:  sim,
  2502  	}
  2503  	sc.handler, err = NewSubBridgeHandler(sc)
  2504  	assert.NoError(t, err)
  2505  	bm, err := NewBridgeManager(sc)
  2506  	assert.NoError(t, err)
  2507  
  2508  	auth := bacc.cAccount.GenerateTransactOpts()
  2509  
  2510  	// Deploy Bridge Contract
  2511  	bridgeAddr, err := bm.DeployBridgeTest(sim, 10000, false)
  2512  	assert.NoError(t, err)
  2513  	sim.Commit() // block
  2514  
  2515  	anotherBridgeAddr, err := bm.DeployBridgeTest(sim, 10000, false)
  2516  	assert.NoError(t, err)
  2517  	sim.Commit() // block
  2518  
  2519  	// Case 1 - Success (The bridge address type is contract address)
  2520  	{
  2521  		// 1. Deploy Token Contract
  2522  		_, tx, token, err := sctoken.DeployServiceChainToken(auth, sim, bridgeAddr)
  2523  		assert.NoError(t, err)
  2524  		sim.Commit() // block
  2525  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2526  
  2527  		// 2. Deploy NFT Contract
  2528  		_, tx, nft, err := scnft.DeployServiceChainNFT(auth, sim, bridgeAddr)
  2529  		assert.NoError(t, err)
  2530  		sim.Commit() // block
  2531  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2532  
  2533  		tx, err = token.SetBridge(auth, anotherBridgeAddr)
  2534  		assert.NoError(t, err)
  2535  		sim.Commit() // block
  2536  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2537  		tx, err = nft.SetBridge(auth, anotherBridgeAddr)
  2538  		assert.NoError(t, err)
  2539  		sim.Commit() // block
  2540  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2541  	}
  2542  
  2543  	// Case 2 - Failure (The bridge address type is not a contract address)
  2544  	{
  2545  		_, tx, _, err := sctoken.DeployServiceChainToken(auth, sim, auth.From)
  2546  		assert.NoError(t, err)
  2547  		sim.Commit() // block
  2548  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t)
  2549  
  2550  		_, tx, _, err = scnft.DeployServiceChainNFT(auth, sim, auth.From)
  2551  		assert.NoError(t, err)
  2552  		sim.Commit() // block
  2553  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t)
  2554  	}
  2555  
  2556  	// Case 3 - Failure (The bridge address type is not a contract address)
  2557  	{
  2558  		_, tx, token, err := sctoken.DeployServiceChainToken(auth, sim, bridgeAddr)
  2559  		assert.NoError(t, err)
  2560  		sim.Commit() // block
  2561  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2562  
  2563  		_, tx, nft, err := scnft.DeployServiceChainNFT(auth, sim, bridgeAddr)
  2564  		assert.NoError(t, err)
  2565  		sim.Commit() // block
  2566  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusSuccessful, t)
  2567  
  2568  		tx, err = token.SetBridge(auth, auth.From)
  2569  		assert.NoError(t, err)
  2570  		sim.Commit() // block
  2571  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t)
  2572  		tx, err = nft.SetBridge(auth, auth.From)
  2573  		assert.NoError(t, err)
  2574  		sim.Commit() // block
  2575  		CheckReceipt(sim, tx, time.Second, types.ReceiptStatusErrExecutionReverted, t)
  2576  	}
  2577  }
  2578  
  2579  // DeployBridgeTest is a test-only function which deploys a bridge contract with some amount of KLAY.
  2580  func (bm *BridgeManager) DeployBridgeTest(backend *backends.SimulatedBackend, amountOfDeposit int64, local bool) (common.Address, error) {
  2581  	var acc *accountInfo
  2582  
  2583  	// When the pending block of backend is updated, commit it
  2584  	// bm.DeployBridge will be waiting until the block is committed
  2585  	pendingBlock := backend.PendingBlock()
  2586  	go func() {
  2587  		for pendingBlock == backend.PendingBlock() {
  2588  			time.Sleep(100 * time.Millisecond)
  2589  		}
  2590  		backend.Commit()
  2591  		return
  2592  	}()
  2593  
  2594  	// Set transfer value of the bridge account
  2595  	if local {
  2596  		acc = bm.subBridge.bridgeAccounts.cAccount
  2597  	} else {
  2598  		acc = bm.subBridge.bridgeAccounts.pAccount
  2599  	}
  2600  
  2601  	auth := acc.GenerateTransactOpts()
  2602  	auth.Value = big.NewInt(amountOfDeposit)
  2603  
  2604  	// Deploy a bridge contract
  2605  	deployedBridge, addr, err := bm.DeployBridge(auth, backend, local)
  2606  	if err != nil {
  2607  		return common.Address{}, err
  2608  	}
  2609  
  2610  	// Set the bridge contract information to the BridgeManager
  2611  	err = bm.SetBridgeInfo(addr, deployedBridge, common.Address{}, nil, acc, local, false)
  2612  	if err != nil {
  2613  		return common.Address{}, err
  2614  	}
  2615  	return addr, err
  2616  }
  2617  
  2618  // deployBridge deploys bridge contract and returns its address
  2619  func deployBridge(t *testing.T, bm *BridgeManager, backend *backends.SimulatedBackend, local bool) common.Address {
  2620  	var acc *accountInfo
  2621  
  2622  	// When the pending block of backend is updated, commit it
  2623  	// bm.DeployBridge will be waiting until the block is committed
  2624  	pendingBlock := backend.PendingBlock()
  2625  	go func() {
  2626  		for pendingBlock == backend.PendingBlock() {
  2627  			time.Sleep(100 * time.Millisecond)
  2628  		}
  2629  		backend.Commit()
  2630  		return
  2631  	}()
  2632  
  2633  	// Set transfer value of the bridge account
  2634  	if local {
  2635  		acc = bm.subBridge.bridgeAccounts.cAccount
  2636  	} else {
  2637  		acc = bm.subBridge.bridgeAccounts.pAccount
  2638  	}
  2639  
  2640  	auth := acc.GenerateTransactOpts()
  2641  	auth.Value = big.NewInt(10000)
  2642  
  2643  	// Deploy a bridge contract
  2644  	_, addr, err := bm.DeployBridge(auth, backend, local)
  2645  	assert.NoError(t, err)
  2646  	return addr
  2647  }
  2648  
  2649  func isExpectedBalance(t *testing.T, bridgeManager *BridgeManager,
  2650  	pBridgeAddr, cBridgeAddr common.Address,
  2651  	expectedParentBridgeBalance, expectedChildBridgeBalance int64,
  2652  ) {
  2653  	pBridgeBalance, err := bridgeManager.subBridge.APIBackend.GetParentBridgeContractBalance(pBridgeAddr)
  2654  	assert.NoError(t, err)
  2655  	cBridgeBalance, err := bridgeManager.subBridge.APIBackend.GetChildBridgeContractBalance(cBridgeAddr)
  2656  	assert.NoError(t, err)
  2657  	assert.Equal(t, pBridgeBalance.Int64(), expectedParentBridgeBalance)
  2658  	assert.Equal(t, cBridgeBalance.Int64(), expectedChildBridgeBalance)
  2659  }
  2660  
  2661  func TestGetBridgeContractBalance(t *testing.T) {
  2662  	tempDir, err := os.MkdirTemp(os.TempDir(), "sc")
  2663  	assert.NoError(t, err)
  2664  	defer func() {
  2665  		if err := os.RemoveAll(tempDir); err != nil {
  2666  			t.Fatalf("fail to delete file %v", err)
  2667  		}
  2668  	}()
  2669  
  2670  	// Config Bridge Account Manager
  2671  	config := &SCConfig{}
  2672  	config.DataDir = tempDir
  2673  	bacc, _ := NewBridgeAccounts(nil, config.DataDir, database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}), DefaultBridgeTxGasLimit, DefaultBridgeTxGasLimit)
  2674  	bacc.pAccount.chainID = big.NewInt(0)
  2675  	bacc.cAccount.chainID = big.NewInt(0)
  2676  
  2677  	// Create Simulated backend
  2678  	alloc := blockchain.GenesisAlloc{
  2679  		bacc.pAccount.address: {Balance: big.NewInt(params.KLAY)},
  2680  		bacc.cAccount.address: {Balance: big.NewInt(params.KLAY)},
  2681  	}
  2682  	sim := backends.NewSimulatedBackend(alloc)
  2683  	defer sim.Close()
  2684  
  2685  	sc := &SubBridge{
  2686  		chainDB:        database.NewDBManager(&database.DBConfig{DBType: database.MemoryDB}),
  2687  		config:         config,
  2688  		peers:          newBridgePeerSet(),
  2689  		bridgeAccounts: bacc,
  2690  		localBackend:   sim,
  2691  		remoteBackend:  sim,
  2692  	}
  2693  	sc.APIBackend = &SubBridgeAPI{sc}
  2694  	sc.handler, err = NewSubBridgeHandler(sc)
  2695  	if err != nil {
  2696  		log.Fatalf("Failed to initialize bridgeHandler : %v", err)
  2697  		return
  2698  	}
  2699  
  2700  	bm, err := NewBridgeManager(sc)
  2701  	assert.NoError(t, err)
  2702  	sc.handler.subbridge.bridgeManager = bm
  2703  
  2704  	// Case 1 - Success
  2705  	{
  2706  		initialChildbridgeBalance, initialParentbridgeBalance := int64(100), int64(100)
  2707  		cBridgeAddr, err := bm.DeployBridgeTest(sim, initialChildbridgeBalance, true)
  2708  		assert.NoError(t, err)
  2709  		pBridgeAddr, err := bm.DeployBridgeTest(sim, initialParentbridgeBalance, false)
  2710  		assert.NoError(t, err)
  2711  		bm.SetJournal("", cBridgeAddr, pBridgeAddr)
  2712  		assert.NoError(t, err)
  2713  		sim.Commit()
  2714  		isExpectedBalance(t, bm, pBridgeAddr, cBridgeAddr, initialParentbridgeBalance, initialChildbridgeBalance)
  2715  	}
  2716  
  2717  	// Case 2 - ? (Random)
  2718  	{
  2719  		rand.Seed(time.Now().UnixNano())
  2720  		for i := 0; i < 10; i++ {
  2721  			initialChildbridgeBalance, initialParentbridgeBalance := rand.Int63n(10000), rand.Int63n(10000)
  2722  			cBridgeAddr, err := bm.DeployBridgeTest(sim, initialChildbridgeBalance, true)
  2723  			assert.NoError(t, err)
  2724  			pBridgeAddr, err := bm.DeployBridgeTest(sim, initialParentbridgeBalance, false)
  2725  			assert.NoError(t, err)
  2726  			bm.SetJournal("", cBridgeAddr, pBridgeAddr)
  2727  			assert.NoError(t, err)
  2728  			sim.Commit()
  2729  			isExpectedBalance(t, bm, pBridgeAddr, cBridgeAddr, initialParentbridgeBalance, initialChildbridgeBalance)
  2730  		}
  2731  	}
  2732  }