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