mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-23 04:48:17 -05:00
205 lines
7.0 KiB
Go
205 lines
7.0 KiB
Go
package l2
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ecdsa"
|
|
"math/big"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
|
|
"github.com/scroll-tech/go-ethereum/common"
|
|
"github.com/scroll-tech/go-ethereum/core/types"
|
|
"github.com/scroll-tech/go-ethereum/ethclient"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"scroll-tech/bridge/config"
|
|
"scroll-tech/bridge/mock_bridge"
|
|
"scroll-tech/bridge/sender"
|
|
|
|
"scroll-tech/database"
|
|
"scroll-tech/database/migrate"
|
|
"scroll-tech/database/orm"
|
|
)
|
|
|
|
func testCreateNewWatcherAndStop(t *testing.T) {
|
|
// Create db handler and reset db.
|
|
l2db, err := database.NewOrmFactory(cfg.DBConfig)
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, migrate.ResetDB(l2db.GetDB().DB))
|
|
defer l2db.Close()
|
|
|
|
l2cfg := cfg.L2Config
|
|
rc := NewL2WatcherClient(context.Background(), l2Cli, l2cfg.Confirmations, l2cfg.BatchProposerConfig, l2cfg.L2MessengerAddress, l2db)
|
|
rc.Start()
|
|
defer rc.Stop()
|
|
|
|
l1cfg := cfg.L1Config
|
|
l1cfg.RelayerConfig.SenderConfig.Confirmations = 0
|
|
newSender, err := sender.NewSender(context.Background(), l1cfg.RelayerConfig.SenderConfig, l1cfg.RelayerConfig.MessageSenderPrivateKeys)
|
|
assert.NoError(t, err)
|
|
|
|
// Create several transactions and commit to block
|
|
numTransactions := 3
|
|
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
|
for i := 0; i < numTransactions; i++ {
|
|
_, err = newSender.SendTransaction(strconv.Itoa(1000+i), &toAddress, big.NewInt(1000000000), nil, 0)
|
|
assert.NoError(t, err)
|
|
<-newSender.ConfirmChan()
|
|
}
|
|
|
|
blockNum, err := l2Cli.BlockNumber(context.Background())
|
|
assert.NoError(t, err)
|
|
assert.GreaterOrEqual(t, blockNum, uint64(numTransactions))
|
|
}
|
|
|
|
func testMonitorBridgeContract(t *testing.T) {
|
|
// Create db handler and reset db.
|
|
db, err := database.NewOrmFactory(cfg.DBConfig)
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
|
|
defer db.Close()
|
|
|
|
previousHeight, err := l2Cli.BlockNumber(context.Background())
|
|
assert.NoError(t, err)
|
|
|
|
auth := prepareAuth(t, l2Cli, cfg.L2Config.RelayerConfig.MessageSenderPrivateKeys[0])
|
|
|
|
// deploy mock bridge
|
|
_, tx, instance, err := mock_bridge.DeployMockBridgeL2(auth, l2Cli)
|
|
assert.NoError(t, err)
|
|
address, err := bind.WaitDeployed(context.Background(), l2Cli, tx)
|
|
assert.NoError(t, err)
|
|
|
|
rc := prepareRelayerClient(l2Cli, cfg.L2Config.BatchProposerConfig, db, address)
|
|
rc.Start()
|
|
defer rc.Stop()
|
|
|
|
// Call mock_bridge instance sendMessage to trigger emit events
|
|
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
|
message := []byte("testbridgecontract")
|
|
fee := big.NewInt(0)
|
|
gasLimit := big.NewInt(1)
|
|
|
|
tx, err = instance.SendMessage(auth, toAddress, fee, message, gasLimit)
|
|
assert.NoError(t, err)
|
|
receipt, err := bind.WaitMined(context.Background(), l2Cli, tx)
|
|
if receipt.Status != types.ReceiptStatusSuccessful || err != nil {
|
|
t.Fatalf("Call failed")
|
|
}
|
|
|
|
// extra block mined
|
|
toAddress = common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
|
message = []byte("testbridgecontract")
|
|
tx, err = instance.SendMessage(auth, toAddress, fee, message, gasLimit)
|
|
assert.NoError(t, err)
|
|
receipt, err = bind.WaitMined(context.Background(), l2Cli, tx)
|
|
if receipt.Status != types.ReceiptStatusSuccessful || err != nil {
|
|
t.Fatalf("Call failed")
|
|
}
|
|
|
|
// wait for dealing time
|
|
<-time.After(6 * time.Second)
|
|
|
|
var latestHeight uint64
|
|
latestHeight, err = l2Cli.BlockNumber(context.Background())
|
|
assert.NoError(t, err)
|
|
t.Log("Latest height is", latestHeight)
|
|
|
|
// check if we successfully stored events
|
|
height, err := db.GetLayer2LatestWatchedHeight()
|
|
assert.NoError(t, err)
|
|
t.Log("Height in DB is", height)
|
|
assert.Greater(t, height, int64(previousHeight))
|
|
msgs, err := db.GetL2Messages(map[string]interface{}{"status": orm.MsgPending})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, len(msgs))
|
|
}
|
|
|
|
func testFetchMultipleSentMessageInOneBlock(t *testing.T) {
|
|
// Create db handler and reset db.
|
|
db, err := database.NewOrmFactory(cfg.DBConfig)
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, migrate.ResetDB(db.GetDB().DB))
|
|
defer db.Close()
|
|
|
|
previousHeight, err := l2Cli.BlockNumber(context.Background()) // shallow the global previousHeight
|
|
assert.NoError(t, err)
|
|
|
|
auth := prepareAuth(t, l2Cli, cfg.L2Config.RelayerConfig.MessageSenderPrivateKeys[0])
|
|
|
|
_, trx, instance, err := mock_bridge.DeployMockBridgeL2(auth, l2Cli)
|
|
assert.NoError(t, err)
|
|
address, err := bind.WaitDeployed(context.Background(), l2Cli, trx)
|
|
assert.NoError(t, err)
|
|
|
|
rc := prepareRelayerClient(l2Cli, cfg.L2Config.BatchProposerConfig, db, address)
|
|
rc.Start()
|
|
defer rc.Stop()
|
|
|
|
// Call mock_bridge instance sendMessage to trigger emit events multiple times
|
|
numTransactions := 4
|
|
var tx *types.Transaction
|
|
|
|
for i := 0; i < numTransactions; i++ {
|
|
addr := common.HexToAddress("0x1c5a77d9fa7ef466951b2f01f724bca3a5820b63")
|
|
nonce, nounceErr := l2Cli.PendingNonceAt(context.Background(), addr)
|
|
assert.NoError(t, nounceErr)
|
|
auth.Nonce = big.NewInt(int64(nonce))
|
|
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
|
message := []byte("testbridgecontract")
|
|
fee := big.NewInt(0)
|
|
gasLimit := big.NewInt(1)
|
|
tx, err = instance.SendMessage(auth, toAddress, fee, message, gasLimit)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
receipt, err := bind.WaitMined(context.Background(), l2Cli, tx)
|
|
if receipt.Status != types.ReceiptStatusSuccessful || err != nil {
|
|
t.Fatalf("Call failed")
|
|
}
|
|
|
|
// extra block mined
|
|
addr := common.HexToAddress("0x1c5a77d9fa7ef466951b2f01f724bca3a5820b63")
|
|
nonce, nounceErr := l2Cli.PendingNonceAt(context.Background(), addr)
|
|
assert.NoError(t, nounceErr)
|
|
auth.Nonce = big.NewInt(int64(nonce))
|
|
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
|
|
message := []byte("testbridgecontract")
|
|
fee := big.NewInt(0)
|
|
gasLimit := big.NewInt(1)
|
|
tx, err = instance.SendMessage(auth, toAddress, fee, message, gasLimit)
|
|
assert.NoError(t, err)
|
|
receipt, err = bind.WaitMined(context.Background(), l2Cli, tx)
|
|
if receipt.Status != types.ReceiptStatusSuccessful || err != nil {
|
|
t.Fatalf("Call failed")
|
|
}
|
|
|
|
// wait for dealing time
|
|
<-time.After(6 * time.Second)
|
|
|
|
// check if we successfully stored events
|
|
height, err := db.GetLayer2LatestWatchedHeight()
|
|
assert.NoError(t, err)
|
|
t.Log("LatestHeight is", height)
|
|
assert.Greater(t, height, int64(previousHeight)) // height must be greater than previousHeight because confirmations is 0
|
|
msgs, err := db.GetL2Messages(map[string]interface{}{"status": orm.MsgPending})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 5, len(msgs))
|
|
}
|
|
|
|
func prepareRelayerClient(l2Cli *ethclient.Client, bpCfg *config.BatchProposerConfig, db database.OrmFactory, contractAddr common.Address) *WatcherClient {
|
|
return NewL2WatcherClient(context.Background(), l2Cli, 0, bpCfg, contractAddr, db)
|
|
}
|
|
|
|
func prepareAuth(t *testing.T, l2Cli *ethclient.Client, privateKey *ecdsa.PrivateKey) *bind.TransactOpts {
|
|
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(53077))
|
|
assert.NoError(t, err)
|
|
auth.Value = big.NewInt(0) // in wei
|
|
assert.NoError(t, err)
|
|
auth.GasPrice, err = l2Cli.SuggestGasPrice(context.Background())
|
|
assert.NoError(t, err)
|
|
return auth
|
|
}
|