diff --git a/pkg/testsuite/mock/blockissuer.go b/pkg/testsuite/mock/blockissuer.go index d8e1498f0..835dd9339 100644 --- a/pkg/testsuite/mock/blockissuer.go +++ b/pkg/testsuite/mock/blockissuer.go @@ -94,15 +94,21 @@ func (i *BlockIssuer) Address() iotago.Address { func (i *BlockIssuer) CreateValidationBlock(ctx context.Context, alias string, node *Node, opts ...options.Option[ValidationBlockParams]) (*blocks.Block, error) { blockParams := options.Apply(NewValidationBlockParams(), opts) + blockIssuanceInfo, err := i.Client.BlockIssuance(ctx) + require.NoError(i.Testing, err) + if blockParams.BlockHeader.IssuingTime == nil { issuingTime := time.Now().UTC() + if issuingTime.Before(blockIssuanceInfo.LatestParentBlockIssuingTime) { + issuingTime = blockIssuanceInfo.LatestParentBlockIssuingTime.Add(time.Nanosecond) + } + blockParams.BlockHeader.IssuingTime = &issuingTime } apiForBlock := i.retrieveAPI(blockParams.BlockHeader) protoParams := apiForBlock.ProtocolParameters() - blockIssuanceInfo, err := i.Client.BlockIssuance(ctx) - require.NoError(i.Testing, err) + if blockParams.BlockHeader.SlotCommitment == nil { commitment := blockIssuanceInfo.LatestCommitment blockSlot := apiForBlock.TimeProvider().SlotFromTime(*blockParams.BlockHeader.IssuingTime) @@ -133,7 +139,7 @@ func (i *BlockIssuer) CreateValidationBlock(ctx context.Context, alias string, n } if blockParams.BlockHeader.References == nil { - blockParams.BlockHeader.References = referencesFromBlockIssuanceResponse(i.latestBlockIssuanceResponse(ctx)) + blockParams.BlockHeader.References = referencesFromBlockIssuanceResponse(blockIssuanceInfo) } err = i.setDefaultBlockParams(ctx, blockParams.BlockHeader) @@ -244,6 +250,10 @@ func (i *BlockIssuer) CreateBasicBlock(ctx context.Context, alias string, opts . // set the issuing time last to ensure the timestamp is greater than that of the parents selected. if blockParams.BlockHeader.IssuingTime == nil { issuingTime := time.Now().UTC() + if issuingTime.Before(blockIssuanceInfo.LatestParentBlockIssuingTime) { + issuingTime = blockIssuanceInfo.LatestParentBlockIssuingTime.Add(time.Nanosecond) + } + blockParams.BlockHeader.IssuingTime = &issuingTime } blockBuilder.IssuingTime(*blockParams.BlockHeader.IssuingTime) diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml index 2864be3a3..205037762 100644 --- a/tools/docker-network/docker-compose.yml +++ b/tools/docker-network/docker-compose.yml @@ -202,7 +202,7 @@ services: prometheus: image: prom/prometheus:latest stop_grace_period: 1m - restart: no + restart: unless-stopped depends_on: node-1-validator: condition: service_started @@ -219,7 +219,7 @@ services: grafana: image: grafana/grafana:9.5.6 - restart: no + restart: unless-stopped networks: - iota-core ports: @@ -259,7 +259,7 @@ services: inx-mqtt: image: iotaledger/inx-mqtt:2.0-alpha stop_grace_period: 1m - restart: no + restart: unless-stopped depends_on: node-1-validator: condition: service_healthy @@ -370,7 +370,7 @@ services: inx-validator-4: image: iotaledger/inx-validator:1.0-alpha stop_grace_period: 1m - restart: unless-stopped + restart: no depends_on: node-4-validator: condition: service_started diff --git a/tools/docker-network/tests/accounttransition_test.go b/tools/docker-network/tests/accounttransition_test.go index 54f72324b..e7b638c8c 100644 --- a/tools/docker-network/tests/accounttransition_test.go +++ b/tools/docker-network/tests/accounttransition_test.go @@ -32,7 +32,7 @@ func Test_AccountTransitions(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) diff --git a/tools/docker-network/tests/api_core_test.go b/tools/docker-network/tests/api_core_test.go index 838f5d5b4..5c064ce61 100644 --- a/tools/docker-network/tests/api_core_test.go +++ b/tools/docker-network/tests/api_core_test.go @@ -272,7 +272,7 @@ func Test_ValidatorsAPI(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -311,7 +311,7 @@ func Test_ValidatorsAPI(t *testing.T) { // issue candidacy payload in the next epoch (currentEpoch + 1), in order to issue it before epochNearingThreshold d.AwaitCommitment(clt.CommittedAPI().TimeProvider().EpochEnd(currentEpoch)) - blkID := d.IssueCandidacyPayloadFromAccount(wallet) + blkID := d.IssueCandidacyPayloadFromAccount(ctx, wallet) fmt.Println("Candidacy payload:", blkID.ToHex(), blkID.Slot()) d.AwaitCommitment(blkID.Slot()) }() @@ -343,7 +343,7 @@ func Test_CoreAPI(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -357,21 +357,21 @@ func Test_CoreAPI(t *testing.T) { tests := []struct { name string - testFunc func(t *testing.T, nodeAlias string) + testFunc func(t *testing.T, node *dockertestframework.Node, client mock.Client) }{ { name: "Test_Info", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Client(nodeAlias).Info(context.Background()) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, err := client.Info(context.Background()) require.NoError(t, err) require.NotNil(t, resp) }, }, { name: "Test_BlockByBlockID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { - respBlock, err := d.Client(nodeAlias).BlockByBlockID(context.Background(), block.MustID()) + respBlock, err := client.BlockByBlockID(context.Background(), block.MustID()) require.NoError(t, err) require.NotNil(t, respBlock) require.Equal(t, block.MustID(), respBlock.MustID(), "BlockID of retrieved block does not match: %s != %s", block.MustID(), respBlock.MustID()) @@ -380,9 +380,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_BlockMetadataByBlockID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { - resp, err := d.Client(nodeAlias).BlockMetadataByBlockID(context.Background(), block.MustID()) + resp, err := client.BlockMetadataByBlockID(context.Background(), block.MustID()) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, block.MustID(), resp.BlockID, "BlockID of retrieved block does not match: %s != %s", block.MustID(), resp.BlockID) @@ -390,7 +390,7 @@ func Test_CoreAPI(t *testing.T) { }) assetsPerSlot.forEachReattachment(t, func(t *testing.T, blockID iotago.BlockID) { - resp, err := d.Client(nodeAlias).BlockMetadataByBlockID(context.Background(), blockID) + resp, err := client.BlockMetadataByBlockID(context.Background(), blockID) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, blockID, resp.BlockID, "BlockID of retrieved block does not match: %s != %s", blockID, resp.BlockID) @@ -400,9 +400,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_BlockWithMetadata", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { - resp, err := d.Client(nodeAlias).BlockWithMetadataByBlockID(context.Background(), block.MustID()) + resp, err := client.BlockWithMetadataByBlockID(context.Background(), block.MustID()) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, block.MustID(), resp.Block.MustID(), "BlockID of retrieved block does not match: %s != %s", block.MustID(), resp.Block.MustID()) @@ -412,8 +412,8 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_BlockIssuance", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Client(nodeAlias).BlockIssuance(context.Background()) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, err := client.BlockIssuance(context.Background()) require.NoError(t, err) require.NotNil(t, resp) @@ -422,79 +422,79 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_CommitmentBySlot", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachSlot(t, func(t *testing.T, slot iotago.SlotIndex, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentBySlot(context.Background(), slot) + resp, err := client.CommitmentBySlot(context.Background(), slot) require.NoError(t, err) require.NotNil(t, resp) - commitmentsPerNode[nodeAlias] = resp.MustID() + commitmentsPerNode[node.Name] = resp.MustID() }) }, }, { name: "Test_CommitmentByID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentByID(context.Background(), commitmentsPerNode[nodeAlias]) + resp, err := client.CommitmentByID(context.Background(), commitmentsPerNode[node.Name]) require.NoError(t, err) require.NotNil(t, resp) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.MustID(), "Commitment does not match commitment got for the same slot from the same node: %s != %s", commitmentsPerNode[nodeAlias], resp.MustID()) + require.Equal(t, commitmentsPerNode[node.Name], resp.MustID(), "Commitment does not match commitment got for the same slot from the same node: %s != %s", commitmentsPerNode[node.Name], resp.MustID()) }) }, }, { name: "Test_CommitmentUTXOChangesByID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesByID(context.Background(), commitmentsPerNode[nodeAlias]) + resp, err := client.CommitmentUTXOChangesByID(context.Background(), commitmentsPerNode[node.Name]) require.NoError(t, err) require.NotNil(t, resp) - assetsPerSlot.assertUTXOOutputIDsInSlot(t, commitmentsPerNode[nodeAlias].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) + assetsPerSlot.assertUTXOOutputIDsInSlot(t, commitmentsPerNode[node.Name].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) + require.Equal(t, commitmentsPerNode[node.Name], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[node.Name], resp.CommitmentID) }) }, }, { "Test_CommitmentUTXOChangesFullByID", - func(t *testing.T, nodeAlias string) { + func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesFullByID(context.Background(), commitmentsPerNode[nodeAlias]) + resp, err := client.CommitmentUTXOChangesFullByID(context.Background(), commitmentsPerNode[node.Name]) require.NoError(t, err) require.NotNil(t, resp) - assetsPerSlot.assertUTXOOutputsInSlot(t, commitmentsPerNode[nodeAlias].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) + assetsPerSlot.assertUTXOOutputsInSlot(t, commitmentsPerNode[node.Name].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) + require.Equal(t, commitmentsPerNode[node.Name], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[node.Name], resp.CommitmentID) }) }, }, { name: "Test_CommitmentUTXOChangesBySlot", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesBySlot(context.Background(), commitmentsPerNode[nodeAlias].Slot()) + resp, err := client.CommitmentUTXOChangesBySlot(context.Background(), commitmentsPerNode[node.Name].Slot()) require.NoError(t, err) require.NotNil(t, resp) - assetsPerSlot.assertUTXOOutputIDsInSlot(t, commitmentsPerNode[nodeAlias].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) + assetsPerSlot.assertUTXOOutputIDsInSlot(t, commitmentsPerNode[node.Name].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) + require.Equal(t, commitmentsPerNode[node.Name], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[node.Name], resp.CommitmentID) }) }, }, { name: "Test_CommitmentUTXOChangesFullBySlot", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesFullBySlot(context.Background(), commitmentsPerNode[nodeAlias].Slot()) + resp, err := client.CommitmentUTXOChangesFullBySlot(context.Background(), commitmentsPerNode[node.Name].Slot()) require.NoError(t, err) require.NotNil(t, resp) - assetsPerSlot.assertUTXOOutputsInSlot(t, commitmentsPerNode[nodeAlias].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) + assetsPerSlot.assertUTXOOutputsInSlot(t, commitmentsPerNode[node.Name].Slot(), resp.CreatedOutputs, resp.ConsumedOutputs) + require.Equal(t, commitmentsPerNode[node.Name], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[node.Name], resp.CommitmentID) }) }, }, { name: "Test_OutputByID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { - resp, err := d.Client(nodeAlias).OutputByID(context.Background(), outputID) + resp, err := client.OutputByID(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, output, resp, "Output created is different than retrieved from the API: %s != %s", output, resp) @@ -503,9 +503,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_OutputMetadata", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { - resp, err := d.Client(nodeAlias).OutputMetadataByID(context.Background(), outputID) + resp, err := client.OutputMetadataByID(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, outputID, resp.OutputID, "OutputID of retrieved output does not match: %s != %s", outputID, resp.OutputID) @@ -515,9 +515,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_OutputWithMetadata", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { - out, outMetadata, err := d.Client(nodeAlias).OutputWithMetadataByID(context.Background(), outputID) + out, outMetadata, err := client.OutputWithMetadataByID(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, outMetadata) require.NotNil(t, out) @@ -529,10 +529,10 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_TransactionByID", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { txID := transaction.Transaction.MustID() - resp, err := d.Client(nodeAlias).TransactionByID(context.Background(), txID) + resp, err := client.TransactionByID(context.Background(), txID) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, txID, resp.MustID()) @@ -541,9 +541,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_TransactionsIncludedBlock", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { - resp, err := d.Client(nodeAlias).TransactionIncludedBlock(context.Background(), transaction.Transaction.MustID()) + resp, err := client.TransactionIncludedBlock(context.Background(), transaction.Transaction.MustID()) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, firstAttachmentID, resp.MustID()) @@ -552,9 +552,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_TransactionsIncludedBlockMetadata", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { - resp, err := d.Client(nodeAlias).TransactionIncludedBlockMetadata(context.Background(), transaction.Transaction.MustID()) + resp, err := client.TransactionIncludedBlockMetadata(context.Background(), transaction.Transaction.MustID()) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, api.BlockStateFinalized, resp.BlockState) @@ -564,9 +564,9 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_TransactionsMetadata", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { - resp, err := d.Client(nodeAlias).TransactionMetadata(context.Background(), transaction.Transaction.MustID()) + resp, err := client.TransactionMetadata(context.Background(), transaction.Transaction.MustID()) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, api.TransactionStateFinalized, resp.TransactionState) @@ -576,52 +576,50 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_Congestion", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachAccountAddress(t, func( t *testing.T, accountAddress *iotago.AccountAddress, commitmentPerNode map[string]iotago.CommitmentID, bicPerNoode map[string]iotago.BlockIssuanceCredits, ) { - resp, err := d.Client(nodeAlias).Congestion(context.Background(), accountAddress, 0) + resp, err := client.Congestion(context.Background(), accountAddress, 0) require.NoError(t, err) require.NotNil(t, resp) // node allows to get account only for the slot newer than lastCommittedSlot - MCA, we need fresh commitment - infoRes, err := d.Client(nodeAlias).Info(context.Background()) + infoRes, err := client.Info(context.Background()) require.NoError(t, err) - commitment, err := d.Client(nodeAlias).CommitmentBySlot(context.Background(), infoRes.Status.LatestCommitmentID.Slot()) + commitment, err := client.CommitmentBySlot(context.Background(), infoRes.Status.LatestCommitmentID.Slot()) require.NoError(t, err) - resp, err = d.Client(nodeAlias).Congestion(context.Background(), accountAddress, 0, commitment.MustID()) + resp, err = client.Congestion(context.Background(), accountAddress, 0, commitment.MustID()) require.NoError(t, err) require.NotNil(t, resp) // later we check if all nodes have returned the same BIC value for this account - bicPerNoode[nodeAlias] = resp.BlockIssuanceCredits + bicPerNoode[node.Name] = resp.BlockIssuanceCredits }) }, }, { name: "Test_Validators", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { pageSize := uint64(3) - resp, err := d.Client(nodeAlias).Validators(context.Background(), pageSize) + resp, err := client.Validators(context.Background(), pageSize) require.NoError(t, err) require.NotNil(t, resp) - //TODO after finishing validators endpoint and including registered validators - //require.Equal(t, int(pageSize), len(resp.Validators), "There should be exactly %d validators returned on the first page", pageSize) + require.Equal(t, int(pageSize), len(resp.Validators), "There should be exactly %d validators returned on the first page", pageSize) - resp, err = d.Client(nodeAlias).Validators(context.Background(), pageSize, resp.Cursor) + resp, err = client.Validators(context.Background(), pageSize, resp.Cursor) require.NoError(t, err) require.NotNil(t, resp) - //TODO after finishing validators endpoint and including registered validators - //require.Equal(t, 1, len(resp.Validators), "There should be only one validator returned on the last page") + require.Equal(t, 1, len(resp.Validators), "There should be only one validator returned on the last page") }, }, { name: "Test_ValidatorsAll", - testFunc: func(t *testing.T, nodeAlias string) { - resp, all, err := d.Client(nodeAlias).ValidatorsAll(context.Background()) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, all, err := client.ValidatorsAll(context.Background()) require.NoError(t, err) require.True(t, all) require.Equal(t, 4, len(resp.Validators)) @@ -629,13 +627,13 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_Rewards", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { if output.Type() != iotago.OutputDelegation { return } - resp, err := d.Client(nodeAlias).Rewards(context.Background(), outputID) + resp, err := client.Rewards(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, resp) // rewards are zero, because we do not wait for the epoch end @@ -645,8 +643,8 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_Committee", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Client(nodeAlias).Committee(context.Background()) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, err := client.Committee(context.Background()) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, 4, len(resp.Committee)) @@ -654,8 +652,8 @@ func Test_CoreAPI(t *testing.T) { }, { name: "Test_CommitteeWithEpoch", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Client(nodeAlias).Committee(context.Background(), 0) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, err := client.Committee(context.Background(), 0) require.NoError(t, err) require.Equal(t, iotago.EpochIndex(0), resp.Epoch) require.Equal(t, 4, len(resp.Committee)) @@ -665,7 +663,9 @@ func Test_CoreAPI(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - d.RequestFromNodes(test.testFunc) + for _, node := range d.Nodes() { + test.testFunc(d.Testing, node, d.Client(node.Name)) + } }) } @@ -688,7 +688,7 @@ func Test_CoreAPI_BadRequests(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -697,13 +697,13 @@ func Test_CoreAPI_BadRequests(t *testing.T) { tests := []struct { name string - testFunc func(t *testing.T, nodeAlias string) + testFunc func(t *testing.T, node *dockertestframework.Node, client mock.Client) }{ { name: "Test_BlockByBlockID_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { blockID := tpkg.RandBlockID() - respBlock, err := d.Client(nodeAlias).BlockByBlockID(context.Background(), blockID) + respBlock, err := client.BlockByBlockID(context.Background(), blockID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, respBlock) @@ -711,9 +711,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_BlockMetadataByBlockID_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { blockID := tpkg.RandBlockID() - resp, err := d.Client(nodeAlias).BlockMetadataByBlockID(context.Background(), blockID) + resp, err := client.BlockMetadataByBlockID(context.Background(), blockID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -721,9 +721,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_BlockWithMetadata_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { blockID := tpkg.RandBlockID() - resp, err := d.Client(nodeAlias).BlockWithMetadataByBlockID(context.Background(), blockID) + resp, err := client.BlockWithMetadataByBlockID(context.Background(), blockID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -731,9 +731,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_CommitmentBySlot_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { slot := iotago.SlotIndex(1000_000_000) - resp, err := d.Client(nodeAlias).CommitmentBySlot(context.Background(), slot) + resp, err := client.CommitmentBySlot(context.Background(), slot) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -741,9 +741,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_CommitmentByID_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { committmentID := tpkg.RandCommitmentID() - resp, err := d.Client(nodeAlias).CommitmentByID(context.Background(), committmentID) + resp, err := client.CommitmentByID(context.Background(), committmentID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -751,9 +751,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_CommitmentUTXOChangesByID_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { committmentID := tpkg.RandCommitmentID() - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesByID(context.Background(), committmentID) + resp, err := client.CommitmentUTXOChangesByID(context.Background(), committmentID) require.Error(t, err) // commitmentID is valid, but the UTXO changes does not exist in the storage require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) @@ -762,10 +762,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { "Test_CommitmentUTXOChangesFullByID_Failure", - func(t *testing.T, nodeAlias string) { + func(t *testing.T, node *dockertestframework.Node, client mock.Client) { committmentID := tpkg.RandCommitmentID() - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesFullByID(context.Background(), committmentID) + resp, err := client.CommitmentUTXOChangesFullByID(context.Background(), committmentID) require.Error(t, err) // commitmentID is valid, but the UTXO changes does not exist in the storage require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) @@ -774,9 +774,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_CommitmentUTXOChangesBySlot_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { slot := iotago.SlotIndex(1000_000_000) - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesBySlot(context.Background(), slot) + resp, err := client.CommitmentUTXOChangesBySlot(context.Background(), slot) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -784,10 +784,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_CommitmentUTXOChangesFullBySlot_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { slot := iotago.SlotIndex(1000_000_000) - resp, err := d.Client(nodeAlias).CommitmentUTXOChangesFullBySlot(context.Background(), slot) + resp, err := client.CommitmentUTXOChangesFullBySlot(context.Background(), slot) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -795,9 +795,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_OutputByID_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { outputID := tpkg.RandOutputID(0) - resp, err := d.Client(nodeAlias).OutputByID(context.Background(), outputID) + resp, err := client.OutputByID(context.Background(), outputID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -805,10 +805,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_OutputMetadata_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { outputID := tpkg.RandOutputID(0) - resp, err := d.Client(nodeAlias).OutputMetadataByID(context.Background(), outputID) + resp, err := client.OutputMetadataByID(context.Background(), outputID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -816,10 +816,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_OutputWithMetadata_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { outputID := tpkg.RandOutputID(0) - out, outMetadata, err := d.Client(nodeAlias).OutputWithMetadataByID(context.Background(), outputID) + out, outMetadata, err := client.OutputWithMetadataByID(context.Background(), outputID) require.Error(t, err) require.Nil(t, out) require.Nil(t, outMetadata) @@ -828,9 +828,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_TransactionsIncludedBlock_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { txID := tpkg.RandTransactionID() - resp, err := d.Client(nodeAlias).TransactionIncludedBlock(context.Background(), txID) + resp, err := client.TransactionIncludedBlock(context.Background(), txID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -838,10 +838,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_TransactionsIncludedBlockMetadata_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { txID := tpkg.RandTransactionID() - resp, err := d.Client(nodeAlias).TransactionIncludedBlockMetadata(context.Background(), txID) + resp, err := client.TransactionIncludedBlockMetadata(context.Background(), txID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -849,10 +849,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_TransactionsMetadata_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { txID := tpkg.RandTransactionID() - resp, err := d.Client(nodeAlias).TransactionMetadata(context.Background(), txID) + resp, err := client.TransactionMetadata(context.Background(), txID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -860,10 +860,10 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_Congestion_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { accountAddress := tpkg.RandAccountAddress() commitmentID := tpkg.RandCommitmentID() - resp, err := d.Client(nodeAlias).Congestion(context.Background(), accountAddress, 0, commitmentID) + resp, err := client.Congestion(context.Background(), accountAddress, 0, commitmentID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -871,8 +871,8 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_Committee_Failure", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Client(nodeAlias).Committee(context.Background(), 4) + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { + resp, err := client.Committee(context.Background(), 4) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusBadRequest)) require.Nil(t, resp) @@ -880,9 +880,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { }, { name: "Test_Rewards_Failure", - testFunc: func(t *testing.T, nodeAlias string) { + testFunc: func(t *testing.T, node *dockertestframework.Node, client mock.Client) { outputID := tpkg.RandOutputID(0) - resp, err := d.Client(nodeAlias).Rewards(context.Background(), outputID) + resp, err := client.Rewards(context.Background(), outputID) require.Error(t, err) require.True(t, dockertestframework.IsStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) @@ -892,7 +892,9 @@ func Test_CoreAPI_BadRequests(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - d.RequestFromNodes(test.testFunc) + for _, node := range d.Nodes() { + test.testFunc(d.Testing, node, d.Client(node.Name)) + } }) } } diff --git a/tools/docker-network/tests/api_management_test.go b/tools/docker-network/tests/api_management_test.go index 6bf9023da..c10c36b95 100644 --- a/tools/docker-network/tests/api_management_test.go +++ b/tools/docker-network/tests/api_management_test.go @@ -43,13 +43,16 @@ func Test_ManagementAPI_Peers(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) d.WaitUntilNetworkReady() + // wait longer for autopeering + d.AwaitCommitment(d.DefaultWallet().CurrentSlot()) + // get the management client managementClient, err := d.Client("V1").Management(getContextWithTimeout(5 * time.Second)) require.NoError(t, err) @@ -132,7 +135,7 @@ func Test_ManagementAPI_Peers_BadRequests(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -185,8 +188,8 @@ func Test_ManagementAPI_Peers_BadRequests(t *testing.T) { func Test_ManagementAPI_Pruning(t *testing.T) { d := dockertestframework.NewDockerTestFramework(t, dockertestframework.WithProtocolParametersOptions( - iotago.WithTimeProviderOptions(0, time.Now().Unix(), 4, 4), - iotago.WithLivenessOptions(3, 4, 2, 4, 5), + iotago.WithTimeProviderOptions(0, time.Now().Unix(), 10, 3), + iotago.WithLivenessOptions(10, 10, 2, 4, 5), iotago.WithCongestionControlOptions(1, 1, 1, 400_000, 250_000, 50_000_000, 1000, 100), iotago.WithRewardsOptions(8, 10, 2, 384), iotago.WithTargetCommitteeSize(4), @@ -198,7 +201,7 @@ func Test_ManagementAPI_Pruning(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -221,9 +224,9 @@ func Test_ManagementAPI_Pruning(t *testing.T) { name: "Test_PruneDatabase_ByEpoch", testFunc: func(t *testing.T) { // we need to wait until epoch 3 to be able to prune epoch 1 - d.AwaitNextEpoch() - d.AwaitNextEpoch() - d.AwaitNextEpoch() + d.AwaitEpochFinalized() + d.AwaitEpochFinalized() + d.AwaitEpochFinalized() // prune database by epoch pruneDatabaseResponse, err := managementClient.PruneDatabaseByEpoch(getContextWithTimeout(5*time.Second), 1) @@ -235,7 +238,7 @@ func Test_ManagementAPI_Pruning(t *testing.T) { name: "Test_PruneDatabase_ByDepth", testFunc: func(t *testing.T) { // wait for the next epoch to start - d.AwaitNextEpoch() + d.AwaitEpochFinalized() // prune database by depth pruneDatabaseResponse, err := managementClient.PruneDatabaseByDepth(getContextWithTimeout(5*time.Second), 1) @@ -247,7 +250,7 @@ func Test_ManagementAPI_Pruning(t *testing.T) { name: "Test_PruneDatabase_BySize", testFunc: func(t *testing.T) { // wait for the next epoch to start - d.AwaitNextEpoch() + d.AwaitEpochFinalized() // prune database by size pruneDatabaseResponse, err := managementClient.PruneDatabaseBySize(getContextWithTimeout(5*time.Second), "5G") @@ -266,8 +269,8 @@ func Test_ManagementAPI_Pruning(t *testing.T) { func Test_ManagementAPI_Snapshots(t *testing.T) { d := dockertestframework.NewDockerTestFramework(t, dockertestframework.WithProtocolParametersOptions( - iotago.WithTimeProviderOptions(0, time.Now().Unix(), 3, 4), - iotago.WithLivenessOptions(3, 4, 2, 4, 8), + iotago.WithTimeProviderOptions(0, time.Now().Unix(), 10, 3), + iotago.WithLivenessOptions(10, 10, 2, 4, 5), iotago.WithCongestionControlOptions(1, 1, 1, 400_000, 250_000, 50_000_000, 1000, 100), iotago.WithRewardsOptions(8, 10, 2, 384), iotago.WithTargetCommitteeSize(4), @@ -278,7 +281,7 @@ func Test_ManagementAPI_Snapshots(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") runErr := d.Run() require.NoError(t, runErr) @@ -291,16 +294,6 @@ func Test_ManagementAPI_Snapshots(t *testing.T) { managementClient, err := nodeClientV1.Management(getContextWithTimeout(5 * time.Second)) require.NoError(t, err) - awaitNextCommittedEpoch := func() { - info, err := nodeClientV1.Info(getContextWithTimeout(5 * time.Second)) - require.NoError(t, err) - - currentEpoch := nodeClientV1.CommittedAPI().TimeProvider().EpochFromSlot(info.Status.LatestCommitmentID.Slot()) - - // await the start slot of the next epoch - d.AwaitCommitment(nodeClientV1.CommittedAPI().TimeProvider().EpochStart(currentEpoch + 1)) - } - type test struct { name string testFunc func(t *testing.T) @@ -311,7 +304,7 @@ func Test_ManagementAPI_Snapshots(t *testing.T) { name: "Test_CreateSnapshot", testFunc: func(t *testing.T) { // wait for the next epoch to start - awaitNextCommittedEpoch() + d.AwaitEpochFinalized() // create snapshot snapshotResponse, err := managementClient.CreateSnapshot(getContextWithTimeout(5 * time.Second)) diff --git a/tools/docker-network/tests/committeerotation_test.go b/tools/docker-network/tests/committeerotation_test.go index 6e117dcc4..576be1af8 100644 --- a/tools/docker-network/tests/committeerotation_test.go +++ b/tools/docker-network/tests/committeerotation_test.go @@ -36,7 +36,7 @@ func Test_SmallerCommittee(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -81,7 +81,7 @@ func Test_ReuseDueToNoFinalization(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -150,7 +150,7 @@ func Test_NoCandidacyPayload(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl", false) d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt", false) d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw", false) - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -200,7 +200,7 @@ func Test_Staking(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -247,7 +247,7 @@ func Test_Delegation(t *testing.T) { d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") // V4 pubKey in hex: 0xc9ceac37d293155a578381aa313ee74edfa3ac73ee930d045564aae7771e8ffe d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) diff --git a/tools/docker-network/tests/dockertestframework/asserts.go b/tools/docker-network/tests/dockertestframework/asserts.go index 3764ee2c3..16dc0f4e7 100644 --- a/tools/docker-network/tests/dockertestframework/asserts.go +++ b/tools/docker-network/tests/dockertestframework/asserts.go @@ -76,7 +76,6 @@ func (d *DockerTestFramework) AssertCommittee(expectedEpoch iotago.EpochIndex, e status := d.NodeStatus("V1") testAPI := d.defaultWallet.Client.CommittedAPI() expectedSlotStart := testAPI.TimeProvider().EpochStart(expectedEpoch) - require.Greater(d.Testing, expectedSlotStart, status.LatestAcceptedBlockSlot) if status.LatestAcceptedBlockSlot < expectedSlotStart { slotToWait := expectedSlotStart - status.LatestAcceptedBlockSlot @@ -87,22 +86,22 @@ func (d *DockerTestFramework) AssertCommittee(expectedEpoch iotago.EpochIndex, e d.Eventually(func() error { for _, node := range d.Nodes() { - resp, err := d.Client(node.Name).Committee(context.TODO()) + resp, err := d.Client(node.Name).Committee(context.TODO(), expectedEpoch) if err != nil { return err } - if resp.Epoch == expectedEpoch { - members := make([]string, len(resp.Committee)) - for i, member := range resp.Committee { - members[i] = member.AddressBech32 - } + if resp.Epoch != expectedEpoch { + return ierrors.Errorf("expected epoch %d, but got %d", expectedEpoch, resp.Epoch) + } - sort.Strings(members) - if match := lo.Equal(expectedCommitteeMember, members); match { - return nil - } + members := make([]string, len(resp.Committee)) + for i, member := range resp.Committee { + members[i] = member.AddressBech32 + } + sort.Strings(members) + if !lo.Equal(expectedCommitteeMember, members) { return ierrors.Errorf("committee members does not match as expected, expected: %v, actual: %v", expectedCommitteeMember, members) } } diff --git a/tools/docker-network/tests/dockertestframework/awaits.go b/tools/docker-network/tests/dockertestframework/awaits.go index 553134cfb..14c9b696e 100644 --- a/tools/docker-network/tests/dockertestframework/awaits.go +++ b/tools/docker-network/tests/dockertestframework/awaits.go @@ -63,9 +63,9 @@ func (d *DockerTestFramework) AwaitTransactionFailure(ctx context.Context, txID if expectedReason == resp.TransactionFailureReason { return nil - } else { - return ierrors.Errorf("expected transaction %s to have failure reason '%s', got '%s' instead, failure details: %s", txID, expectedReason, resp.TransactionFailureReason, resp.TransactionFailureDetails) } + + return ierrors.Errorf("expected transaction %s to have failure reason '%s', got '%s' instead, failure details: %s", txID, expectedReason, resp.TransactionFailureReason, resp.TransactionFailureDetails) }) } @@ -92,17 +92,28 @@ func (d *DockerTestFramework) AwaitCommitment(targetSlot iotago.SlotIndex) { } func (d *DockerTestFramework) AwaitFinalization(targetSlot iotago.SlotIndex) { - d.Eventually(func() error { + currentFinalizedSlot := d.NodeStatus("V1").LatestFinalizedSlot + + // we wait at max "targetSlot - currentFinalizedSlot" times * slot duration + deadline := time.Duration(d.defaultWallet.Client.CommittedAPI().ProtocolParameters().SlotDurationInSeconds()) * time.Second + if currentFinalizedSlot < targetSlot { + deadline *= time.Duration(targetSlot - currentFinalizedSlot) + } + + // give some extra time for peering etc + deadline += 30 * time.Second + + d.EventuallyWithDurations(func() error { currentFinalisedSlot := d.NodeStatus("V1").LatestFinalizedSlot if targetSlot > currentFinalisedSlot { return ierrors.Errorf("finalized slot %d is not reached yet", targetSlot) } return nil - }) + }, deadline, 1*time.Second) } -func (d *DockerTestFramework) AwaitNextEpoch() { +func (d *DockerTestFramework) AwaitEpochFinalized() { //nolint:lostcancel ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) diff --git a/tools/docker-network/tests/dockertestframework/framework.go b/tools/docker-network/tests/dockertestframework/framework.go index a6b203b77..abb474795 100644 --- a/tools/docker-network/tests/dockertestframework/framework.go +++ b/tools/docker-network/tests/dockertestframework/framework.go @@ -130,11 +130,15 @@ func (d *DockerTestFramework) DockerComposeUp(detach ...bool) error { } func (d *DockerTestFramework) Run() error { + // first we remove old containers, volumes and orphans + _ = exec.Command("docker", "compose", "down", "-v", "--remove-orphans").Run() + ch := make(chan error) stopCh := make(chan struct{}) defer close(ch) defer close(stopCh) + ts := time.Now() go func() { err := d.DockerComposeUp() @@ -165,7 +169,7 @@ loop: } case <-ticker.C: fmt.Println("Waiting for nodes to become available...") - if d.waitForNodesAndGetClients() == nil { + if d.waitForNodesOnlineAndInitClients(ts) == nil { break loop } } @@ -183,7 +187,8 @@ func (d *DockerTestFramework) Stop() { fmt.Println("Stop the network...") defer fmt.Println("Stop the network.....done") - _ = exec.Command("docker", "compose", "down").Run() + // remove volumes and orphans + _ = exec.Command("docker", "compose", "down", "-v", "--remove-orphans").Run() _ = exec.Command("rm", d.snapshotPath).Run() //nolint:gosec } @@ -242,12 +247,10 @@ func (d *DockerTestFramework) DumpContainerLog(name string, optLogNameExtension func (d *DockerTestFramework) GetContainersConfigs() { // get container configs - nodes := d.Nodes() - d.nodesLock.Lock() defer d.nodesLock.Unlock() - for _, node := range nodes { + for _, node := range d.nodesWithoutLocking() { cmd := fmt.Sprintf("docker inspect --format='{{.Config.Cmd}}' %s", node.ContainerName) containerConfigsBytes, err := exec.Command("bash", "-c", cmd).Output() require.NoError(d.Testing, err) @@ -266,6 +269,7 @@ func (d *DockerTestFramework) GetContainersConfigs() { node.ContainerConfigs = configs node.PrivateKey = envs + d.nodes[node.Name] = node } } diff --git a/tools/docker-network/tests/dockertestframework/nodes.go b/tools/docker-network/tests/dockertestframework/nodes.go index 1dd7038a4..7cac38dd8 100644 --- a/tools/docker-network/tests/dockertestframework/nodes.go +++ b/tools/docker-network/tests/dockertestframework/nodes.go @@ -7,6 +7,7 @@ import ( "fmt" "math/rand" "testing" + "time" "github.com/stretchr/testify/require" @@ -49,18 +50,22 @@ func (d *DockerTestFramework) NodeStatus(name string) *api.InfoResNodeStatus { return info.Status } -func (d *DockerTestFramework) waitForNodesAndGetClients() error { - nodes := d.Nodes() - +func (d *DockerTestFramework) waitForNodesOnlineAndInitClients(ts time.Time) error { d.nodesLock.Lock() defer d.nodesLock.Unlock() - for _, node := range nodes { + for _, node := range d.nodesWithoutLocking() { + // check if the node is online and initialize the client client, err := nodeclient.New(node.ClientURL) if err != nil { + delete(d.clients, node.Name) return ierrors.Wrapf(err, "failed to create node client for node %s", node.Name) } - d.nodes[node.Name] = node + + if _, exist := d.clients[node.Name]; !exist { + fmt.Println(fmt.Sprintf("Node %s became available after %v!", node.Name, time.Since(ts).Truncate(time.Millisecond))) + } + d.clients[node.Name] = client } @@ -84,22 +89,65 @@ func (d *DockerTestFramework) WaitUntilNetworkReady() { d.DumpContainerLogsToFiles() } +func (d *DockerTestFramework) WaitUntilNodesHealthy() { + fmt.Println("Wait until all the nodes are healthy...") + defer fmt.Println("Wait until all the nodes are healthy... done!") + + // remember a map of nodes that were synced so we don't print the same node multiple times + healthyNodes := make(map[string]struct{}) + + ts := time.Now() + + d.Eventually(func() error { + for _, node := range d.Nodes() { + info, err := d.Client(node.Name).Info(context.TODO()) + if err != nil { + delete(healthyNodes, node.Name) + return ierrors.Errorf("failed to get node %s's info: %w", node.Name, err) + } + + if !info.Status.IsHealthy { + delete(healthyNodes, node.Name) + return ierrors.Errorf("node %s's network is not healthy", node.Name) + } + + if _, exist := healthyNodes[node.Name]; !exist { + healthyNodes[node.Name] = struct{}{} + + fmt.Println(fmt.Sprintf("Node %s became healthy after %v!", node.Name, time.Since(ts).Truncate(time.Millisecond))) + } + } + + return nil + }, true) +} + func (d *DockerTestFramework) WaitUntilNetworkHealthy() { fmt.Println("Wait until the network is healthy...") - defer fmt.Println("Wait until the network is healthy......done") + defer fmt.Println("Wait until the network is healthy... done!") + + // remember a map of nodes that were synced so we don't print the same node multiple times + syncedNodes := make(map[string]struct{}) + + ts := time.Now() d.Eventually(func() error { for _, node := range d.Nodes() { - for { - info, err := d.Client(node.Name).Info(context.TODO()) - if err != nil { - return err - } - - if info.Status.IsNetworkHealthy { - fmt.Println("Node", node.Name, "is synced") - break - } + info, err := d.Client(node.Name).Info(context.TODO()) + if err != nil { + delete(syncedNodes, node.Name) + return ierrors.Errorf("failed to get node %s's info: %w", node.Name, err) + } + + if !info.Status.IsNetworkHealthy { + delete(syncedNodes, node.Name) + return ierrors.Errorf("node %s's network is not healthy", node.Name) + } + + if _, exist := syncedNodes[node.Name]; !exist { + syncedNodes[node.Name] = struct{}{} + + fmt.Println(fmt.Sprintf("Node %s's network is healthy after %v!", node.Name, time.Since(ts).Truncate(time.Millisecond))) } } @@ -136,10 +184,7 @@ func (d *DockerTestFramework) AddNode(name string, containerName string, clientU } } -func (d *DockerTestFramework) Nodes(names ...string) []*Node { - d.nodesLock.RLock() - defer d.nodesLock.RUnlock() - +func (d *DockerTestFramework) nodesWithoutLocking(names ...string) []*Node { if len(names) == 0 { nodes := make([]*Node, 0, len(d.nodes)) for _, node := range d.nodes { @@ -157,6 +202,13 @@ func (d *DockerTestFramework) Nodes(names ...string) []*Node { return nodes } +func (d *DockerTestFramework) Nodes(names ...string) []*Node { + d.nodesLock.RLock() + defer d.nodesLock.RUnlock() + + return d.nodesWithoutLocking(names...) +} + func (d *DockerTestFramework) Node(name string) *Node { d.nodesLock.RLock() defer d.nodesLock.RUnlock() @@ -190,9 +242,3 @@ func (d *DockerTestFramework) ResetNode(alias string, newSnapshotPath string) { d.DumpContainerLog(d.Node(alias).ContainerName, "reset1") d.WaitUntilNetworkHealthy() } - -func (d *DockerTestFramework) RequestFromNodes(testFunc func(*testing.T, string)) { - for nodeAlias := range d.nodes { - testFunc(d.Testing, nodeAlias) - } -} diff --git a/tools/docker-network/tests/dockertestframework/options.go b/tools/docker-network/tests/dockertestframework/options.go index 1df7097b9..b706ce12a 100644 --- a/tools/docker-network/tests/dockertestframework/options.go +++ b/tools/docker-network/tests/dockertestframework/options.go @@ -3,6 +3,7 @@ package dockertestframework import ( + "fmt" "time" "github.com/iotaledger/hive.go/runtime/options" @@ -13,7 +14,7 @@ import ( ) var DefaultProtocolParametersOptions = []options.Option[iotago.V3ProtocolParameters]{ - iotago.WithNetworkOptions("docker", iotago.PrefixTestnet), + iotago.WithNetworkOptions(fmt.Sprintf("docker-tests-%d", time.Now().Unix()), iotago.PrefixTestnet), } // DefaultAccountOptions are the default snapshot options for the docker network. diff --git a/tools/docker-network/tests/dockertestframework/utils.go b/tools/docker-network/tests/dockertestframework/utils.go index f96154048..5ab37792b 100644 --- a/tools/docker-network/tests/dockertestframework/utils.go +++ b/tools/docker-network/tests/dockertestframework/utils.go @@ -34,8 +34,8 @@ func (d *DockerTestFramework) EventuallyWithDurations(condition func() error, de tick = nil go func() { ch <- condition() }() case lastErr = <-ch: - // The condition is satisfied, we can exit. if lastErr == nil { + // The condition is satisfied, we can exit. return } tick = ticker.C diff --git a/tools/docker-network/tests/dockertestframework/validator.go b/tools/docker-network/tests/dockertestframework/validator.go index 68c57335f..534c7e21e 100644 --- a/tools/docker-network/tests/dockertestframework/validator.go +++ b/tools/docker-network/tests/dockertestframework/validator.go @@ -37,8 +37,8 @@ func (d *DockerTestFramework) StopIssueCandidacyPayload(nodes ...*Node) { require.NoError(d.Testing, err) } -func (d *DockerTestFramework) IssueCandidacyPayloadFromAccount(wallet *mock.Wallet) iotago.BlockID { - block, err := wallet.CreateAndSubmitBasicBlock(context.TODO(), "candidacy_payload", mock.WithPayload(&iotago.CandidacyAnnouncement{})) +func (d *DockerTestFramework) IssueCandidacyPayloadFromAccount(ctx context.Context, wallet *mock.Wallet) iotago.BlockID { + block, err := wallet.CreateAndSubmitBasicBlock(ctx, "candidacy_payload", mock.WithPayload(&iotago.CandidacyAnnouncement{})) require.NoError(d.Testing, err) return block.ID() diff --git a/tools/docker-network/tests/eventapi_test.go b/tools/docker-network/tests/eventapi_test.go index 7e2eb378c..b1255624e 100644 --- a/tools/docker-network/tests/eventapi_test.go +++ b/tools/docker-network/tests/eventapi_test.go @@ -38,7 +38,7 @@ func Test_MQTTTopics(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) diff --git a/tools/docker-network/tests/mempool_invalid_signatures_test.go b/tools/docker-network/tests/mempool_invalid_signatures_test.go index feee13e79..6af13dcac 100644 --- a/tools/docker-network/tests/mempool_invalid_signatures_test.go +++ b/tools/docker-network/tests/mempool_invalid_signatures_test.go @@ -30,7 +30,7 @@ func Test_MempoolInvalidSignatures(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) diff --git a/tools/docker-network/tests/rewards_test.go b/tools/docker-network/tests/rewards_test.go index 55950108b..3a3022c25 100644 --- a/tools/docker-network/tests/rewards_test.go +++ b/tools/docker-network/tests/rewards_test.go @@ -34,7 +34,7 @@ func Test_ValidatorRewards(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -73,8 +73,7 @@ func Test_ValidatorRewards(t *testing.T) { d, goodWallet, clt.CommittedAPI().TimeProvider().CurrentSlot(), - goodClaimingSlot, - slotsDuration) + goodClaimingSlot) // create lazy account lazyWallet, lazyAccountOutputData := d.CreateImplicitAccount(ctx) @@ -98,8 +97,7 @@ func Test_ValidatorRewards(t *testing.T) { d, lazyWallet, clt.CommittedAPI().TimeProvider().CurrentSlot(), - lazyClaimingSlot, - slotsDuration) + lazyClaimingSlot) // make sure the account is in the committee, so it can issue validation blocks goodAccountAddrBech32 := goodAccountData.Address.Bech32(clt.CommittedAPI().ProtocolParameters().Bech32HRP()) @@ -151,7 +149,7 @@ func Test_DelegatorRewards(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -209,7 +207,7 @@ func Test_DelayedClaimingRewards(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) @@ -273,19 +271,26 @@ func Test_DelayedClaimingRewards(t *testing.T) { } } -func issueCandidacyPayloadInBackground(ctx context.Context, d *dockertestframework.DockerTestFramework, wallet *mock.Wallet, startSlot, endSlot iotago.SlotIndex, slotDuration uint8) { +func issueCandidacyPayloadInBackground(ctx context.Context, d *dockertestframework.DockerTestFramework, wallet *mock.Wallet, startSlot, endSlot iotago.SlotIndex) { go func() { fmt.Println("Issuing candidacy payloads for account", wallet.BlockIssuer.AccountData.ID, "in the background...") defer fmt.Println("Issuing candidacy payloads for account", wallet.BlockIssuer.AccountData.ID, "in the background......done") for i := startSlot; i < endSlot; i++ { - if ctx.Err() != nil { - // context is canceled - return + // wait until the slot is reached + for { + if ctx.Err() != nil { + // context is canceled + return + } + + if wallet.CurrentSlot() == i { + break + } + time.Sleep(2 * time.Second) } - d.IssueCandidacyPayloadFromAccount(wallet) - time.Sleep(time.Duration(slotDuration) * time.Second) + d.IssueCandidacyPayloadFromAccount(ctx, wallet) } }() } @@ -318,7 +323,7 @@ func issueValidationBlockInBackground(ctx context.Context, wg *sync.WaitGroup, w return } - wallet.CreateAndSubmitValidationBlock(context.Background(), "", nil) + wallet.CreateAndSubmitValidationBlock(ctx, "", nil) time.Sleep(1 * time.Second) } } diff --git a/tools/docker-network/tests/sync_snapshot_test.go b/tools/docker-network/tests/sync_snapshot_test.go index 912cc29b5..f800a426f 100644 --- a/tools/docker-network/tests/sync_snapshot_test.go +++ b/tools/docker-network/tests/sync_snapshot_test.go @@ -3,11 +3,14 @@ package tests import ( + "context" + "fmt" "testing" "time" "github.com/stretchr/testify/require" + "github.com/iotaledger/iota-core/pkg/testsuite/mock" "github.com/iotaledger/iota-core/tools/docker-network/tests/dockertestframework" iotago "github.com/iotaledger/iota.go/v4" ) @@ -15,11 +18,11 @@ import ( func Test_SyncFromSnapshot(t *testing.T) { d := dockertestframework.NewDockerTestFramework(t, dockertestframework.WithProtocolParametersOptions( - iotago.WithTimeProviderOptions(0, time.Now().Unix(), 4, 4), - iotago.WithLivenessOptions(3, 4, 2, 4, 5), + iotago.WithTimeProviderOptions(0, time.Now().Unix(), 10, 3), + iotago.WithLivenessOptions(10, 10, 2, 4, 5), iotago.WithCongestionControlOptions(1, 1, 1, 400_000, 250_000, 50_000_000, 1000, 100), iotago.WithRewardsOptions(8, 10, 2, 384), - iotago.WithTargetCommitteeSize(4), + iotago.WithTargetCommitteeSize(3), )) defer d.Stop() @@ -27,26 +30,126 @@ func Test_SyncFromSnapshot(t *testing.T) { d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl") d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt") d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") - d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") + d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8080") err := d.Run() require.NoError(t, err) d.WaitUntilNetworkReady() - d.AwaitNextEpoch() - d.AwaitNextEpoch() + ctx := context.Background() + clt := d.DefaultWallet().Client - nodeClientV1 := d.Client("V1") - managementClient, err := nodeClientV1.Management(getContextWithTimeout(5 * time.Second)) + createAccountAndDelegateTo := func(receiver *dockertestframework.Node) (*mock.Wallet, *mock.AccountData, *mock.OutputData) { + delegatorWallet, accountData := d.CreateAccountFromFaucet() + clt := delegatorWallet.Client + + // delegate funds to receiver + delegationOutputData := d.DelegateToValidator(delegatorWallet, receiver.AccountAddress(t)) + d.AwaitCommitment(delegationOutputData.ID.CreationSlot()) + + // check if receiver received the delegator stake + resp, err := clt.Validator(ctx, receiver.AccountAddress(t)) + require.NoError(t, err) + require.Greater(t, resp.PoolStake, resp.ValidatorStake) + + return delegatorWallet, accountData, delegationOutputData + } + + v1DelegatorWallet, v1DelegatorAccountData, v1DelegationOutputData := createAccountAndDelegateTo(d.Node("V1")) + v2DelegatorWallet, v2DelegatorAccountData, v2DelegationOutputData := createAccountAndDelegateTo(d.Node("V2")) + + //nolint:forcetypeassert + currentEpoch := clt.CommittedAPI().TimeProvider().CurrentEpoch() + expectedEpoch := v2DelegationOutputData.Output.(*iotago.DelegationOutput).StartEpoch + 2 + for range expectedEpoch - currentEpoch { + d.AwaitEpochFinalized() + } + d.AssertCommittee(expectedEpoch, d.AccountsFromNodes(d.Nodes("V1", "V2", "V4")...)) + + // claim rewards for v1 delegator + v1DelegatorRewardsOutputID := d.ClaimRewardsForDelegator(ctx, v1DelegatorWallet, v1DelegationOutputData) + + // check if the mana increased as expected + node5Clt := d.Client("node5") + outputFromAPI, err := node5Clt.OutputByID(ctx, v1DelegatorRewardsOutputID) require.NoError(t, err) - response, err := managementClient.CreateSnapshot(getContextWithTimeout(5 * time.Second)) + rewardsOutput := v1DelegatorWallet.Output(v1DelegatorRewardsOutputID) + require.Equal(t, rewardsOutput.Output.StoredMana(), outputFromAPI.StoredMana()) + + d.AwaitEpochFinalized() + + managementClient, err := clt.Management(getContextWithTimeout(5 * time.Second)) require.NoError(t, err) - // Deletes the database of node5 and restarts it with the just created snapshot. - d.ResetNode("node5", response.FilePath) + // take the snapshot and restart node5 + { + fmt.Println("Create the first snapshot...") + response, err := managementClient.CreateSnapshot(getContextWithTimeout(5 * time.Second)) + require.NoError(t, err) + + // Deletes the database of node5 and restarts it with the just created snapshot. + d.ResetNode("node5", response.FilePath) + + d.AwaitEpochFinalized() + d.AwaitEpochFinalized() + + // check if the committee is the same among nodes + currentEpoch := clt.CommittedAPI().TimeProvider().CurrentEpoch() + d.AssertCommittee(currentEpoch, d.AccountsFromNodes(d.Nodes("V1", "V2", "V4")...)) + + // check if the account and rewardsOutput are available + node5Clt = d.Client("node5") + _, err = node5Clt.Validator(ctx, v1DelegatorAccountData.Address) + require.NoError(t, err) + _, err = node5Clt.Validator(ctx, v2DelegatorAccountData.Address) + require.NoError(t, err) + + _, err = node5Clt.OutputByID(ctx, v1DelegatorRewardsOutputID) + require.NoError(t, err) + + } + + // claim rewards for V2 delegator, and see if the output is available on node5 + v2DelegatorRewardsOutputID := d.ClaimRewardsForDelegator(ctx, v2DelegatorWallet, v2DelegationOutputData) + _, err = node5Clt.OutputByID(ctx, v2DelegatorRewardsOutputID) + require.NoError(t, err) + + // create V3 delegator, the committee should change to V1, V3, V4 + v3DelegatorWallet, v3DelegatorAccountData, v3DelegationOutputData := createAccountAndDelegateTo(d.Node("V3")) + currentEpoch = clt.CommittedAPI().TimeProvider().CurrentEpoch() + expectedEpoch = v3DelegationOutputData.Output.(*iotago.DelegationOutput).StartEpoch + 1 + for range expectedEpoch - currentEpoch { + d.AwaitEpochFinalized() + } + + d.AssertCommittee(expectedEpoch, d.AccountsFromNodes(d.Nodes("V1", "V3", "V4")...)) + + d.AwaitEpochFinalized() + + // take the snapshot again and restart node5 + { + fmt.Println("Create the second snapshot...") + response, err := managementClient.CreateSnapshot(getContextWithTimeout(5 * time.Second)) + require.NoError(t, err) + + // Deletes the database of node5 and restarts it with the just created snapshot. + d.ResetNode("node5", response.FilePath) + currentEpoch = clt.CommittedAPI().TimeProvider().EpochFromSlot(v3DelegatorWallet.CurrentSlot()) + d.AssertCommittee(currentEpoch, d.AccountsFromNodes(d.Nodes("V1", "V3", "V4")...)) + + node5Clt = d.Client("node5") + _, err = node5Clt.Validator(ctx, v1DelegatorAccountData.Address) + require.NoError(t, err) + _, err = node5Clt.Validator(ctx, v2DelegatorAccountData.Address) + require.NoError(t, err) + _, err = node5Clt.Validator(ctx, v3DelegatorAccountData.Address) + require.NoError(t, err) - d.AwaitNextEpoch() - d.AwaitNextEpoch() + _, err = node5Clt.OutputByID(ctx, v1DelegatorRewardsOutputID) + require.NoError(t, err) + _, err = node5Clt.OutputByID(ctx, v2DelegatorRewardsOutputID) + require.NoError(t, err) + } }