Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2E test native tokens bridge more than 0x0 balance #253

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 60 additions & 11 deletions e2e-polybft/e2e/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) {

// assert that all deposits are executed successfully
// because of the token mapping with the first deposit
checkStateSyncResultLogs(t, logs, transfersCount+1)
assertStateSyncResultSuccess(t, logs, transfersCount+1)

// get child token address
childERC20Token := getChildToken(t, contractsapi.RootERC20Predicate.Abi,
Expand Down Expand Up @@ -282,7 +282,7 @@ func TestE2E_Bridge_RootchainTokensTransfers(t *testing.T) {
require.NoError(t, err)

// assert that all state syncs are executed successfully
checkStateSyncResultLogs(t, logs, transfersCount)
assertStateSyncResultSuccess(t, logs, transfersCount)
})
}

Expand Down Expand Up @@ -384,7 +384,7 @@ func TestE2E_Bridge_ERC721Transfer(t *testing.T) {
// assert that all deposits are executed successfully.
// All deposits are sent using a single transaction, so arbitrary message bridge emits two state sync events:
// MAP_TOKEN_SIG and DEPOSIT_BATCH_SIG state sync events
checkStateSyncResultLogs(t, logs, stateSyncedLogsCount)
assertStateSyncResultSuccess(t, logs, stateSyncedLogsCount)

break
}
Expand Down Expand Up @@ -558,7 +558,7 @@ func TestE2E_Bridge_ERC1155Transfer(t *testing.T) {
// assert that all deposits are executed successfully.
// All deposits are sent using a single transaction, so arbitrary message bridge emits two state sync events:
// MAP_TOKEN_SIG and DEPOSIT_BATCH_SIG state sync events
checkStateSyncResultLogs(t, logs, stateSyncedLogsCount)
assertStateSyncResultSuccess(t, logs, stateSyncedLogsCount)

break
}
Expand Down Expand Up @@ -1146,7 +1146,7 @@ func TestE2E_Bridge_Transfers_AccessLists(t *testing.T) {

// assert that all deposits are executed successfully
// (token mapping and transferCount of deposits)
checkStateSyncResultLogs(t, logs, transfersCount+1)
assertStateSyncResultSuccess(t, logs, transfersCount+1)

// get child token address
childERC20Token := getChildToken(t, contractsapi.RootERC20Predicate.Abi,
Expand Down Expand Up @@ -1256,6 +1256,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {
numBlockConfirmations = uint64(2)
exitEventsCount = uint64(2)
tokensToTransfer = ethgo.Gwei(10)
tenMilionTokens = ethgo.Ether(10000000)
bigZero = big.NewInt(0)
)

Expand Down Expand Up @@ -1290,7 +1291,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {
tcc.Premine = append(tcc.Premine,
fmt.Sprintf("%s:%s:%s",
nonValidatorKey.Address(),
command.DefaultPremineBalance.String(),
new(big.Int).Mul(big.NewInt(10), tenMilionTokens).String(),
nonValidatorKeyString))

// do premine to reward wallet address
Expand All @@ -1301,14 +1302,13 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {
rewardWalletKeyString))
}),
)
defer cluster.Stop()

rootchainTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(cluster.Bridge.JSONRPCAddr()))
require.NoError(t, err)

childEthEndpoint := cluster.Servers[0].JSONRPC()

defer cluster.Stop()

cluster.WaitForReady(t)

polybftCfg, err := polybft.LoadPolyBFTConfig(path.Join(cluster.Config.TmpDir, chainConfigFileName))
Expand Down Expand Up @@ -1354,7 +1354,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {
})

// this test case will check first if they can withdraw some of the premined amount of non-mintable token
t.Run("Do a withdraw for premined validator address and premined non-validator address", func(t *testing.T) {
t.Run("do a withdraw for premined validator address and premined non-validator address", func(t *testing.T) {
validatorSrv := cluster.Servers[1]
validatorAcc, err := validatorHelper.GetAccountFromDir(validatorSrv.DataDir())
require.NoError(t, err)
Expand Down Expand Up @@ -1422,7 +1422,7 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {
checkBalancesFn(types.Address(nonValidatorKey.Address()), tokensToTransfer, nonValidatorBalanceAfterWithdraw, false)
})

t.Run("Do a deposit to some validator and non-validator address", func(t *testing.T) {
t.Run("do a deposit to some validator and non-validator address", func(t *testing.T) {
validatorSrv := cluster.Servers[4]
validatorAcc, err := validatorHelper.GetAccountFromDir(validatorSrv.DataDir())
require.NoError(t, err)
Expand Down Expand Up @@ -1456,7 +1456,56 @@ func TestE2E_Bridge_NonMintableERC20Token_WithPremine(t *testing.T) {

if len(logs) == stateSyncedLogsCount || i == numberOfAttempts-1 {
// assert that all deposits are executed successfully
checkStateSyncResultLogs(t, logs, stateSyncedLogsCount)
assertStateSyncResultSuccess(t, logs, stateSyncedLogsCount)

break
}

require.NoError(t, cluster.WaitForBlock(finalBlockNum+(i+1)*epochSize, time.Minute))
}
})

t.Run("transfer more native tokens than 0x0 balance is", func(t *testing.T) {
const expectedStateSyncsCount = 1

// since bridging native token is essentially minting
// (i.e. transferring tokens from 0x0 to receiver address using native transfer precompile),
// this test tries to deposit more tokens than 0x0 address has on its balance
currentBlock, err := childEthEndpoint.GetBlockByNumber(jsonrpc.LatestBlockNumber, false)
require.NoError(t, err)

require.NoError(t, cluster.Bridge.Deposit(
common.ERC20,
polybftCfg.Bridge.RootNativeERC20Addr,
polybftCfg.Bridge.RootERC20PredicateAddr,
bridgeHelper.TestAccountPrivKey,
strings.Join([]string{nonValidatorKey.Address().String()}, ","),
strings.Join([]string{tenMilionTokens.String()}, ","),
"",
cluster.Bridge.JSONRPCAddr(),
bridgeHelper.TestAccountPrivKey,
false),
)

// wait for couple of epoches
finalBlockNum := currentBlock.Header.Number + epochSize
require.NoError(t, cluster.WaitForBlock(finalBlockNum, 2*time.Minute))

// the transaction is processed and there should be a success event
var stateSyncedResult contractsapi.StateSyncResultEvent

for i := uint64(0); i < numberOfAttempts; i++ {
logs, err := getFilteredLogs(stateSyncedResult.Sig(), currentBlock.Number()+1, finalBlockNum+i*epochSize, childEthEndpoint)
require.NoError(t, err)

if len(logs) == expectedStateSyncsCount || i == numberOfAttempts-1 {
// assert that sent deposit has failed
checkStateSyncResultLogs(t, logs, expectedStateSyncsCount,
func(t *testing.T, ssre contractsapi.StateSyncResultEvent) {
t.Helper()

require.False(t, ssre.Status)
})

break
}
Expand Down
27 changes: 25 additions & 2 deletions e2e-polybft/e2e/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (

const nativeTokenNonMintableConfig = "Blade:BLD:18:false"

var (
stateSyncResultEvent contractsapi.StateSyncResultEvent
)

func ABICall(relayer txrelayer.TxRelayer, artifact *contracts.Artifact, contractAddress types.Address, senderAddr types.Address, method string, params ...interface{}) (string, error) {
input, err := artifact.Abi.GetMethod(method).Encode(params)
if err != nil {
Expand Down Expand Up @@ -59,22 +63,41 @@ func checkStateSyncResultLogs(
t *testing.T,
logs []*ethgo.Log,
expectedCount int,
handler func(*testing.T, contractsapi.StateSyncResultEvent),
) {
t.Helper()
require.Equal(t, expectedCount, len(logs))

var stateSyncResultEvent contractsapi.StateSyncResultEvent
for _, log := range logs {
doesMatch, err := stateSyncResultEvent.ParseLog(log)
require.NoError(t, err)
require.True(t, doesMatch)

t.Logf("Block Number=%d, Decoded Log=%+v\n", log.BlockNumber, stateSyncResultEvent)

require.True(t, stateSyncResultEvent.Status)
if handler != nil {
handler(t, stateSyncResultEvent)
}
}
}

// assertStateSyncResultSuccess asserts that:
// 1. there are required amount of logs,
// 2. they are of contractsapi.StateSyncResult type
// 3. status is true, meaning that the state syncs were executed successfully
func assertStateSyncResultSuccess(
t *testing.T,
logs []*ethgo.Log,
expectedCount int) {
t.Helper()
checkStateSyncResultLogs(t, logs, expectedCount,
func(t *testing.T, ssre contractsapi.StateSyncResultEvent) {
t.Helper()

require.True(t, ssre.Status)
})
}

// getCheckpointBlockNumber gets current checkpoint block number from checkpoint manager smart contract
func getCheckpointBlockNumber(l1Relayer txrelayer.TxRelayer, checkpointManagerAddr types.Address) (uint64, error) {
checkpointBlockNumRaw, err := ABICall(l1Relayer, contractsapi.CheckpointManager,
Expand Down
Loading