diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d913d275..061b43e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for `CARTESI_AUTH_PRIVATE_KEY` and `CARTESI_AUTH_PRIVATE_KEY_FILE` - Added `CARTESI_AUTH_KIND` environment variable to select the blockchain authetication method - Added structured logging with slog. Colored logs can now be enabled with `CARTESI_LOG_PRETTY` environment variable. +- Added Rollps end to end test using Echo Dapp ### Changed diff --git a/cmd/cartesi-rollups-cli/root/send/send.go b/cmd/cartesi-rollups-cli/root/send/send.go index d44554eb2..225d47825 100644 --- a/cmd/cartesi-rollups-cli/root/send/send.go +++ b/cmd/cartesi-rollups-cli/root/send/send.go @@ -51,6 +51,7 @@ func init() { } func run(cmd *cobra.Command, args []string) { + payload, err := hexutil.Decode(hexPayload) cobra.CheckErr(err) diff --git a/end-to-end-tests/clinet_util.go b/end-to-end-tests/clinet_util.go new file mode 100644 index 000000000..213066c8a --- /dev/null +++ b/end-to-end-tests/clinet_util.go @@ -0,0 +1,49 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package endtoendtests + +import ( + "context" + + "github.com/cartesi/rollups-node/pkg/addresses" + "github.com/cartesi/rollups-node/pkg/ethutil" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" +) + +func sendInput(ctx context.Context, + blockchainHttpEnpoint string, payload string) (int, error) { + + // Send Input + client, err := ethclient.DialContext(ctx, blockchainHttpEnpoint) + if err != nil { + return 0, err + } + defer client.Close() + + signer, err := ethutil.NewMnemonicSigner(ctx, client, ethutil.FoundryMnemonic, 0) + if err != nil { + return 0, err + } + book := addresses.GetTestBook() + + payloadBytes, _ := hexutil.Decode(payload) + inputIndex, err := ethutil.AddInput(ctx, client, book, signer, payloadBytes) + if err != nil { + return 0, err + } + return inputIndex, nil + +} + +func advanceTime(ctx context.Context, blockchainHttpEnpoint string, timeInSeconds int) error { + client, err := rpc.DialContext(ctx, blockchainHttpEnpoint) + if err != nil { + return err + } + defer client.Close() + return client.CallContext(ctx, nil, "evm_increaseTime", timeInSeconds) + +} diff --git a/end-to-end-tests/config.go b/end-to-end-tests/config.go new file mode 100644 index 000000000..497c4f70b --- /dev/null +++ b/end-to-end-tests/config.go @@ -0,0 +1,85 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +// Package endtoendtests +package endtoendtests + +import ( + "fmt" + "log/slog" + "time" + + "github.com/cartesi/rollups-node/internal/node/config" + "github.com/cartesi/rollups-node/pkg/addresses" + "github.com/cartesi/rollups-node/pkg/ethutil" +) + +const ( + LocalPostgresEndpoint = "postgres://postgres:password@localhost:5432/postgres" + LocalBlockchainID = 31337 + LocalBlockchainHttpEndpoint = "http://localhost:8545" + LocalBlockchainWsEnpoint = "ws://localhost:8545" + LocalApplicationDeploymentBlockNumber = 20 + LocalInputBoxDeploymentBlockNumber = 20 + LocalHttpAddress = "0.0.0.0" + LocalHttpPort = 10000 + LocalBlockTimeout = 60 + LocalFinalityOffset = 1 + LocalEpochDurationInSeconds = 120 +) + +func newLocalNodeConfig() config.NodeConfig { + var nodeConfig config.NodeConfig + + book := addresses.GetTestBook() + + //Log + nodeConfig.LogLevel = slog.LevelInfo + nodeConfig.LogPretty = false + + //Postgres + nodeConfig.PostgresEndpoint = + config.Redacted[string]{Value: LocalPostgresEndpoint} + + //Epoch + nodeConfig.RollupsEpochDuration, _ = + time.ParseDuration(fmt.Sprintf("%ds", LocalEpochDurationInSeconds)) + + //Blochain + nodeConfig.BlockchainID = LocalBlockchainID + nodeConfig.BlockchainHttpEndpoint = + config.Redacted[string]{Value: LocalBlockchainHttpEndpoint} + nodeConfig.BlockchainWsEndpoint = + config.Redacted[string]{Value: LocalBlockchainWsEnpoint} + nodeConfig.BlockchainIsLegacy = false + nodeConfig.BlockchainFinalityOffset = LocalFinalityOffset + nodeConfig.BlockchainBlockTimeout = LocalBlockTimeout + + //Contracts + nodeConfig.ContractsHistoryAddress = book.HistoryAddress.Hex() + nodeConfig.ContractsAuthorityAddress = book.AuthorityAddress.Hex() + nodeConfig.ContractsApplicationAddress = book.CartesiDApp.Hex() + nodeConfig.ContractsApplicationDeploymentBlockNumber = LocalApplicationDeploymentBlockNumber + nodeConfig.ContractsInputBoxAddress = book.InputBox.Hex() + nodeConfig.ContractsInputBoxDeploymentBlockNumber = LocalInputBoxDeploymentBlockNumber + + //HTTP endpoint + nodeConfig.HttpAddress = LocalHttpAddress + nodeConfig.HttpPort = LocalHttpPort + + //Features + nodeConfig.FeatureHostMode = false + nodeConfig.FeatureDisableClaimer = false + nodeConfig.FeatureDisableMachineHashCheck = true + + //Experimental + nodeConfig.ExperimentalSunodoValidatorEnabled = false + + //Auth + nodeConfig.Auth = config.AuthMnemonic{ + Mnemonic: config.Redacted[string]{Value: ethutil.FoundryMnemonic}, + AccountIndex: config.Redacted[int]{Value: 0}, + } + + return nodeConfig +} diff --git a/end-to-end-tests/echo_test.go b/end-to-end-tests/echo_test.go new file mode 100644 index 000000000..d8452b025 --- /dev/null +++ b/end-to-end-tests/echo_test.go @@ -0,0 +1,246 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +//go:build endtoendtests +// +build endtoendtests + +package endtoendtests + +import ( + "context" + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/Khan/genqlient/graphql" + "github.com/cartesi/rollups-node/internal/deps" + "github.com/cartesi/rollups-node/internal/machine" + "github.com/cartesi/rollups-node/internal/node" + "github.com/cartesi/rollups-node/pkg/readerclient" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + payload = "0xdeadbeef" + maxReadInputAttempts = 10 + defaulTxDatabaseFile = "default_tx_database" +) + +type EchoInputTestSuite struct { + suite.Suite + containers *deps.DepsContainers + cancel context.CancelFunc + tempDir string + supervisorErr chan error +} + +func (s *EchoInputTestSuite) SetupSuite() { + + // Clear default_tx_database + cwd, err := os.Getwd() + require.NoError(s.T(), err) + + _ = os.Remove(filepath.Join(cwd, defaulTxDatabaseFile)) + + // Create machine snapshot + tempDir, err := ioutil.TempDir("", "machine-snapshot") + assert.NoError(s.T(), err) + machine.Save("cartesi/rollups-node-snapshot:devel", tempDir, "test-echo-app") + + // Run deps + ctx := context.Background() + var depsConfig = deps.NewDefaultDepsConfig() + depsContainers, err := deps.Run(ctx, *depsConfig) + assert.NoError(s.T(), err) + + // Wait a little for Dependencies to be actually ready + time.Sleep(2 * time.Second) + + // Run Node Service + nodeConfig := newLocalNodeConfig() + + nodeConfig.SnapshotDir = tempDir + + ctx, cancel := context.WithCancel(ctx) + supervisor, err := node.Setup(ctx, nodeConfig) + require.NoError(s.T(), err) + + ready := make(chan struct{}, 1) + supervisorErr := make(chan error, 1) + go func() { + err := supervisor.Start(ctx, ready) + if err != nil { + supervisorErr <- err + } + }() + + select { + case err := <-supervisorErr: + require.NoError(s.T(), err) + case <-ready: + break + } + + // Configure Suite for tear down + s.containers = depsContainers + s.tempDir = tempDir + s.cancel = cancel + s.supervisorErr = supervisorErr + +} + +func (s *EchoInputTestSuite) TearDownSuite() { + + // Stop Node services + s.cancel() + + // Remove machine snpshot + os.RemoveAll(s.tempDir) + + // Terminate deps + ctx := context.Background() + err := deps.Terminate(ctx, s.containers) + require.NoError(s.T(), err) + + // Clear default_tx_database + cwd, err := os.Getwd() + require.NoError(s.T(), err) + + _ = os.Remove(filepath.Join(cwd, defaulTxDatabaseFile)) + +} + +func (s *EchoInputTestSuite) SetupTest() { + +} + +func (s *EchoInputTestSuite) TestSendInput() { + + ctx := context.Background() + + inputIndex, err := sendInput(ctx, LocalBlockchainHttpEndpoint, payload) + require.NoError(s.T(), err) + + // Check input was correctly added to the blockchain + require.EqualValues(s.T(), 0, inputIndex) + + require.NoError(s.T(), advanceTime(ctx, LocalBlockchainHttpEndpoint), 120) + + // Get Input with vouchers and proofs + graphQlClient := graphql.NewClient("http://localhost:10000/graphql", nil) + getInputChan := make(chan *readerclient.Input, 1) + getInputErr := make(chan struct{}, 1) + + go func() { + var resp *readerclient.Input + attempts := 0 + for ; attempts < maxReadInputAttempts; attempts++ { + time.Sleep(2 * time.Second) + resp, err = readerclient.GetInput(ctx, graphQlClient, inputIndex) + if err == nil && resp.Status == "ACCEPTED" && resp.Vouchers != nil && resp.Vouchers[0].Proof != nil { + break + } + } + if attempts == maxReadInputAttempts { + getInputErr <- struct{}{} + return + } + getInputChan <- resp + }() + + select { + case input := <-getInputChan: + + //Check Input Fields + + require.EqualValues(s.T(), 0, input.Index) + require.EqualValues(s.T(), "ACCEPTED", input.Status) + require.EqualValues(s.T(), payload, hexutil.Encode(input.Payload)) + + //Check Notices + + require.NotNil(s.T(), input.Notices) + require.EqualValues(s.T(), 1, len(input.Notices)) + require.EqualValues(s.T(), 0, input.Notices[0].Index) + require.EqualValues(s.T(), 0, input.Notices[0].InputIndex) + require.EqualValues(s.T(), payload, hexutil.Encode(input.Notices[0].Payload)) + + expectedProof, err := readExpectedProof("expected_notice_proof.json") + require.NoError(s.T(), err) + + checkProof(s, expectedProof, input.Notices[0].Proof) + + // Check Vouchers + + require.NotNil(s.T(), input.Vouchers) + require.EqualValues(s.T(), 1, len(input.Vouchers)) + require.EqualValues(s.T(), 0, input.Vouchers[0].Index) + require.EqualValues(s.T(), 0, input.Vouchers[0].InputIndex) + require.EqualValues(s.T(), "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", strings.ToLower(input.Vouchers[0].Destination.Hex())) + require.EqualValues(s.T(), payload, hexutil.Encode(input.Vouchers[0].Payload)) + + expectedProof, err = readExpectedProof("expected_voucher_proof.json") + require.NoError(s.T(), err) + + checkProof(s, expectedProof, input.Vouchers[0].Proof) + + // Check Reports + + require.NotNil(s.T(), input.Reports) + require.EqualValues(s.T(), 1, len(input.Reports)) + require.EqualValues(s.T(), 0, input.Reports[0].Index) + require.EqualValues(s.T(), 0, input.Reports[0].InputIndex) + require.EqualValues(s.T(), payload, hexutil.Encode(input.Reports[0].Payload)) + + break + case err = <-s.supervisorErr: + require.NoError(s.T(), err) + break + case <-getInputErr: + require.FailNow(s.T(), "Could not retrieve Voucher with Proof 0") + } + +} + +func readExpectedProof(proofFileName string) (*readerclient.Proof, error) { + cwd, err := os.Getwd() + if err != nil { + return nil, err + } + + expectedProofJsonBytes, err := ioutil.ReadFile(filepath.Join(cwd, "resources", "echo_input", proofFileName)) + if err != nil { + return nil, err + } + + var proof readerclient.Proof + err = json.Unmarshal(expectedProofJsonBytes, &proof) + if err != nil { + return nil, err + } + + return &proof, nil + +} + +func checkProof(s *EchoInputTestSuite, expectedProof *readerclient.Proof, proof *readerclient.Proof) { + + // Machine state hashes are different between runs + proof.MachineStateHash = nil + expectedProof.MachineStateHash = nil + + require.EqualValues(s.T(), expectedProof, proof) + +} + +func TestEchoInput(t *testing.T) { + + suite.Run(t, new(EchoInputTestSuite)) +} diff --git a/end-to-end-tests/resources/echo_input/expected_notice_proof.json b/end-to-end-tests/resources/echo_input/expected_notice_proof.json new file mode 100644 index 000000000..26cbd01c8 --- /dev/null +++ b/end-to-end-tests/resources/echo_input/expected_notice_proof.json @@ -0,0 +1,63 @@ + + +{ + "inputIndexWithinEpoch": 0, + "outputIndexWithinInput": 0, + "outputHashesRootHash": "0x660c2d35b0a43d8179792345211d0eab28d88f47fafadd8334b80196cad41ded", + "vouchersEpochRootHash": "0x7d0423c65ec1c03578e3c6182956c51ae617b372c504cc9d272e71a2a3385dcb", + "noticesEpochRootHash": "0x63a367741b1feb9c2dc64bda8ac4a083ebbe5fd1f7bb4746e94597c988f30197", + "machineStateHash": "0x", + "outputHashInOutputHashesSiblings": [ + "0xae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a23", + "0x3fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f", + "0x17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9", + "0xc37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e6", + "0x8e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e309", + "0x30b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90", + "0xcd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efe", + "0xd8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0", + "0xc9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e61", + "0x63e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb", + "0x91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b7", + "0x2122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046", + "0xf7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec51", + "0x7a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca89", + "0x2b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e1524", + "0x99af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f" + ], + "outputHashesInEpochSiblings": [ + "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", + "0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d", + "0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d", + "0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8", + "0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da", + "0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5", + "0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7", + "0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead", + "0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10", + "0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82", + "0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516", + "0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c", + "0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e", + "0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab", + "0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862", + "0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10", + "0x776a31db34a1a0a7caaf862cffdfff1789297ffadc380bd3d39281d340abd3ad", + "0xe2e7610b87a5fdf3a72ebe271287d923ab990eefac64b6e59d79f8b7e08c46e3", + "0x504364a5c6858bf98fff714ab5be9de19ed31a976860efbd0e772a2efe23e2e0", + "0x4f05f4acb83f5b65168d9fef89d56d4d77b8944015e6b1eed81b0238e2d0dba3", + "0x44a6d974c75b07423e1d6d33f481916fdd45830aea11b6347e700cd8b9f0767c", + "0xedf260291f734ddac396a956127dde4c34c0cfb8d8052f88ac139658ccf2d507", + "0x6075c657a105351e7f0fce53bc320113324a522e8fd52dc878c762551e01a46e", + "0x6ca6a3f763a9395f7da16014725ca7ee17e4815c0ff8119bf33f273dee11833b", + "0x1c25ef10ffeb3c7d08aa707d17286e0b0d3cbcb50f1bd3b6523b63ba3b52dd0f", + "0xfffc43bd08273ccf135fd3cacbeef055418e09eb728d727c4d5d5c556cdea7e3", + "0xc5ab8111456b1f28f3c7a0a604b4553ce905cb019c463ee159137af83c350b22", + "0x0ff273fcbf4ae0f2bd88d6cf319ff4004f8d7dca70d4ced4e74d2c74139739e6", + "0x7fa06ba11241ddd5efdc65d4e39c9f6991b74fd4b81b62230808216c876f827c", + "0x7e275adf313a996c7e2950cac67caba02a5ff925ebf9906b58949f3e77aec5b9", + "0x8f6162fa308d2b3a15dc33cffac85f13ab349173121645aedf00f471663108be", + "0x78ccaaab73373552f207a63599de54d7d8d0c1805f86ce7da15818d09f4cff62" + ], + "context": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/end-to-end-tests/resources/echo_input/expected_voucher_proof.json b/end-to-end-tests/resources/echo_input/expected_voucher_proof.json new file mode 100644 index 000000000..37d2bd50b --- /dev/null +++ b/end-to-end-tests/resources/echo_input/expected_voucher_proof.json @@ -0,0 +1,61 @@ +{ + "inputIndexWithinEpoch": 0, + "outputIndexWithinInput": 0, + "outputHashesRootHash": "0xae4004e727f8d55ebd8171010f56e467fe19042f1f84304a379bac9a7d2d8215", + "vouchersEpochRootHash": "0x7d0423c65ec1c03578e3c6182956c51ae617b372c504cc9d272e71a2a3385dcb", + "noticesEpochRootHash": "0x63a367741b1feb9c2dc64bda8ac4a083ebbe5fd1f7bb4746e94597c988f30197", + "machineStateHash": "0x", + "outputHashInOutputHashesSiblings": [ + "0xae39ce8537aca75e2eff3e38c98011dfe934e700a0967732fc07b430dd656a23", + "0x3fc9a15f5b4869c872f81087bb6104b7d63e6f9ab47f2c43f3535eae7172aa7f", + "0x17d2dd614cddaa4d879276b11e0672c9560033d3e8453a1d045339d34ba601b9", + "0xc37b8b13ca95166fb7af16988a70fcc90f38bf9126fd833da710a47fb37a55e6", + "0x8e7a427fa943d9966b389f4f257173676090c6e95f43e2cb6d65f8758111e309", + "0x30b0b9deb73e155c59740bacf14a6ff04b64bb8e201a506409c3fe381ca4ea90", + "0xcd5deac729d0fdaccc441d09d7325f41586ba13c801b7eccae0f95d8f3933efe", + "0xd8b96e5b7f6f459e9cb6a2f41bf276c7b85c10cd4662c04cbbb365434726c0a0", + "0xc9695393027fb106a8153109ac516288a88b28a93817899460d6310b71cf1e61", + "0x63e8806fa0d4b197a259e8c3ac28864268159d0ac85f8581ca28fa7d2c0c03eb", + "0x91e3eee5ca7a3da2b3053c9770db73599fb149f620e3facef95e947c0ee860b7", + "0x2122e31e4bbd2b7c783d79cc30f60c6238651da7f0726f767d22747264fdb046", + "0xf7549f26cc70ed5e18baeb6c81bb0625cb95bb4019aeecd40774ee87ae29ec51", + "0x7a71f6ee264c5d761379b3d7d617ca83677374b49d10aec50505ac087408ca89", + "0x2b573c267a712a52e1d06421fe276a03efb1889f337201110fdc32a81f8e1524", + "0x99af665835aabfdc6740c7e2c3791a31c3cdc9f5ab962f681b12fc092816a62f" + ], + "outputHashesInEpochSiblings": [ + "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", + "0x633dc4d7da7256660a892f8f1604a44b5432649cc8ec5cb3ced4c4e6ac94dd1d", + "0x890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d", + "0x3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8", + "0xecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da", + "0xdefff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5", + "0x617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7", + "0x292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead", + "0xe1cea92ed99acdcb045a6726b2f87107e8a61620a232cf4d7d5b5766b3952e10", + "0x7ad66c0a68c72cb89e4fb4303841966e4062a76ab97451e3b9fb526a5ceb7f82", + "0xe026cc5a4aed3c22a58cbd3d2ac754c9352c5436f638042dca99034e83636516", + "0x3d04cffd8b46a874edf5cfae63077de85f849a660426697b06a829c70dd1409c", + "0xad676aa337a485e4728a0b240d92b3ef7b3c372d06d189322bfd5f61f1e7203e", + "0xa2fca4a49658f9fab7aa63289c91b7c7b6c832a6d0e69334ff5b0a3483d09dab", + "0x4ebfd9cd7bca2505f7bef59cc1c12ecc708fff26ae4af19abe852afe9e20c862", + "0x2def10d13dd169f550f578bda343d9717a138562e0093b380a1120789d53cf10", + "0x776a31db34a1a0a7caaf862cffdfff1789297ffadc380bd3d39281d340abd3ad", + "0xe2e7610b87a5fdf3a72ebe271287d923ab990eefac64b6e59d79f8b7e08c46e3", + "0x504364a5c6858bf98fff714ab5be9de19ed31a976860efbd0e772a2efe23e2e0", + "0x4f05f4acb83f5b65168d9fef89d56d4d77b8944015e6b1eed81b0238e2d0dba3", + "0x44a6d974c75b07423e1d6d33f481916fdd45830aea11b6347e700cd8b9f0767c", + "0xedf260291f734ddac396a956127dde4c34c0cfb8d8052f88ac139658ccf2d507", + "0x6075c657a105351e7f0fce53bc320113324a522e8fd52dc878c762551e01a46e", + "0x6ca6a3f763a9395f7da16014725ca7ee17e4815c0ff8119bf33f273dee11833b", + "0x1c25ef10ffeb3c7d08aa707d17286e0b0d3cbcb50f1bd3b6523b63ba3b52dd0f", + "0xfffc43bd08273ccf135fd3cacbeef055418e09eb728d727c4d5d5c556cdea7e3", + "0xc5ab8111456b1f28f3c7a0a604b4553ce905cb019c463ee159137af83c350b22", + "0x0ff273fcbf4ae0f2bd88d6cf319ff4004f8d7dca70d4ced4e74d2c74139739e6", + "0x7fa06ba11241ddd5efdc65d4e39c9f6991b74fd4b81b62230808216c876f827c", + "0x7e275adf313a996c7e2950cac67caba02a5ff925ebf9906b58949f3e77aec5b9", + "0x8f6162fa308d2b3a15dc33cffac85f13ab349173121645aedf00f471663108be", + "0x78ccaaab73373552f207a63599de54d7d8d0c1805f86ce7da15818d09f4cff62" + ], + "context": "0x0000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/internal/deps/deps.go b/internal/deps/deps.go index cc8220332..a3069a305 100644 --- a/internal/deps/deps.go +++ b/internal/deps/deps.go @@ -62,12 +62,19 @@ func (d debugLogging) Printf(format string, v ...interface{}) { } func createHook(containerName string, - waitGroup *sync.WaitGroup) []testcontainers.ContainerLifecycleHooks { + finishedWaitGroup *sync.WaitGroup, + startedWaitGroup *sync.WaitGroup) []testcontainers.ContainerLifecycleHooks { return []testcontainers.ContainerLifecycleHooks{ { + PostStarts: []testcontainers.ContainerHook{ + func(ctx context.Context, container testcontainers.Container) error { + startedWaitGroup.Done() + return nil + }, + }, PostTerminates: []testcontainers.ContainerHook{ func(ctx context.Context, container testcontainers.Container) error { - waitGroup.Done() + finishedWaitGroup.Done() return nil }, }, @@ -80,14 +87,17 @@ func createHook(containerName string, // The returned DepContainers struct can be used to gracefully // terminate the containers using the Terminate method func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { + debugLogger := debugLogging{} - var waitGroup sync.WaitGroup + var finishedWaitGroup sync.WaitGroup + var startedWaitGroup sync.WaitGroup // wait strategy copied from testcontainers docs postgresWaitStrategy := wait.ForLog("database system is ready to accept connections"). WithOccurrence(numPostgresCheckReadyAttempts). WithPollInterval(pollInterval) + startedWaitGroup.Add(1) postgresReq := testcontainers.ContainerRequest{ Image: depsConfig.PostgresDockerImage, ExposedPorts: []string{strings.Join([]string{ @@ -97,7 +107,8 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { Env: map[string]string{ "POSTGRES_PASSWORD": depsConfig.PostgresPassword, }, - LifecycleHooks: createHook("rollups-node-dep-postgres", &waitGroup), + LifecycleHooks: createHook("rollups-node-dep-postgres", + &finishedWaitGroup, &startedWaitGroup), } postgres, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -109,8 +120,9 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { if err != nil { return nil, err } - waitGroup.Add(1) + finishedWaitGroup.Add(1) + startedWaitGroup.Add(1) devNetReq := testcontainers.ContainerRequest{ Image: depsConfig.DevnetDockerImage, ExposedPorts: []string{strings.Join([]string{depsConfig.DevnetPort, ":8545/tcp"}, "")}, @@ -119,7 +131,8 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { Env: map[string]string{ "ANVIL_IP_ADDR": "0.0.0.0", }, - LifecycleHooks: createHook("rollups-node-dep-devnet", &waitGroup), + LifecycleHooks: createHook("rollups-node-dep-devnet", + &finishedWaitGroup, &startedWaitGroup), } devnet, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ @@ -131,11 +144,12 @@ func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { return nil, err } - waitGroup.Add(1) + finishedWaitGroup.Add(1) containers := []testcontainers.Container{postgres, devnet} - return &DepsContainers{containers, &waitGroup}, nil + startedWaitGroup.Wait() + return &DepsContainers{containers, &finishedWaitGroup}, nil } // Terminate terminates all dependencies containers. This method waits for all the containers diff --git a/pkg/addresses/addresses.go b/pkg/addresses/addresses.go index 8a2c490ff..1bac01d16 100644 --- a/pkg/addresses/addresses.go +++ b/pkg/addresses/addresses.go @@ -29,6 +29,8 @@ type Book struct { EtherPortal common.Address InputBox common.Address CartesiDApp common.Address + HistoryAddress common.Address + AuthorityAddress common.Address } // Get the addresses for the test environment. @@ -45,6 +47,8 @@ func GetTestBook() *Book { EtherPortal: common.HexToAddress("0xFfdbe43d4c855BF7e0f105c400A50857f53AB044"), InputBox: common.HexToAddress("0x59b22D57D4f067708AB0c00552767405926dc768"), CartesiDApp: common.HexToAddress("0x7FFdf694A877067DE99462A7243b29972D19cf72"), + HistoryAddress: common.HexToAddress("0x325272217ae6815b494bF38cED004c5Eb8a7CdA7"), + AuthorityAddress: common.HexToAddress("0x58c93F83fb3304730C95aad2E360cdb88b782010"), } }