diff --git a/.github/workflows/regression-tests.yml b/.github/workflows/regression-tests.yml index 43f25fc5..831776b2 100644 --- a/.github/workflows/regression-tests.yml +++ b/.github/workflows/regression-tests.yml @@ -5,14 +5,14 @@ on: types: [opened, synchronize] # Trigger on new PR and existing with new commits branches: - develop + jobs: - deploy_devnet: + regression_tests: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 + - name: Checkout Repository + uses: actions/checkout@v2 - name: Build image (with proposed code changes) locally id: build @@ -22,13 +22,14 @@ jobs: echo $GITHUB_SHA_SHORT echo "::set-output name=GITHUB_SHA_SHORT::$GITHUB_SHA_SHORT" fi - - - name: Set up Docker - uses: docker/setup-buildx-action@v1 - - - name: Run regression tests against JIT container image + - name: Run Regression Tests uses: 0xPolygon/kurtosis-cdk@v0.1.9 with: zkevm_bridge_service: ${{ steps.build.outputs.GITHUB_SHA_SHORT }} - kurtosis_cli: 0.89.3 - kurtosis_cdk: v0.2.0 + zkevm_agglayer: '0.1.4' + zkevm_bridge_ui: '0006445' + zkevm_dac: '0.0.7' + zkevm_node: '0.6.5-cdk' + kurtosis_cdk: 'v0.2.3' + kurtosis_cli: '0.89.3' + bake_time: 30 \ No newline at end of file diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index d99808f5..fe715d34 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -1,4 +1,4 @@ -name: Test +name: Test-e2e on: push: branches: diff --git a/.github/workflows/test-e2ecompress.yml b/.github/workflows/test-e2ecompress.yml index 624f9953..6061295d 100644 --- a/.github/workflows/test-e2ecompress.yml +++ b/.github/workflows/test-e2ecompress.yml @@ -1,4 +1,4 @@ -name: Test +name: Test-e2compress on: push: branches: diff --git a/.github/workflows/test-edge.yml b/.github/workflows/test-edge.yml index 7f933d12..957b134d 100644 --- a/.github/workflows/test-edge.yml +++ b/.github/workflows/test-edge.yml @@ -1,4 +1,4 @@ -name: Test +name: Test-edge on: push: branches: diff --git a/DockerfileE2ETest b/DockerfileE2ETest index 8e53b701..3562c463 100644 --- a/DockerfileE2ETest +++ b/DockerfileE2ETest @@ -8,6 +8,11 @@ COPY . /src RUN cd /src && make build-test-e2e-real_network # CONTAINER FOR RUNNING BINARY -FROM alpine:3.16.0 -COPY --from=build /src/dist/zkevm-bridge-e2e-real_network /app/zkevm-bridge-e2e-real_network -CMD ["/bin/sh", "-c", "/app/zkevm-bridge-e2e-real_network -test.failfast -test.v"] +FROM alpine:3.16.0 AS ERC20 +COPY --from=build /src/dist/zkevm-bridge-e2e-real_network-erc20 /app/zkevm-bridge-e2e-real_network-erc20 +CMD ["/bin/sh", "-c", "/app/zkevm-bridge-e2e-real_network-erc20 -test.failfast -test.v"] + +# CONTAINER FOR RUNNING BINARY +FROM alpine:3.16.0 AS MSG +COPY --from=build /src/dist/zkevm-bridge-e2e-real_network-bridgemsg /app/zkevm-bridge-e2e-real_network-bridgemsg +CMD ["/bin/sh", "-c", "/app/zkevm-bridge-e2e-real_network-bridgemsg -test.failfast -test.v"] diff --git a/Makefile b/Makefile index ca197b85..e2f09b33 100644 --- a/Makefile +++ b/Makefile @@ -88,8 +88,16 @@ build-docker: ## Builds a docker image with the zkevm bridge binary docker build -t zkevm-bridge-service -f ./Dockerfile . .PHONY: build-docker-e2e-real_network -build-docker-e2e-real_network: ## Builds a docker image with the zkevm bridge binary for e2e tests with real network - docker build -f DockerfileE2ETest . -t bridge-e2e-realnetwork-erc20 +build-docker-e2e-real_network: build-docker-e2e-real_network-erc20 build-docker-e2e-real_network-msg ## Builds a docker image with the zkevm bridge binary for e2e tests with real network + + +.PHONY: build-docker-e2e-real_network-erc20 +build-docker-e2e-real_network-erc20: ## Builds a docker image with the zkevm bridge binary for e2e ERC20 tests with real network + docker build -f DockerfileE2ETest . -t bridge-e2e-realnetwork-erc20 --target ERC20 + +.PHONY: build-docker-e2e-real_network-msg +build-docker-e2e-real_network-msg: ## Builds a docker image with the zkevm bridge binary for e2e BridgeMessage tests with real network + docker build -f DockerfileE2ETest . -t bridge-e2e-realnetwork-msg --target MSG .PHONY: run-db-node run-db-node: ## Runs the node database @@ -270,8 +278,10 @@ test-e2ecompress: build-docker stop run ## Runs all tests checking race conditio .PHONY: build-test-e2e-real_network build-test-e2e-real_network: ## Build binary for e2e tests with real network - go test -c ./test/e2e/ -o dist/zkevm-bridge-e2e-real_network -tags='e2e_real_network_erc20' - ./dist/zkevm-bridge-e2e-real_network -test.failfast -test.list Test + go test -c ./test/e2e/ -o dist/zkevm-bridge-e2e-real_network-erc20 -tags='e2e_real_network_erc20' + go test -c ./test/e2e/ -o dist/zkevm-bridge-e2e-real_network-bridgemsg -tags='e2e_real_network_msg' + ./dist/zkevm-bridge-e2e-real_network-erc20 -test.failfast -test.list Test + ./dist/zkevm-bridge-e2e-real_network-bridgemsg -test.failfast -test.list Test .PHONY: validate validate: lint build test-full ## Validates the whole integrity of the code base @@ -299,9 +309,7 @@ generate-mocks: ## Generates mocks for the tests, using mockery tool export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir claimtxman/ --output claimtxman/mocks --outpkg mock_txcompressor ${COMMON_MOCKERY_PARAMS} -.PHONY: generate-smart-contracts-bindings +.PHONY: generate-smartcontracts-bindings generate-smartcontracts-bindings: ## Generates the smart contracts bindings - @for contract in `ls -1 etherman/smartcontracts/json/*.json | xargs -l basename`; do \ - ./scripts/generate-smartcontracts-bindings.sh $${contract%.*}; \ - done + cd scripts && ./generate-smartcontracts-bindings.sh \ No newline at end of file diff --git a/claimtxman/claimtxman.go b/claimtxman/claimtxman.go index 1d79175b..3ea977e2 100644 --- a/claimtxman/claimtxman.go +++ b/claimtxman/claimtxman.go @@ -182,6 +182,10 @@ func (tm *ClaimTxManager) processDepositStatus(ger *etherman.GlobalExitRoot, dbT log.Errorf("error getting and updating L1DepositsStatus. Error: %v", err) return err } + if !tm.cfg.Enabled { + log.Infof("ClaimTxManager is disabled. No auto-claim") + return nil + } for _, deposit := range deposits { if tm.l2NetworkID != deposit.DestinationNetwork { log.Infof("Ignoring deposit: %d: dest_net: %d, we are:%d", deposit.DepositCount, deposit.DestinationNetwork, tm.l2NetworkID) @@ -223,6 +227,7 @@ func (tm *ClaimTxManager) processDepositStatus(ger *etherman.GlobalExitRoot, dbT log.Errorf("error BuildSendClaim tx for deposit %d. Error: %v", deposit.DepositCount, err) return err } + if err = tm.addClaimTx(deposit.DepositCount, tm.auth.From, tx.To(), nil, tx.Data(), ger.GlobalExitRoot, dbTx); err != nil { log.Errorf("error adding claim tx for deposit %d. Error: %v", deposit.DepositCount, err) return err diff --git a/cmd/run.go b/cmd/run.go index 508d3199..23649dae 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -41,6 +41,8 @@ func start(ctx *cli.Context) error { if err != nil { return err } + log.Infof("kzevmAddr = %s", c.NetworkConfig.PolygonZkEvmAddress.String()) + log.Infof("RollupManagerAddress = %s", c.NetworkConfig.PolygonRollupManagerAddress.String()) setupLog(c.Log) err = db.RunMigrations(c.SyncDB) if err != nil { @@ -55,11 +57,11 @@ func start(ctx *cli.Context) error { } networkID, err := l1Etherman.GetNetworkID(ctx.Context) - log.Infof("main network id: %d", networkID) if err != nil { log.Error(err) return err } + log.Infof("main network id: %d", networkID) var networkIDs = []uint{networkID} for _, client := range l2Ethermans { @@ -114,46 +116,29 @@ func start(ctx *cli.Context) error { go runSynchronizer(ctx.Context, 0, bridgeController, client, c.Synchronizer, storage, zkEVMClient, chExitRootEvent, chSynced) } - if c.ClaimTxManager.Enabled { - for i := 0; i < len(c.Etherman.L2URLs); i++ { - // we should match the orders of L2URLs between etherman and claimtxman - // since we are using the networkIDs in the same order - ctx := context.Background() - client, err := utils.NewClient(ctx, c.Etherman.L2URLs[i], c.NetworkConfig.L2PolygonBridgeAddresses[i]) - if err != nil { - log.Fatalf("error creating client for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) - } - nonceCache, err := claimtxman.NewNonceCache(ctx, client) - if err != nil { - log.Fatalf("error creating nonceCache for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) - } - auth, err := client.GetSignerFromKeystore(ctx, c.ClaimTxManager.PrivateKey) - if err != nil { - log.Fatalf("error creating signer for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) - } - - claimTxManager, err := claimtxman.NewClaimTxManager(ctx, c.ClaimTxManager, chExitRootEvent, chSynced, - c.Etherman.L2URLs[i], networkIDs[i+1], c.NetworkConfig.L2PolygonBridgeAddresses[i], bridgeService, storage, rollupID, l2Ethermans[i], nonceCache, auth) - if err != nil { - log.Fatalf("error creating claim tx manager for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) - } - go claimTxManager.Start() + for i := 0; i < len(c.Etherman.L2URLs); i++ { + // we should match the orders of L2URLs between etherman and claimtxman + // since we are using the networkIDs in the same order + ctx := context.Background() + client, err := utils.NewClient(ctx, c.Etherman.L2URLs[i], c.NetworkConfig.L2PolygonBridgeAddresses[i]) + if err != nil { + log.Fatalf("error creating client for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) } - } else { - log.Warn("ClaimTxManager not configured") - go func() { - for { - select { - case <-chExitRootEvent: - log.Debug("New GER received") - case netID := <-chSynced: - log.Debug("NetworkID synced: ", netID) - case <-ctx.Context.Done(): - log.Debug("Stopping goroutine that listen new GER updates") - return - } - } - }() + nonceCache, err := claimtxman.NewNonceCache(ctx, client) + if err != nil { + log.Fatalf("error creating nonceCache for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) + } + auth, err := client.GetSignerFromKeystore(ctx, c.ClaimTxManager.PrivateKey) + if err != nil { + log.Fatalf("error creating signer for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) + } + + claimTxManager, err := claimtxman.NewClaimTxManager(ctx, c.ClaimTxManager, chExitRootEvent, chSynced, + c.Etherman.L2URLs[i], networkIDs[i+1], c.NetworkConfig.L2PolygonBridgeAddresses[i], bridgeService, storage, rollupID, l2Ethermans[i], nonceCache, auth) + if err != nil { + log.Fatalf("error creating claim tx manager for L2 %s. Error: %v", c.Etherman.L2URLs[i], err) + } + go claimTxManager.Start() } // Wait for an in interrupt. diff --git a/docs/e2e-realnetwork-test.md b/docs/e2e-realnetwork-test.md new file mode 100644 index 00000000..d4c8f2af --- /dev/null +++ b/docs/e2e-realnetwork-test.md @@ -0,0 +1,25 @@ +# Test Real network using e2e Test +This suite is for test the bridge service running in a real network. +The included tests are: +- ERC20 L1->L2 expecting auto-claim +- ERC20 L2->L1 +- BridgeMessage L1->L2 +- BridgeMessage L2->L1 + +# Build docker +First you need to build the docker that include the tests. +`make build-docker-e2e-real_network-ERC20` +or +`make build-docker-e2e-real_network-MSG` + + +## Create a config file +Check the config example `test/config/bridge_network_e2e/cardona.toml` + +## Execute docker using the config file +- Create the config file in `/tmp/test.toml` +- Launch tests: + ``` + $ docker run --volume "./tmp/:/config/" --env BRIDGE_TEST_CONFIG_FILE=/config/test.toml bridge-e2e-realnetwork-erc20 + $docker run --volume "./tmp/:/config/" --env BRIDGE_TEST_CONFIG_FILE=/config/test.toml bridge-e2e-realnetwork-erc20 + ``` \ No newline at end of file diff --git a/etherman/etherman.go b/etherman/etherman.go index ec761438..9556ad1b 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -158,6 +158,9 @@ func NewClient(cfg Config, polygonBridgeAddr, polygonZkEVMGlobalExitRootAddress, return nil, err } log.Debug("rollupID: ", rollupID) + if rollupID == 0 { + return nil, fmt.Errorf("rollupID is 0, this is not allowed. Check the rollup contract (%s)", polygonZkEvmAddress.String()) + } var scAddresses []common.Address scAddresses = append(scAddresses, polygonZkEVMGlobalExitRootAddress, polygonBridgeAddr, polygonRollupManagerAddress) diff --git a/etherman/smartcontracts/readme.md b/etherman/smartcontracts/readme.md index 669053c5..ada2917d 100644 --- a/etherman/smartcontracts/readme.md +++ b/etherman/smartcontracts/readme.md @@ -4,7 +4,7 @@ The folder `generated_binding` have autogenerated files to use the contracts You can generate from root folder project invoking: ``` -make generate-smartcontracts-bindings +make generate-smartcontracts-bindings ``` ## Folder json diff --git a/scripts/generate-smartcontracts-bindings.sh b/scripts/generate-smartcontracts-bindings.sh index 8164f307..e18a7e3b 100755 --- a/scripts/generate-smartcontracts-bindings.sh +++ b/scripts/generate-smartcontracts-bindings.sh @@ -19,4 +19,11 @@ gen() { abigen --bin ${OUTPUT_BASE_DIR}/bin/${package}.bin --abi ${OUTPUT_BASE_DIR}/abi/${package}.abi --pkg=${package} --out=${OUTPUT_BASE_DIR}/${package}/${package}.go } +gen_from_json(){ + local package=$1 + mkdir -p ${OUTPUT_BASE_DIR}/${package} + abigen --combined-json ${OUTPUT_BASE_DIR}/json/${package}.json --pkg=${package} --out=${OUTPUT_BASE_DIR}/${package}/${package}.go +} + +#gen_from_json pingreceiver gen claimcompressor \ No newline at end of file diff --git a/test/e2e/bridge_network_bridge_msg_test.go b/test/e2e/bridge_network_bridge_msg_test.go new file mode 100644 index 00000000..48aa89b2 --- /dev/null +++ b/test/e2e/bridge_network_bridge_msg_test.go @@ -0,0 +1,176 @@ +//go:build e2e_real_network_msg +// +build e2e_real_network_msg + +package e2e + +import ( + "context" + "fmt" + "math/big" + "testing" + "time" + + "github.com/0xPolygonHermez/zkevm-bridge-service/log" + "github.com/0xPolygonHermez/zkevm-bridge-service/test/mocksmartcontracts/BridgeMessageReceiver" + "github.com/0xPolygonHermez/zkevm-bridge-service/test/mocksmartcontracts/PingReceiver" + "github.com/0xPolygonHermez/zkevm-bridge-service/test/operations" + "github.com/0xPolygonHermez/zkevm-bridge-service/utils" + ops "github.com/0xPolygonHermez/zkevm-node/test/operations" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func newMetadata(starting byte) []byte { + var res []byte + for i := 0; i < 32; i++ { + res = append(res, starting+byte(i)) + } + return res +} +func TestMessageTransferL1toL2(t *testing.T) { + if testing.Short() { + t.Skip() + } + log.Infof("Starting test bridge_message L1 -> L2") + ctx := context.TODO() + testData, err := NewBridge2e2TestData(ctx, nil) + require.NoError(t, err) + balances, err := getcurrentBalance(ctx, testData) + require.NoError(t, err) + log.Infof("MSG [L1->L2] balances: %s", balances.String()) + log.Infof("MSG [L1->L2] deploying contract to L2 to recieve message") + contractDeployedAdrr, pingContract, blockDeployed, err := deployBridgeMessagePingReceiver(ctx, testData.auth[operations.L2], testData.L2Client, testData.cfg.ConnectionConfig.L2BridgeAddr) + //contractDeployedAdrr, pingContract, blockDeployed, err := deployBridgeMessagePingReceiver2(ctx, testData.cfg.TestL2AddrPrivate, testData.L2Client, testData.cfg.ConnectionConfig.L2BridgeAddr) + + require.NoError(t, err) + log.Infof("MSG [L1->L2] Setting to PingReceiver Contract the sender of the message, if not is refused") + log.Infof("MSG [L1->L2] deployed contract to recieve message: %s", contractDeployedAdrr.String()) + tx, err := pingContract.SetSender(testData.auth[operations.L2], testData.auth[operations.L1].From) + require.NoError(t, err) + log.Infof("MSG [L1->L2] SetSender(%s) tx: %s", testData.cfg.ConnectionConfig.L2BridgeAddr, tx.Hash().String()) + log.Infof("MSG [L1->L2] send BridgeMessage to L1 bridge metadata:") + amount := new(big.Int).SetUint64(1000000000000004444) + + txAssetHash := assetMsgL1ToL2(ctx, testData, t, contractDeployedAdrr, amount, newMetadata(1)) + log.Infof("MSG [L1->L2] txAssetHash: %s", txAssetHash.String()) + log.Infof("MSG [L1->L2] waitDepositToBeReadyToClaim") + deposit, err := waitDepositToBeReadyToClaim(ctx, testData, txAssetHash, maxTimeToClaimReady, contractDeployedAdrr.String()) + require.NoError(t, err) + log.Infof("MSG [L2->L1] manualClaimDeposit") + err = manualClaimDepositL2(ctx, testData, deposit) + require.NoError(t, err) + checkThatPingReceivedIsEmitted(ctx, t, blockDeployed, pingContract) +} + +func TestMessageTransferL2toL1(t *testing.T) { + if testing.Short() { + t.Skip() + } + log.Infof("Starting test bridge_message L2 -> L1") + ctx := context.TODO() + testData, err := NewBridge2e2TestData(ctx, nil) + require.NoError(t, err) + log.Infof("MSG [L2->L1] deploying contract to L1 to recieve message") + v, err := testData.L1Client.Bridge.NetworkID(nil) + require.NoError(t, err) + log.Infof("MSG [L2->L1] L1 Network ID: %d", v) + //contractDeployedAdrr, _, err := deployBridgeMessageReceiver(ctx, testData.auth[operations.L2], testData.L2Client) + contractDeployedAdrr, pingContract, blockDeployed, err := deployBridgeMessagePingReceiver(ctx, testData.auth[operations.L1], testData.L1Client, testData.cfg.ConnectionConfig.L1BridgeAddr) + require.NoError(t, err) + log.Infof("MSG [L2->L1] deployed contract to recieve message: %s", contractDeployedAdrr.String()) + log.Infof("MSG [L2->L1] Setting to PingReceiver Contract the sender of the message, if not is refused") + tx, err := pingContract.SetSender(testData.auth[operations.L1], testData.auth[operations.L2].From) + require.NoError(t, err) + log.Infof("MSG [L2->L1] SetSender(%s) tx: %s", testData.auth[operations.L2].From, tx.Hash().String()) + + log.Infof("MSG [L2->L1] send BridgeMessage to L1 bridge metadata: ") + amount := new(big.Int).SetUint64(1000000000000005555) + txAssetHash := assetMsgL2ToL1(ctx, testData, t, contractDeployedAdrr, amount, newMetadata(4)) + log.Infof("MSG [L2->L1] txAssetHash: %s", txAssetHash.String()) + log.Infof("MSG [L2->L1] waitDepositToBeReadyToClaim") + deposit, err := waitDepositToBeReadyToClaim(ctx, testData, txAssetHash, maxTimeToClaimReady, contractDeployedAdrr.String()) + require.NoError(t, err) + log.Infof("MSG [L2->L1] manualClaimDeposit") + err = manualClaimDepositL1(ctx, testData, deposit) + require.NoError(t, err) + checkThatPingReceivedIsEmitted(ctx, t, blockDeployed, pingContract) +} + +func checkThatPingReceivedIsEmitted(ctx context.Context, t *testing.T, blockDeployed uint64, pingContract *PingReceiver.PingReceiver) { + query := bind.FilterOpts{Start: blockDeployed, End: nil, Context: ctx} + eventIterator, err := pingContract.FilterPingReceived(&query) + if err != nil { + log.Errorf("Error filtering events: %s", err.Error()) + } + if !eventIterator.Next() { + log.Errorf("Error getting event, something fails") + require.Fail(t, "Fail to retrieve the event PingReceived, something fails") + } +} + +func assetMsgL1ToL2(ctx context.Context, testData *bridge2e2TestData, t *testing.T, destAddr common.Address, amount *big.Int, metadata []byte) common.Hash { + destNetworkId, err := testData.L2Client.Bridge.NetworkID(nil) + require.NoError(t, err) + auth := testData.auth[operations.L1] + log.Infof("MSG [L1->L2] L2 Network ID: %d. BridgeMessage(destContract: %s) metadata:%+v from L1 -> L2 (from addr=%s)\n", destNetworkId, destAddr.String(), metadata, auth.From.String()) + txHash, err := assetMsgGeneric(ctx, testData.L1Client, destNetworkId, auth, destAddr, amount, metadata) + require.NoError(t, err) + return txHash +} + +func assetMsgL2ToL1(ctx context.Context, testData *bridge2e2TestData, t *testing.T, destAddr common.Address, amount *big.Int, metadata []byte) common.Hash { + destNetworkId, err := testData.L1Client.Bridge.NetworkID(nil) + require.NoError(t, err) + auth := testData.auth[operations.L2] + log.Infof("MSG [L2->L1] L1 Network ID: %d. L2->BridgeMessage(destContract: %s) metadata:%+v from L2 -> L1 (from addr=%s)\n", destNetworkId, destAddr.String(), metadata, auth.From.String()) + txHash, err := assetMsgGeneric(ctx, testData.L2Client, destNetworkId, auth, destAddr, amount, metadata) + require.NoError(t, err) + return txHash +} + +func assetMsgGeneric(ctx context.Context, client *utils.Client, destNetwork uint32, auth *bind.TransactOpts, destAddr common.Address, amount *big.Int, metadata []byte) (common.Hash, error) { + auth.GasLimit = 500000 + auth.Value = amount + tx, err := client.Bridge.BridgeMessage(auth, destNetwork, destAddr, true, metadata) + if err != nil { + return common.Hash{}, err + } + fmt.Println("Tx: ", tx.Hash().Hex()) + err = ops.WaitTxToBeMined(ctx, client.Client, tx, 60*time.Second) + return tx.Hash(), err +} +func checkEventOfBridgeMessageReceiver(t *testing.T, pingContract *PingReceiver.PingReceiver, blockDeployed uint64, timeNow uint32) { + +} + +func deployBridgeMessageReceiver(ctx context.Context, auth *bind.TransactOpts, backend *utils.Client) (common.Address, *BridgeMessageReceiver.BridgeMessageReceiver, error) { + const txMinedTimeoutLimit = 60 * time.Second + addr, tx, contractBinded, err := BridgeMessageReceiver.DeployBridgeMessageReceiver(auth, backend) + if err != nil { + return common.Address{}, nil, err + } + err = ops.WaitTxToBeMined(ctx, backend, tx, txMinedTimeoutLimit) + + return addr, contractBinded, err +} +func deployBridgeMessagePingReceiver(ctx context.Context, auth *bind.TransactOpts, backend *utils.Client, bridgeAddr common.Address) (common.Address, *PingReceiver.PingReceiver, uint64, error) { + const txMinedTimeoutLimit = 60 * time.Second + log.Infof("Deploying PingReceiver contract using ath.From: %s", auth.From.String()) + addr, tx, contractBinded, err := PingReceiver.DeployPingReceiver(auth, backend, bridgeAddr) + if err != nil { + log.Errorf("Error deploying PingReceiver contract: %s", err.Error()) + return common.Address{}, nil, 0, err + } + err = ops.WaitTxToBeMined(ctx, backend, tx, txMinedTimeoutLimit) + if err != nil { + log.Errorf("Error deploying PingReceiver contract:WaitTxToBeMined: %s", err.Error()) + return common.Address{}, nil, 0, err + } + receipt, err := backend.TransactionReceipt(ctx, tx.Hash()) + if err != nil { + log.Errorf("Error deploying PingReceiver contract:TransactionReceipt: %s", err.Error()) + return common.Address{}, nil, 0, err + } + return addr, contractBinded, receipt.BlockNumber.Uint64(), nil +} diff --git a/test/e2e/bridge_network_erc20_test.go b/test/e2e/bridge_network_erc20_test.go index 13794cc1..66c5d174 100644 --- a/test/e2e/bridge_network_erc20_test.go +++ b/test/e2e/bridge_network_erc20_test.go @@ -24,41 +24,59 @@ func TestERC20TransferL1toL2(t *testing.T) { if testing.Short() { t.Skip() } - log.Infof("Starting test L1 -> L2") + log.Infof("Starting test ERC20 L1 -> L2") ctx := context.TODO() testData, err := NewBridge2e2TestData(ctx, nil) require.NoError(t, err) - log.Infof("[L1->L2] Deploy token\n") + balances, err := getcurrentBalance(ctx, testData) + require.NoError(t, err) + log.Infof("ERC20 [L1->L2] balances: %s", balances.String()) + + log.Infof("ERC20 [L1->L2] Deploy token") tokenAddr, err := deployToken(ctx, testData.L1Client, testData.auth[operations.L1], testData.cfg.ConnectionConfig.L1BridgeAddr) - log.Infof("[L1->L2] L1: Token Addr: ", tokenAddr.Hex()) require.NoError(t, err) + log.Infof("ERC20 [L1->L2] L1: Token Addr: ", tokenAddr.Hex()) + // Do Asset L1 -> L2 amount := big.NewInt(143210000000001234) // 0.14321 ETH - log.Infof("[L1->L2] assetERC20L2ToL1") - txAssetHash := assetERC20L2ToL1(ctx, testData, t, tokenAddr, amount) - log.Infof("ERC20 L1->L2 txAssetHash: %s \n", txAssetHash.String()) - log.Infof("[L1->L2] waitToAutoClaim") - waitToAutoClaim(t, ctx, testData, txAssetHash, maxTimeToClaimReady) + log.Infof("ERC20 [L1->L2] assetERC20L2ToL1") + txAssetHash := assetERC20L1ToL2(ctx, testData, t, tokenAddr, amount) + log.Infof("ERC20 [L1->L2] assetERC20L2ToL1 txAssetHash: %s ", txAssetHash.String()) + log.Infof("ERC20 [L1->L2] waitToAutoClaim") + //waitToAutoClaim(t, ctx, testData, txAssetHash, maxTimeToClaimReady) + deposit, err := waitDepositToBeReadyToClaim(ctx, testData, txAssetHash, maxTimeToClaimReady, testData.auth[operations.L1].From.String()) + require.NoError(t, err) + err = waitToAutoClaimTx(t, ctx, testData, deposit, 60*time.Second) + if err != nil { + log.Errorf("ERC20 [L1->L2] Doing manual claim") + err = manualClaimDepositL2(ctx, testData, deposit) + require.NoError(t, err) + } } func TestERC20TransferL2toL1(t *testing.T) { if testing.Short() { t.Skip() } - log.Infof("Starting test L2->L1") + log.Infof("Starting test ERC20 L2->L1") + ctx := context.TODO() testData, err := NewBridge2e2TestData(ctx, nil) require.NoError(t, err) + balances, err := getcurrentBalance(ctx, testData) + require.NoError(t, err) + log.Infof("ERC20 [L1->L2] balances: %s", balances.String()) + tokenAddr, err := deployToken(ctx, testData.L2Client, testData.auth[operations.L2], testData.cfg.ConnectionConfig.L2BridgeAddr) - log.Infof("[L2->L1] L2: Token Addr: ", tokenAddr.Hex()) require.NoError(t, err) - log.Infof("[L2->L1] assetERC20L2ToL1") - txAssetHash := assetERC20L1ToL2(ctx, testData, t, tokenAddr, big.NewInt(133330000000001234)) - log.Infof("[L2->L1] ERC20 L2->L1 txAssetHash: %s ", txAssetHash.String()) - deposit, err := waitDepositToBeReadyToClaim(ctx, testData, txAssetHash, maxTimeToClaimReady) + log.Infof("ERC20 [L2->L1] L2: Token Addr: ", tokenAddr.Hex()) + log.Infof("ERC20 [L2->L1] assetERC20L2ToL1") + txAssetHash := assetERC20L2ToL1(ctx, testData, t, tokenAddr, big.NewInt(133330000000001234)) + log.Infof("ERC20 [L2->L1] ERC20 L2->L1 txAssetHash: %s ", txAssetHash.String()) + deposit, err := waitDepositToBeReadyToClaim(ctx, testData, txAssetHash, maxTimeToClaimReady, testData.auth[operations.L2].From.String()) require.NoError(t, err) - log.Infof("[L2->L1] manualClaimDeposit") - err = manualClaimDeposit(ctx, testData, deposit) + log.Infof("ERC20 [L2->L1] manualClaimDeposit") + err = manualClaimDepositL1(ctx, testData, deposit) require.NoError(t, err) } @@ -67,7 +85,7 @@ func deployToken(ctx context.Context, client *utils.Client, auth *bind.TransactO if err != nil { return tokenAddr, err } - fmt.Println("Token Addr: ", tokenAddr.Hex()) + log.Info("Token Addr: ", tokenAddr.Hex()) amountTokens := new(big.Int).SetUint64(1000000000000000000) err = client.ApproveERC20(ctx, tokenAddr, bridgeAddr, amountTokens, auth) if err != nil { @@ -81,7 +99,7 @@ func deployToken(ctx context.Context, client *utils.Client, auth *bind.TransactO if err != nil { return tokenAddr, err } - fmt.Println("ERC20 Balance: ", erc20Balance.String()) + log.Info("ERC20 Balance: ", erc20Balance.String()) return tokenAddr, nil } @@ -101,21 +119,21 @@ func getAccountTokenBalance(ctx context.Context, auth *bind.TransactOpts, client return balance, nil } -func assetERC20L2ToL1(ctx context.Context, testData *bridge2e2TestData, t *testing.T, tokenAddr common.Address, amount *big.Int) common.Hash { +func assetERC20L1ToL2(ctx context.Context, testData *bridge2e2TestData, t *testing.T, tokenAddr common.Address, amount *big.Int) common.Hash { l2NetworkId, err := testData.L2Client.Bridge.NetworkID(nil) require.NoError(t, err) auth := testData.auth[operations.L1] - fmt.Printf("L2 Network ID: %d. Asset ERC20(%s) %+v from L1 -> L2 (addr=%s)\n", l2NetworkId, tokenAddr.String(), amount, auth.From.String()) + fmt.Printf("L1->L2 Network ID: %d. Asset ERC20(%s) %+v from L1 -> L2 (addr=%s)\n", l2NetworkId, tokenAddr.String(), amount, auth.From.String()) txHash, err := assetERC20Generic(ctx, testData.L1Client, l2NetworkId, auth, tokenAddr, amount) require.NoError(t, err) return txHash } -func assetERC20L1ToL2(ctx context.Context, testData *bridge2e2TestData, t *testing.T, tokenAddr common.Address, amount *big.Int) common.Hash { +func assetERC20L2ToL1(ctx context.Context, testData *bridge2e2TestData, t *testing.T, tokenAddr common.Address, amount *big.Int) common.Hash { destNetworkId, err := testData.L1Client.Bridge.NetworkID(nil) require.NoError(t, err) auth := testData.auth[operations.L2] - fmt.Printf("L1 Network ID: %d. Asset ERC20(%s) %+v from L2 -> L1 (addr=%s)\n", destNetworkId, tokenAddr.String(), amount, auth.From.String()) + fmt.Printf("L2->L1 Network ID: %d. Asset ERC20(%s) %+v from L2 -> L1 (addr=%s)\n", destNetworkId, tokenAddr.String(), amount, auth.From.String()) txHash, err := assetERC20Generic(ctx, testData.L2Client, destNetworkId, auth, tokenAddr, amount) require.NoError(t, err) return txHash diff --git a/test/e2e/bridge_network_shared.go b/test/e2e/bridge_network_shared.go index 77866709..e749574c 100644 --- a/test/e2e/bridge_network_shared.go +++ b/test/e2e/bridge_network_shared.go @@ -1,5 +1,5 @@ -//go:build e2e_real_network_eth || e2e_real_network_erc20 -// +build e2e_real_network_eth e2e_real_network_erc20 +//go:build e2e_real_network_eth || e2e_real_network_erc20 || e2e_real_network_msg +// +build e2e_real_network_eth e2e_real_network_erc20 e2e_real_network_msg package e2e @@ -32,10 +32,10 @@ import ( ) type bridge2e2TestConfig struct { - ConnectionConfig client.Config - ChainID int - TestAddr string - TestAddrPrivate string + ConnectionConfig client.Config + ChainID int + TestL1AddrPrivate string + TestL2AddrPrivate string } const ( @@ -120,28 +120,30 @@ func NewBridge2e2TestData(ctx context.Context, cfg *bridge2e2TestConfig) (*bridg l1Client, err := utils.NewClient(ctx, cfg.ConnectionConfig.L1NodeURL, cfg.ConnectionConfig.L1BridgeAddr) if err != nil { - return nil, err + return nil, fmt.Errorf("Error connecting L1 url: %s Err:%w", cfg.ConnectionConfig.L1NodeURL, err) } l2Client, err := utils.NewClient(ctx, cfg.ConnectionConfig.L2NodeURL, cfg.ConnectionConfig.L2BridgeAddr) if err != nil { - return nil, err + return nil, fmt.Errorf("Error connecting L2 url: %s Err:%w", cfg.ConnectionConfig.L2NodeURL, err) } l1BridgeService := client.NewRestClient(cfg.ConnectionConfig.BridgeURL) - L1auth, err := l1Client.GetSigner(ctx, cfg.TestAddrPrivate) + L1auth, err := l1Client.GetSigner(ctx, cfg.TestL1AddrPrivate) if err != nil { - return nil, err + return nil, fmt.Errorf("Error auth from L1: Err:%w", err) } - if cfg.TestAddr == "" { - cfg.TestAddr = L1auth.From.String() - } else { - if cfg.TestAddr != L1auth.From.String() { - return nil, fmt.Errorf("TestAddr: %s is different from the one in the private key: %s", cfg.TestAddr, L1auth.From.String()) + /* + if cfg.TestAddr == "" { + cfg.TestAddr = L1auth.From.String() + } else { + if cfg.TestAddr != L1auth.From.String() { + return nil, fmt.Errorf("TestAddr: %s is different from the one in the private key: %s", cfg.TestAddr, L1auth.From.String()) + } } - } - L2auth, err := l2Client.GetSigner(ctx, cfg.TestAddrPrivate) + */ + L2auth, err := l2Client.GetSigner(ctx, cfg.TestL2AddrPrivate) if err != nil { - return nil, err + return nil, fmt.Errorf("Error auth from L2: Err:%w", err) } return &bridge2e2TestData{ L1Client: l1Client, @@ -199,14 +201,22 @@ func showCurrentStatus(t *testing.T, ctx context.Context, testData *bridge2e2Tes require.NoError(t, err) fmt.Println("Chain ID L2: ", chainL2.String()) - deposits, _, err := testData.l1BridgeService.GetBridges(testData.cfg.TestAddr, 0, 10) + deposits, _, err := testData.l1BridgeService.GetBridges(testData.auth[operations.L1].From.String(), 0, 10) require.NoError(t, err) for _, deposit := range deposits { fmt.Println("Deposit: ", deposit) } } -func manualClaimDeposit(ctx context.Context, testData *bridge2e2TestData, deposit *pb.Deposit) error { +func manualClaimDepositL1(ctx context.Context, testData *bridge2e2TestData, deposit *pb.Deposit) error { + return manualClaimDeposit(ctx, testData, deposit, true) +} + +func manualClaimDepositL2(ctx context.Context, testData *bridge2e2TestData, deposit *pb.Deposit) error { + return manualClaimDeposit(ctx, testData, deposit, false) +} + +func manualClaimDeposit(ctx context.Context, testData *bridge2e2TestData, deposit *pb.Deposit, L1 bool) error { proof, err := testData.l1BridgeService.GetMerkleProof(deposit.NetworkId, deposit.DepositCnt) if err != nil { log.Fatal("error: ", err) @@ -223,7 +233,13 @@ func manualClaimDeposit(ctx context.Context, testData *bridge2e2TestData, deposi ger := ðerman.GlobalExitRoot{ ExitRoots: []common.Hash{common.HexToHash(proof.MainExitRoot), common.HexToHash(proof.RollupExitRoot)}, } - err = testData.L1Client.SendClaim(ctx, deposit, smtProof, smtRollupProof, ger, testData.auth[operations.L1]) + if L1 { + log.Infof(" L1.Claim()") + err = testData.L1Client.SendClaim(ctx, deposit, smtProof, smtRollupProof, ger, testData.auth[operations.L1]) + } else { + log.Infof(" L2.Claim()") + err = testData.L2Client.SendClaim(ctx, deposit, smtProof, smtRollupProof, ger, testData.auth[operations.L2]) + } return err } @@ -249,40 +265,11 @@ func printMkerkleProof(mkProof [mtHeight][32]byte, title string) { } } -func waitDepositToBeReadyToClaim(ctx context.Context, testData *bridge2e2TestData, asssetTxHash common.Hash, timeout time.Duration) (*pb.Deposit, error) { - startTime := time.Now() - for true { - fmt.Println("Waiting to deposit fo assetTx: ", asssetTxHash.Hex(), "...") - deposits, _, err := testData.l1BridgeService.GetBridges(testData.cfg.TestAddr, 0, 10) - if err != nil { - return nil, err - } - - for _, deposit := range deposits { - depositHash := common.HexToHash(deposit.TxHash) - if depositHash == asssetTxHash { - fmt.Println("Deposit: ", deposit) - - if deposit.ReadyForClaim { - fmt.Println("Found claim! Claim Is ready Elapsed time: ", time.Since(startTime)) - return deposit, nil - } - } - } - if time.Since(startTime) > timeout { - return nil, fmt.Errorf("Timeout waiting for deposit to be ready to be claimed") - } - fmt.Println("Sleeping ", timeBetweenCheckClaim.String(), "Elapsed time: ", time.Since(startTime)) - time.Sleep(timeBetweenCheckClaim) - } - return nil, nil -} - func waitDepositByTxHash(ctx context.Context, testData *bridge2e2TestData, asssetTxHash common.Hash, timeout time.Duration) (*pb.Deposit, error) { startTime := time.Now() for true { fmt.Println("Waiting to deposit fo assetTx: ", asssetTxHash.Hex(), "...") - deposits, _, err := testData.l1BridgeService.GetBridges(testData.cfg.TestAddr, 0, 10) + deposits, _, err := testData.l1BridgeService.GetBridges(testData.auth[operations.L1].From.String(), 0, 10) if err != nil { return nil, err } @@ -303,11 +290,11 @@ func waitDepositByTxHash(ctx context.Context, testData *bridge2e2TestData, assse return nil, nil } func getcurrentBalance(ctx context.Context, testData *bridge2e2TestData) (*ethBalances, error) { - balanceL1, err := getBalance(ctx, testData.L1Client, testData.cfg.TestAddrPrivate, nil) + balanceL1, err := getBalance(ctx, testData.L1Client, testData.cfg.TestL1AddrPrivate, nil) if err != nil { return nil, err } - balanceL2, err := getBalance(ctx, testData.L2Client, testData.cfg.TestAddrPrivate, nil) + balanceL2, err := getBalance(ctx, testData.L2Client, testData.cfg.TestL2AddrPrivate, nil) if err != nil { return nil, err } @@ -361,11 +348,78 @@ func assetEthGeneric(ctx context.Context, client *utils.Client, destNetwork uint return tx.Hash(), err } +func waitDepositToBeReadyToClaim(ctx context.Context, testData *bridge2e2TestData, asssetTxHash common.Hash, timeout time.Duration, destAddr string) (*pb.Deposit, error) { + startTime := time.Now() + if len(destAddr) < 1 { + destAddr = testData.auth[operations.L1].From.String() + } + for true { + fmt.Println("Waiting to deposit (", destAddr, ") fo assetTx: ", asssetTxHash.Hex(), "...") + deposits, _, err := testData.l1BridgeService.GetBridges(destAddr, 0, 100) + if err != nil { + return nil, err + } + + for _, deposit := range deposits { + depositHash := common.HexToHash(deposit.TxHash) + if depositHash == asssetTxHash { + fmt.Println("Deposit found: ", deposit, " ready:", deposit.ReadyForClaim) + + if deposit.ReadyForClaim { + fmt.Println("Found claim! Claim Is ready Elapsed time: ", time.Since(startTime)) + return deposit, nil + } + } + } + if time.Since(startTime) > timeout { + return nil, fmt.Errorf("Timeout waiting for deposit to be ready to be claimed") + } + fmt.Println("Sleeping ", timeBetweenCheckClaim.String(), "Elapsed time: ", time.Since(startTime)) + time.Sleep(timeBetweenCheckClaim) + } + return nil, nil +} + func waitToAutoClaim(t *testing.T, ctx context.Context, testData *bridge2e2TestData, asssetTxHash common.Hash, timeout time.Duration) { + startTime := time.Now() + deposit, err := waitDepositToBeReadyToClaim(ctx, testData, asssetTxHash, timeout, testData.auth[operations.L1].From.String()) + require.NoError(t, err) + emptyHash := common.Hash{} + claimTxHash := common.HexToHash(deposit.ClaimTxHash) + if claimTxHash != emptyHash { + fmt.Println("Found claim! Claim Tx Hash: ", claimTxHash.Hex()) + // The claim from L1 -> L2 is done by the bridge service to L2 + receipt, err := waitTxToBeMinedByTxHash(ctx, testData.L2Client, claimTxHash, 60*time.Second) + require.NoError(t, err) + fmt.Println("Receipt: ", receipt, " Elapsed time: ", time.Since(startTime)) + return + } + require.Fail(t, "No auto-claim done, deposit:", deposit) +} + +func waitToAutoClaimTx(t *testing.T, ctx context.Context, testData *bridge2e2TestData, deposit *pb.Deposit, timeout time.Duration) error { + startTime := time.Now() + emptyHash := common.Hash{} + claimTxHash := common.HexToHash(deposit.ClaimTxHash) + if claimTxHash != emptyHash { + log.Debugf("Found claim! Claim Tx Hash: ", claimTxHash.Hex()) + // The claim from L1 -> L2 is done by the bridge service to L2 + receipt, err := waitTxToBeMinedByTxHash(ctx, testData.L2Client, claimTxHash, 60*time.Second) + if err != nil { + return err + } + log.Debug("Receipt: ", receipt, " Elapsed time: ", time.Since(startTime)) + return nil + } + return fmt.Errorf("No auto-claim tx, deposit: %+v", deposit) + +} + +func waitToAutoClaim2(t *testing.T, ctx context.Context, testData *bridge2e2TestData, asssetTxHash common.Hash, timeout time.Duration) { startTime := time.Now() for true { fmt.Println("Waiting to deposit fo assetTx: ", asssetTxHash.Hex(), "...") - deposits, _, err := testData.l1BridgeService.GetBridges(testData.cfg.TestAddr, 0, 10) + deposits, _, err := testData.l1BridgeService.GetBridges(testData.auth[operations.L1].From.String(), 0, 10) require.NoError(t, err) for _, deposit := range deposits { @@ -374,6 +428,7 @@ func waitToAutoClaim(t *testing.T, ctx context.Context, testData *bridge2e2TestD fmt.Println("Deposit: ", deposit, " Elapsed time: ", time.Since(startTime)) claimTxHash := common.HexToHash(deposit.ClaimTxHash) emptyHash := common.Hash{} + if claimTxHash != emptyHash { fmt.Println("Found claim! Claim Tx Hash: ", claimTxHash.Hex()) // The claim from L1 -> L2 is done by the bridge service to L2 @@ -382,12 +437,16 @@ func waitToAutoClaim(t *testing.T, ctx context.Context, testData *bridge2e2TestD fmt.Println("Receipt: ", receipt, " Elapsed time: ", time.Since(startTime)) return } + if deposit.ReadyForClaim && claimTxHash == emptyHash { + log.Warnf("Deposit is ready for claim but no claim tx hash found,maybe autoclaim is disabled?. Deposit: %+v", deposit) + } } } if time.Since(startTime) > timeout { require.Fail(t, "Timeout waiting for deposit to be automatically claimed by Bridge Service") } - time.Sleep(5 * time.Second) + fmt.Println("Sleeping ", timeBetweenCheckClaim.String(), "Elapsed time: ", time.Since(startTime)) + time.Sleep(timeBetweenCheckClaim) } } diff --git a/test/mocksmartcontracts/PingReceiver.sol b/test/mocksmartcontracts/PingReceiver.sol new file mode 100644 index 00000000..d8149453 --- /dev/null +++ b/test/mocksmartcontracts/PingReceiver.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: AGPL-3.0 + +pragma solidity >=0.8.17; + +import "./polygonZKEVMContracts/interfaces/IBridgeMessageReceiver.sol"; +import "./polygonZKEVMContracts/interfaces/IPolygonZkEVMBridge.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +/** + * ZkEVMNFTBridge is an example contract to use the message layer of the PolygonZkEVMBridge to bridge NFTs + */ +contract PingReceiver is IBridgeMessageReceiver, Ownable { + // Global Exit Root address + IPolygonZkEVMBridge public immutable polygonZkEVMBridge; + + // Current network identifier + uint32 public immutable networkID; + + // Address in the other network that will send the message + address public pingSender; + + // Value sent from the other network + uint256 public pingValue; + + /** + * @param _polygonZkEVMBridge Polygon zkevm bridge address + */ + constructor(IPolygonZkEVMBridge _polygonZkEVMBridge) { + polygonZkEVMBridge = _polygonZkEVMBridge; + networkID = polygonZkEVMBridge.networkID(); + } + + /** + * @dev Emitted when a message is received from another network + */ + event PingReceived(uint256 pingValue); + + /** + * @dev Emitted when change the sender + */ + event SetSender(address newPingSender); + + /** + * @notice Set the sender of the message + * @param newPingSender Address of the sender in the other network + */ + function setSender(address newPingSender) external onlyOwner { + pingSender = newPingSender; + emit SetSender(newPingSender); + } + + /** + * @notice Verify merkle proof and withdraw tokens/ether + * @param originAddress Origin address that the message was sended + * @param originNetwork Origin network that the message was sended ( not usefull for this contract) + * @param data Abi encoded metadata + */ + function onMessageReceived( + address originAddress, + uint32 originNetwork, + bytes memory data + ) external payable override { + // Can only be called by the bridge + require( + msg.sender == address(polygonZkEVMBridge), + "PingReceiver::onMessageReceived: Not PolygonZkEVMBridge" + ); + + // Can only be called by the sender on the other network + require( + pingSender == originAddress, + "PingReceiver::onMessageReceived: Not ping Sender" + ); + + // Decode data + pingValue = abi.decode(data, (uint256)); + + emit PingReceived(pingValue); + } +} diff --git a/test/mocksmartcontracts/PingReceiver/PingReceiver.go b/test/mocksmartcontracts/PingReceiver/PingReceiver.go new file mode 100644 index 00000000..2cebfc6e --- /dev/null +++ b/test/mocksmartcontracts/PingReceiver/PingReceiver.go @@ -0,0 +1,863 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package PingReceiver + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// PingReceiverMetaData contains all meta data concerning the PingReceiver contract. +var PingReceiverMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIPolygonZkEVMBridge\",\"name\":\"_polygonZkEVMBridge\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"pingValue\",\"type\":\"uint256\"}],\"name\":\"PingReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPingSender\",\"type\":\"address\"}],\"name\":\"SetSender\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"networkID\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"originNetwork\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onMessageReceived\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pingSender\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pingValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"polygonZkEVMBridge\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMBridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPingSender\",\"type\":\"address\"}],\"name\":\"setSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c060405234801561001057600080fd5b5060405161097b38038061097b83398101604081905261002f91610107565b610038336100b7565b6001600160a01b03811660808190526040805163bab161bf60e01b8152905163bab161bf9160048082019260209290919082900301816000875af1158015610084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a89190610137565b63ffffffff1660a0525061015d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561011957600080fd5b81516001600160a01b038116811461013057600080fd5b9392505050565b60006020828403121561014957600080fd5b815163ffffffff8116811461013057600080fd5b60805160a0516107f3610188600039600061018401526000818160c2015261024001526107f36000f3fe6080604052600436106100965760003560e01c8063ba2b0ff611610069578063ced32b0c1161004e578063ced32b0c146101bb578063f2fde38b146101db578063ffa8d9dc146101fb57600080fd5b8063ba2b0ff61461014e578063bab161bf1461017257600080fd5b80631806b5f21461009b5780635d43792c146100b0578063715018a61461010e5780638da5cb5b14610123575b600080fd5b6100ae6100a9366004610687565b610228565b005b3480156100bc57600080fd5b506100e47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561011a57600080fd5b506100ae6103ed565b34801561012f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100e4565b34801561015a57600080fd5b5061016460025481565b604051908152602001610105565b34801561017e57600080fd5b506101a67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610105565b3480156101c757600080fd5b506100ae6101d6366004610782565b610401565b3480156101e757600080fd5b506100ae6101f6366004610782565b610482565b34801561020757600080fd5b506001546100e49073ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f7420506f6c79676f6e5a6b45564d42726964676500000000000000000060648201526084015b60405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff84811691161461039c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f742070696e672053656e6465720000000000000000000000000000000060648201526084016102e9565b808060200190518101906103b091906107a4565b60028190556040519081527f51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d659060200160405180910390a1505050565b6103f5610539565b6103ff60006105ba565b565b610409610539565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b669060200160405180910390a150565b61048a610539565b73ffffffffffffffffffffffffffffffffffffffff811661052d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e9565b610536816105ba565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e9565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461065357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561069c57600080fd5b6106a58461062f565b9250602084013563ffffffff811681146106be57600080fd5b9150604084013567ffffffffffffffff808211156106db57600080fd5b818601915086601f8301126106ef57600080fd5b81358181111561070157610701610658565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074757610747610658565b8160405282815289602084870101111561076057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079457600080fd5b61079d8261062f565b9392505050565b6000602082840312156107b657600080fd5b505191905056fea2646970667358221220f7a6343b3726f685cbf1f60341761a53a0484ae48391492386c86ccaa585ea9964736f6c63430008110033", +} + +// PingReceiverABI is the input ABI used to generate the binding from. +// Deprecated: Use PingReceiverMetaData.ABI instead. +var PingReceiverABI = PingReceiverMetaData.ABI + +// PingReceiverBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use PingReceiverMetaData.Bin instead. +var PingReceiverBin = PingReceiverMetaData.Bin + +// DeployPingReceiver deploys a new Ethereum contract, binding an instance of PingReceiver to it. +func DeployPingReceiver(auth *bind.TransactOpts, backend bind.ContractBackend, _polygonZkEVMBridge common.Address) (common.Address, *types.Transaction, *PingReceiver, error) { + parsed, err := PingReceiverMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PingReceiverBin), backend, _polygonZkEVMBridge) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PingReceiver{PingReceiverCaller: PingReceiverCaller{contract: contract}, PingReceiverTransactor: PingReceiverTransactor{contract: contract}, PingReceiverFilterer: PingReceiverFilterer{contract: contract}}, nil +} + +// PingReceiver is an auto generated Go binding around an Ethereum contract. +type PingReceiver struct { + PingReceiverCaller // Read-only binding to the contract + PingReceiverTransactor // Write-only binding to the contract + PingReceiverFilterer // Log filterer for contract events +} + +// PingReceiverCaller is an auto generated read-only Go binding around an Ethereum contract. +type PingReceiverCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PingReceiverTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PingReceiverTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PingReceiverFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PingReceiverFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PingReceiverSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PingReceiverSession struct { + Contract *PingReceiver // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PingReceiverCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PingReceiverCallerSession struct { + Contract *PingReceiverCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PingReceiverTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PingReceiverTransactorSession struct { + Contract *PingReceiverTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PingReceiverRaw is an auto generated low-level Go binding around an Ethereum contract. +type PingReceiverRaw struct { + Contract *PingReceiver // Generic contract binding to access the raw methods on +} + +// PingReceiverCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PingReceiverCallerRaw struct { + Contract *PingReceiverCaller // Generic read-only contract binding to access the raw methods on +} + +// PingReceiverTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PingReceiverTransactorRaw struct { + Contract *PingReceiverTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPingReceiver creates a new instance of PingReceiver, bound to a specific deployed contract. +func NewPingReceiver(address common.Address, backend bind.ContractBackend) (*PingReceiver, error) { + contract, err := bindPingReceiver(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PingReceiver{PingReceiverCaller: PingReceiverCaller{contract: contract}, PingReceiverTransactor: PingReceiverTransactor{contract: contract}, PingReceiverFilterer: PingReceiverFilterer{contract: contract}}, nil +} + +// NewPingReceiverCaller creates a new read-only instance of PingReceiver, bound to a specific deployed contract. +func NewPingReceiverCaller(address common.Address, caller bind.ContractCaller) (*PingReceiverCaller, error) { + contract, err := bindPingReceiver(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PingReceiverCaller{contract: contract}, nil +} + +// NewPingReceiverTransactor creates a new write-only instance of PingReceiver, bound to a specific deployed contract. +func NewPingReceiverTransactor(address common.Address, transactor bind.ContractTransactor) (*PingReceiverTransactor, error) { + contract, err := bindPingReceiver(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PingReceiverTransactor{contract: contract}, nil +} + +// NewPingReceiverFilterer creates a new log filterer instance of PingReceiver, bound to a specific deployed contract. +func NewPingReceiverFilterer(address common.Address, filterer bind.ContractFilterer) (*PingReceiverFilterer, error) { + contract, err := bindPingReceiver(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PingReceiverFilterer{contract: contract}, nil +} + +// bindPingReceiver binds a generic wrapper to an already deployed contract. +func bindPingReceiver(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PingReceiverMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PingReceiver *PingReceiverRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PingReceiver.Contract.PingReceiverCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PingReceiver *PingReceiverRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingReceiver.Contract.PingReceiverTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PingReceiver *PingReceiverRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PingReceiver.Contract.PingReceiverTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PingReceiver *PingReceiverCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PingReceiver.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PingReceiver *PingReceiverTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingReceiver.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PingReceiver *PingReceiverTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PingReceiver.Contract.contract.Transact(opts, method, params...) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_PingReceiver *PingReceiverCaller) NetworkID(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _PingReceiver.contract.Call(opts, &out, "networkID") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_PingReceiver *PingReceiverSession) NetworkID() (uint32, error) { + return _PingReceiver.Contract.NetworkID(&_PingReceiver.CallOpts) +} + +// NetworkID is a free data retrieval call binding the contract method 0xbab161bf. +// +// Solidity: function networkID() view returns(uint32) +func (_PingReceiver *PingReceiverCallerSession) NetworkID() (uint32, error) { + return _PingReceiver.Contract.NetworkID(&_PingReceiver.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PingReceiver *PingReceiverCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingReceiver.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PingReceiver *PingReceiverSession) Owner() (common.Address, error) { + return _PingReceiver.Contract.Owner(&_PingReceiver.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PingReceiver *PingReceiverCallerSession) Owner() (common.Address, error) { + return _PingReceiver.Contract.Owner(&_PingReceiver.CallOpts) +} + +// PingSender is a free data retrieval call binding the contract method 0xffa8d9dc. +// +// Solidity: function pingSender() view returns(address) +func (_PingReceiver *PingReceiverCaller) PingSender(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingReceiver.contract.Call(opts, &out, "pingSender") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PingSender is a free data retrieval call binding the contract method 0xffa8d9dc. +// +// Solidity: function pingSender() view returns(address) +func (_PingReceiver *PingReceiverSession) PingSender() (common.Address, error) { + return _PingReceiver.Contract.PingSender(&_PingReceiver.CallOpts) +} + +// PingSender is a free data retrieval call binding the contract method 0xffa8d9dc. +// +// Solidity: function pingSender() view returns(address) +func (_PingReceiver *PingReceiverCallerSession) PingSender() (common.Address, error) { + return _PingReceiver.Contract.PingSender(&_PingReceiver.CallOpts) +} + +// PingValue is a free data retrieval call binding the contract method 0xba2b0ff6. +// +// Solidity: function pingValue() view returns(uint256) +func (_PingReceiver *PingReceiverCaller) PingValue(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PingReceiver.contract.Call(opts, &out, "pingValue") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PingValue is a free data retrieval call binding the contract method 0xba2b0ff6. +// +// Solidity: function pingValue() view returns(uint256) +func (_PingReceiver *PingReceiverSession) PingValue() (*big.Int, error) { + return _PingReceiver.Contract.PingValue(&_PingReceiver.CallOpts) +} + +// PingValue is a free data retrieval call binding the contract method 0xba2b0ff6. +// +// Solidity: function pingValue() view returns(uint256) +func (_PingReceiver *PingReceiverCallerSession) PingValue() (*big.Int, error) { + return _PingReceiver.Contract.PingValue(&_PingReceiver.CallOpts) +} + +// PolygonZkEVMBridge is a free data retrieval call binding the contract method 0x5d43792c. +// +// Solidity: function polygonZkEVMBridge() view returns(address) +func (_PingReceiver *PingReceiverCaller) PolygonZkEVMBridge(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PingReceiver.contract.Call(opts, &out, "polygonZkEVMBridge") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PolygonZkEVMBridge is a free data retrieval call binding the contract method 0x5d43792c. +// +// Solidity: function polygonZkEVMBridge() view returns(address) +func (_PingReceiver *PingReceiverSession) PolygonZkEVMBridge() (common.Address, error) { + return _PingReceiver.Contract.PolygonZkEVMBridge(&_PingReceiver.CallOpts) +} + +// PolygonZkEVMBridge is a free data retrieval call binding the contract method 0x5d43792c. +// +// Solidity: function polygonZkEVMBridge() view returns(address) +func (_PingReceiver *PingReceiverCallerSession) PolygonZkEVMBridge() (common.Address, error) { + return _PingReceiver.Contract.PolygonZkEVMBridge(&_PingReceiver.CallOpts) +} + +// OnMessageReceived is a paid mutator transaction binding the contract method 0x1806b5f2. +// +// Solidity: function onMessageReceived(address originAddress, uint32 originNetwork, bytes data) payable returns() +func (_PingReceiver *PingReceiverTransactor) OnMessageReceived(opts *bind.TransactOpts, originAddress common.Address, originNetwork uint32, data []byte) (*types.Transaction, error) { + return _PingReceiver.contract.Transact(opts, "onMessageReceived", originAddress, originNetwork, data) +} + +// OnMessageReceived is a paid mutator transaction binding the contract method 0x1806b5f2. +// +// Solidity: function onMessageReceived(address originAddress, uint32 originNetwork, bytes data) payable returns() +func (_PingReceiver *PingReceiverSession) OnMessageReceived(originAddress common.Address, originNetwork uint32, data []byte) (*types.Transaction, error) { + return _PingReceiver.Contract.OnMessageReceived(&_PingReceiver.TransactOpts, originAddress, originNetwork, data) +} + +// OnMessageReceived is a paid mutator transaction binding the contract method 0x1806b5f2. +// +// Solidity: function onMessageReceived(address originAddress, uint32 originNetwork, bytes data) payable returns() +func (_PingReceiver *PingReceiverTransactorSession) OnMessageReceived(originAddress common.Address, originNetwork uint32, data []byte) (*types.Transaction, error) { + return _PingReceiver.Contract.OnMessageReceived(&_PingReceiver.TransactOpts, originAddress, originNetwork, data) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PingReceiver *PingReceiverTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PingReceiver.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PingReceiver *PingReceiverSession) RenounceOwnership() (*types.Transaction, error) { + return _PingReceiver.Contract.RenounceOwnership(&_PingReceiver.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PingReceiver *PingReceiverTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _PingReceiver.Contract.RenounceOwnership(&_PingReceiver.TransactOpts) +} + +// SetSender is a paid mutator transaction binding the contract method 0xced32b0c. +// +// Solidity: function setSender(address newPingSender) returns() +func (_PingReceiver *PingReceiverTransactor) SetSender(opts *bind.TransactOpts, newPingSender common.Address) (*types.Transaction, error) { + return _PingReceiver.contract.Transact(opts, "setSender", newPingSender) +} + +// SetSender is a paid mutator transaction binding the contract method 0xced32b0c. +// +// Solidity: function setSender(address newPingSender) returns() +func (_PingReceiver *PingReceiverSession) SetSender(newPingSender common.Address) (*types.Transaction, error) { + return _PingReceiver.Contract.SetSender(&_PingReceiver.TransactOpts, newPingSender) +} + +// SetSender is a paid mutator transaction binding the contract method 0xced32b0c. +// +// Solidity: function setSender(address newPingSender) returns() +func (_PingReceiver *PingReceiverTransactorSession) SetSender(newPingSender common.Address) (*types.Transaction, error) { + return _PingReceiver.Contract.SetSender(&_PingReceiver.TransactOpts, newPingSender) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PingReceiver *PingReceiverTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _PingReceiver.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PingReceiver *PingReceiverSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PingReceiver.Contract.TransferOwnership(&_PingReceiver.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PingReceiver *PingReceiverTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PingReceiver.Contract.TransferOwnership(&_PingReceiver.TransactOpts, newOwner) +} + +// PingReceiverOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the PingReceiver contract. +type PingReceiverOwnershipTransferredIterator struct { + Event *PingReceiverOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PingReceiverOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingReceiverOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PingReceiverOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PingReceiverOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PingReceiverOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PingReceiverOwnershipTransferred represents a OwnershipTransferred event raised by the PingReceiver contract. +type PingReceiverOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PingReceiver *PingReceiverFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*PingReceiverOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PingReceiver.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &PingReceiverOwnershipTransferredIterator{contract: _PingReceiver.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PingReceiver *PingReceiverFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PingReceiverOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PingReceiver.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PingReceiverOwnershipTransferred) + if err := _PingReceiver.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PingReceiver *PingReceiverFilterer) ParseOwnershipTransferred(log types.Log) (*PingReceiverOwnershipTransferred, error) { + event := new(PingReceiverOwnershipTransferred) + if err := _PingReceiver.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PingReceiverPingReceivedIterator is returned from FilterPingReceived and is used to iterate over the raw logs and unpacked data for PingReceived events raised by the PingReceiver contract. +type PingReceiverPingReceivedIterator struct { + Event *PingReceiverPingReceived // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PingReceiverPingReceivedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingReceiverPingReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PingReceiverPingReceived) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PingReceiverPingReceivedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PingReceiverPingReceivedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PingReceiverPingReceived represents a PingReceived event raised by the PingReceiver contract. +type PingReceiverPingReceived struct { + PingValue *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterPingReceived is a free log retrieval operation binding the contract event 0x51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d65. +// +// Solidity: event PingReceived(uint256 pingValue) +func (_PingReceiver *PingReceiverFilterer) FilterPingReceived(opts *bind.FilterOpts) (*PingReceiverPingReceivedIterator, error) { + + logs, sub, err := _PingReceiver.contract.FilterLogs(opts, "PingReceived") + if err != nil { + return nil, err + } + return &PingReceiverPingReceivedIterator{contract: _PingReceiver.contract, event: "PingReceived", logs: logs, sub: sub}, nil +} + +// WatchPingReceived is a free log subscription operation binding the contract event 0x51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d65. +// +// Solidity: event PingReceived(uint256 pingValue) +func (_PingReceiver *PingReceiverFilterer) WatchPingReceived(opts *bind.WatchOpts, sink chan<- *PingReceiverPingReceived) (event.Subscription, error) { + + logs, sub, err := _PingReceiver.contract.WatchLogs(opts, "PingReceived") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PingReceiverPingReceived) + if err := _PingReceiver.contract.UnpackLog(event, "PingReceived", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParsePingReceived is a log parse operation binding the contract event 0x51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d65. +// +// Solidity: event PingReceived(uint256 pingValue) +func (_PingReceiver *PingReceiverFilterer) ParsePingReceived(log types.Log) (*PingReceiverPingReceived, error) { + event := new(PingReceiverPingReceived) + if err := _PingReceiver.contract.UnpackLog(event, "PingReceived", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PingReceiverSetSenderIterator is returned from FilterSetSender and is used to iterate over the raw logs and unpacked data for SetSender events raised by the PingReceiver contract. +type PingReceiverSetSenderIterator struct { + Event *PingReceiverSetSender // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PingReceiverSetSenderIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PingReceiverSetSender) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PingReceiverSetSender) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PingReceiverSetSenderIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PingReceiverSetSenderIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PingReceiverSetSender represents a SetSender event raised by the PingReceiver contract. +type PingReceiverSetSender struct { + NewPingSender common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetSender is a free log retrieval operation binding the contract event 0x3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b66. +// +// Solidity: event SetSender(address newPingSender) +func (_PingReceiver *PingReceiverFilterer) FilterSetSender(opts *bind.FilterOpts) (*PingReceiverSetSenderIterator, error) { + + logs, sub, err := _PingReceiver.contract.FilterLogs(opts, "SetSender") + if err != nil { + return nil, err + } + return &PingReceiverSetSenderIterator{contract: _PingReceiver.contract, event: "SetSender", logs: logs, sub: sub}, nil +} + +// WatchSetSender is a free log subscription operation binding the contract event 0x3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b66. +// +// Solidity: event SetSender(address newPingSender) +func (_PingReceiver *PingReceiverFilterer) WatchSetSender(opts *bind.WatchOpts, sink chan<- *PingReceiverSetSender) (event.Subscription, error) { + + logs, sub, err := _PingReceiver.contract.WatchLogs(opts, "SetSender") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PingReceiverSetSender) + if err := _PingReceiver.contract.UnpackLog(event, "SetSender", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetSender is a log parse operation binding the contract event 0x3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b66. +// +// Solidity: event SetSender(address newPingSender) +func (_PingReceiver *PingReceiverFilterer) ParseSetSender(log types.Log) (*PingReceiverSetSender, error) { + event := new(PingReceiverSetSender) + if err := _PingReceiver.contract.UnpackLog(event, "SetSender", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/test/mocksmartcontracts/abi/PingReceiver.abi b/test/mocksmartcontracts/abi/PingReceiver.abi new file mode 100644 index 00000000..ebc2e5f2 --- /dev/null +++ b/test/mocksmartcontracts/abi/PingReceiver.abi @@ -0,0 +1,179 @@ + [ + { + "inputs": [ + { + "internalType": "contract IPolygonZkEVMBridge", + "name": "_polygonZkEVMBridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "pingValue", + "type": "uint256" + } + ], + "name": "PingReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPingSender", + "type": "address" + } + ], + "name": "SetSender", + "type": "event" + }, + { + "inputs": [], + "name": "networkID", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "onMessageReceived", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pingSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pingValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "polygonZkEVMBridge", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPingSender", + "type": "address" + } + ], + "name": "setSender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/test/mocksmartcontracts/bin/PingReceiver.bin b/test/mocksmartcontracts/bin/PingReceiver.bin new file mode 100644 index 00000000..0dece813 --- /dev/null +++ b/test/mocksmartcontracts/bin/PingReceiver.bin @@ -0,0 +1 @@ +0x60c060405234801561001057600080fd5b5060405161097b38038061097b83398101604081905261002f91610107565b610038336100b7565b6001600160a01b03811660808190526040805163bab161bf60e01b8152905163bab161bf9160048082019260209290919082900301816000875af1158015610084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a89190610137565b63ffffffff1660a0525061015d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561011957600080fd5b81516001600160a01b038116811461013057600080fd5b9392505050565b60006020828403121561014957600080fd5b815163ffffffff8116811461013057600080fd5b60805160a0516107f3610188600039600061018401526000818160c2015261024001526107f36000f3fe6080604052600436106100965760003560e01c8063ba2b0ff611610069578063ced32b0c1161004e578063ced32b0c146101bb578063f2fde38b146101db578063ffa8d9dc146101fb57600080fd5b8063ba2b0ff61461014e578063bab161bf1461017257600080fd5b80631806b5f21461009b5780635d43792c146100b0578063715018a61461010e5780638da5cb5b14610123575b600080fd5b6100ae6100a9366004610687565b610228565b005b3480156100bc57600080fd5b506100e47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561011a57600080fd5b506100ae6103ed565b34801561012f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100e4565b34801561015a57600080fd5b5061016460025481565b604051908152602001610105565b34801561017e57600080fd5b506101a67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610105565b3480156101c757600080fd5b506100ae6101d6366004610782565b610401565b3480156101e757600080fd5b506100ae6101f6366004610782565b610482565b34801561020757600080fd5b506001546100e49073ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f7420506f6c79676f6e5a6b45564d42726964676500000000000000000060648201526084015b60405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff84811691161461039c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f742070696e672053656e6465720000000000000000000000000000000060648201526084016102e9565b808060200190518101906103b091906107a4565b60028190556040519081527f51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d659060200160405180910390a1505050565b6103f5610539565b6103ff60006105ba565b565b610409610539565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b669060200160405180910390a150565b61048a610539565b73ffffffffffffffffffffffffffffffffffffffff811661052d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e9565b610536816105ba565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e9565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461065357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561069c57600080fd5b6106a58461062f565b9250602084013563ffffffff811681146106be57600080fd5b9150604084013567ffffffffffffffff808211156106db57600080fd5b818601915086601f8301126106ef57600080fd5b81358181111561070157610701610658565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074757610747610658565b8160405282815289602084870101111561076057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079457600080fd5b61079d8261062f565b9392505050565b6000602082840312156107b657600080fd5b505191905056fea2646970667358221220f7a6343b3726f685cbf1f60341761a53a0484ae48391492386c86ccaa585ea9964736f6c63430008110033 \ No newline at end of file diff --git a/test/mocksmartcontracts/json/PingReceiver.json b/test/mocksmartcontracts/json/PingReceiver.json new file mode 100644 index 00000000..14f35637 --- /dev/null +++ b/test/mocksmartcontracts/json/PingReceiver.json @@ -0,0 +1,188 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "PingReceiver", + "sourceName": "contracts/PingReceiver.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IPolygonZkEVMBridge", + "name": "_polygonZkEVMBridge", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "pingValue", + "type": "uint256" + } + ], + "name": "PingReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPingSender", + "type": "address" + } + ], + "name": "SetSender", + "type": "event" + }, + { + "inputs": [], + "name": "networkID", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "originAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "originNetwork", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "onMessageReceived", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pingSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pingValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "polygonZkEVMBridge", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMBridge", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPingSender", + "type": "address" + } + ], + "name": "setSender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60c060405234801561001057600080fd5b5060405161097b38038061097b83398101604081905261002f91610107565b610038336100b7565b6001600160a01b03811660808190526040805163bab161bf60e01b8152905163bab161bf9160048082019260209290919082900301816000875af1158015610084573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a89190610137565b63ffffffff1660a0525061015d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561011957600080fd5b81516001600160a01b038116811461013057600080fd5b9392505050565b60006020828403121561014957600080fd5b815163ffffffff8116811461013057600080fd5b60805160a0516107f3610188600039600061018401526000818160c2015261024001526107f36000f3fe6080604052600436106100965760003560e01c8063ba2b0ff611610069578063ced32b0c1161004e578063ced32b0c146101bb578063f2fde38b146101db578063ffa8d9dc146101fb57600080fd5b8063ba2b0ff61461014e578063bab161bf1461017257600080fd5b80631806b5f21461009b5780635d43792c146100b0578063715018a61461010e5780638da5cb5b14610123575b600080fd5b6100ae6100a9366004610687565b610228565b005b3480156100bc57600080fd5b506100e47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561011a57600080fd5b506100ae6103ed565b34801561012f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100e4565b34801561015a57600080fd5b5061016460025481565b604051908152602001610105565b34801561017e57600080fd5b506101a67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610105565b3480156101c757600080fd5b506100ae6101d6366004610782565b610401565b3480156101e757600080fd5b506100ae6101f6366004610782565b610482565b34801561020757600080fd5b506001546100e49073ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f7420506f6c79676f6e5a6b45564d42726964676500000000000000000060648201526084015b60405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff84811691161461039c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f742070696e672053656e6465720000000000000000000000000000000060648201526084016102e9565b808060200190518101906103b091906107a4565b60028190556040519081527f51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d659060200160405180910390a1505050565b6103f5610539565b6103ff60006105ba565b565b610409610539565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b669060200160405180910390a150565b61048a610539565b73ffffffffffffffffffffffffffffffffffffffff811661052d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e9565b610536816105ba565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e9565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461065357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561069c57600080fd5b6106a58461062f565b9250602084013563ffffffff811681146106be57600080fd5b9150604084013567ffffffffffffffff808211156106db57600080fd5b818601915086601f8301126106ef57600080fd5b81358181111561070157610701610658565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074757610747610658565b8160405282815289602084870101111561076057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079457600080fd5b61079d8261062f565b9392505050565b6000602082840312156107b657600080fd5b505191905056fea2646970667358221220f7a6343b3726f685cbf1f60341761a53a0484ae48391492386c86ccaa585ea9964736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106100965760003560e01c8063ba2b0ff611610069578063ced32b0c1161004e578063ced32b0c146101bb578063f2fde38b146101db578063ffa8d9dc146101fb57600080fd5b8063ba2b0ff61461014e578063bab161bf1461017257600080fd5b80631806b5f21461009b5780635d43792c146100b0578063715018a61461010e5780638da5cb5b14610123575b600080fd5b6100ae6100a9366004610687565b610228565b005b3480156100bc57600080fd5b506100e47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561011a57600080fd5b506100ae6103ed565b34801561012f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100e4565b34801561015a57600080fd5b5061016460025481565b604051908152602001610105565b34801561017e57600080fd5b506101a67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610105565b3480156101c757600080fd5b506100ae6101d6366004610782565b610401565b3480156101e757600080fd5b506100ae6101f6366004610782565b610482565b34801561020757600080fd5b506001546100e49073ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f7420506f6c79676f6e5a6b45564d42726964676500000000000000000060648201526084015b60405180910390fd5b60015473ffffffffffffffffffffffffffffffffffffffff84811691161461039c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f50696e6752656365697665723a3a6f6e4d65737361676552656365697665643a60448201527f204e6f742070696e672053656e6465720000000000000000000000000000000060648201526084016102e9565b808060200190518101906103b091906107a4565b60028190556040519081527f51c4f05cea43f3d4604f77fd5a656743088090aa726deb5e3a9f670d8da75d659060200160405180910390a1505050565b6103f5610539565b6103ff60006105ba565b565b610409610539565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f3f61e183128e8b0775a132afd07eb6b4d74e1e66d7de3c5fbb7a6349b1207b669060200160405180910390a150565b61048a610539565b73ffffffffffffffffffffffffffffffffffffffff811661052d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102e9565b610536816105ba565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102e9565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461065357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561069c57600080fd5b6106a58461062f565b9250602084013563ffffffff811681146106be57600080fd5b9150604084013567ffffffffffffffff808211156106db57600080fd5b818601915086601f8301126106ef57600080fd5b81358181111561070157610701610658565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074757610747610658565b8160405282815289602084870101111561076057600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079457600080fd5b61079d8261062f565b9392505050565b6000602082840312156107b657600080fd5b505191905056fea2646970667358221220f7a6343b3726f685cbf1f60341761a53a0484ae48391492386c86ccaa585ea9964736f6c63430008110033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/test/mocksmartcontracts/readme.md b/test/mocksmartcontracts/readme.md new file mode 100644 index 00000000..5629c727 --- /dev/null +++ b/test/mocksmartcontracts/readme.md @@ -0,0 +1,4 @@ +# Contracts + +### PingReceiver +- Original code: [PingReceiver.sol](https://github.com/0xPolygonHermez/code-examples/blob/main/pingPongExample/contracts/PingReceiver.sol) diff --git a/test/mocksmartcontracts/script.sh b/test/mocksmartcontracts/script.sh index 0e01b46a..1517e2dc 100755 --- a/test/mocksmartcontracts/script.sh +++ b/test/mocksmartcontracts/script.sh @@ -10,12 +10,14 @@ gen() { abigen --bin bin/${package}.bin --abi abi/${package}.abi --pkg=${package} --out=${package}/${package}.go } + compilegen() { local package=$1 - docker run --rm --user $(id -u) -v "${dir}:/contracts" ethereum/solc:0.8.20-alpine - "/contracts/${package}.sol" -o "/contracts/${package}" --abi --bin --overwrite --optimize --evm-version shangai + docker run --rm --user $(id -u) -v "${dir}:/contracts" ethereum/solc:0.8.20-alpine - "/contracts/${package}.sol" -o "/contracts/${package}" --abi --bin --overwrite --optimize --evm-version paris abigen --bin ${package}/${package}.bin --abi ${package}/${package}.abi --pkg=${package} --out=${package}/${package}.go } +gen PingReceiver gen polygonzkevmbridge compilegen BridgeMessageReceiver \ No newline at end of file