From 736003ac635b8d10ccc0bc705d2c9f133fb06ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Wed, 28 Feb 2024 16:12:41 +0100 Subject: [PATCH 01/22] Add core api tests --- tools/docker-network/tests/coreapi.go | 11 + tools/docker-network/tests/coreapi_test.go | 293 ++++++++++++++++++ tools/docker-network/tests/dockerframework.go | 38 +++ 3 files changed, 342 insertions(+) create mode 100644 tools/docker-network/tests/coreapi.go create mode 100644 tools/docker-network/tests/coreapi_test.go diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go new file mode 100644 index 000000000..da0e48d5a --- /dev/null +++ b/tools/docker-network/tests/coreapi.go @@ -0,0 +1,11 @@ +package tests + +import ( + "testing" +) + +func (d *DockerTestFramework) requestFromClients(testFunc func(*testing.T, string)) { + for alias := range d.nodes { + testFunc(d.Testing, alias) + } +} diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go new file mode 100644 index 000000000..3a52c3ef2 --- /dev/null +++ b/tools/docker-network/tests/coreapi_test.go @@ -0,0 +1,293 @@ +//go:build dockertests + +package tests + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/require" + + iotago "github.com/iotaledger/iota.go/v4" + "github.com/iotaledger/iota.go/v4/api" +) + +func Test_ValidatorAPI(t *testing.T) { + d := NewDockerTestFramework(t, + WithProtocolParametersOptions( + iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4), + iotago.WithLivenessOptions(10, 10, 2, 4, 8), + iotago.WithRewardsOptions(8, 10, 2, 384), + iotago.WithTargetCommitteeSize(4), + )) + defer d.Stop() + + d.AddValidatorNode("V1", "docker-network-inx-validator-1-1", "http://localhost:8050", "rms1pzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3y5rx2w6") + 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.WaitUntilNetworkReady() + + ctx := context.Background() + + prePreparedAssets := struct { + slot iotago.SlotIndex + epoch iotago.EpochIndex + dataBlock *iotago.Block + valueBlock *iotago.Block + transaction *iotago.SignedTransaction + transactionID iotago.TransactionID + basicOutput iotago.Output + basicOutputID iotago.OutputID + accountAddress *iotago.AccountAddress + }{ + slot: iotago.SlotIndex(2), + } + + sharedAssets := struct { + commitmentIDs map[string]iotago.CommitmentID + }{} + + clt := d.Node("V1").Client + prePreparedAssets.epoch = clt.APIForSlot(prePreparedAssets.slot).TimeProvider().EpochFromSlot(prePreparedAssets.slot) + prePreparedAssets.dataBlock = d.CreateTaggedDataBlock(d.Node("V1").AccountAddress(t).AccountID(), []byte{'t', 'a', 'g'}) + + block, signedTx, basicOut := d.CreateValueBlock("V1") + d.SubmitBlock(ctx, block) + + prePreparedAssets.valueBlock = block + prePreparedAssets.basicOutput = basicOut + prePreparedAssets.transaction = signedTx + txID, err := signedTx.Transaction.ID() + require.NoError(d.Testing, err) + prePreparedAssets.transactionID = txID + prePreparedAssets.basicOutputID = iotago.OutputIDFromTransactionIDAndIndex(txID, 0) + + account := d.CreateAccount() + prePreparedAssets.accountAddress = account.Address + + d.AwaitCommitment(prePreparedAssets.slot) + + tests := []struct { + name string + testFunc func(t *testing.T, nodeAlias string) + }{ + { + name: "Test_Info", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.Info(context.Background()) + require.NoError(t, err) + require.NotNil(t, resp) + + fmt.Println(resp) + }, + }, + { + name: "Test_BlockByBlockID", + testFunc: func(t *testing.T, nodeAlias string) { + respBlock, err := d.Node(nodeAlias).Client.BlockByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) + require.NoError(t, err) + require.NotNil(t, respBlock) + require.Equal(t, prePreparedAssets.dataBlock, respBlock) + }, + }, + { + name: "Test_BlockMetadataByBlockID", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.BlockMetadataByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) + require.NoError(t, err) + require.NotNil(t, resp) + + require.Equal(t, prePreparedAssets.dataBlock.MustID(), resp.BlockID) + require.Equal(t, api.BlockStateFinalized, resp.BlockState) + }, + }, + { + name: "Test_BlockWithMetadata", + testFunc: func(t *testing.T, nodeAlias string) { + // TODO missing client side implementation + resp, err := d.Node(nodeAlias).Client.BlockMetadataByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_BlockIssuance", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.BlockIssuance(context.Background()) + require.NoError(t, err) + require.NotNil(t, resp) + + require.GreaterOrEqual(t, resp.StrongParents, 1) + }, + }, + { + name: "Test_CommitmentBySlot", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentByIndex(context.Background(), prePreparedAssets.slot) + require.NoError(t, err) + require.NotNil(t, resp) + sharedAssets.commitmentIDs[nodeAlias] = resp.MustID() + }, + }, + { + name: "Test_CommitmentByID", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, sharedAssets.commitmentIDs[nodeAlias], resp.MustID()) + }, + }, + { + name: "Test_CommitmentUTXOChangesByID", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + fmt.Println(resp) + }, + }, + { + name: "Test_CommitmentUTXOChangesFullByID", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesFullByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + fmt.Println(resp) + }, + }, + { + name: "Test_CommitmentUTXOChangesBySlot", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesByIndex(context.Background(), prePreparedAssets.slot) + require.NoError(t, err) + require.NotNil(t, resp) + // check by what I have sent + + resp, err = d.Node(nodeAlias).Client.CommitmentUTXOChangesByIndex(context.Background(), sharedAssets.commitmentIDs[nodeAlias].Slot()) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, sharedAssets.commitmentIDs[nodeAlias], resp.CommitmentID) + + // todo check with by commitment resp + + }, + }, + { + name: "Test_CommitmentUTXOChangesFullBySlot", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesFullByIndex(context.Background(), prePreparedAssets.slot) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_OutputByID", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.OutputByID(context.Background(), prePreparedAssets.basicOutputID) + require.NoError(t, err) + require.NotNil(t, resp) + // todo calculate outID + }, + }, + { + name: "Test_OutputMetadata", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.OutputMetadataByID(context.Background(), prePreparedAssets.basicOutputID) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_TransactionsIncludedBlock", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.TransactionIncludedBlock(context.Background(), prePreparedAssets.transactionID) + require.NoError(t, err) + require.NotNil(t, resp) + + // todo issue second block with the same tx, and make sure that the first one is returned here + }, + }, + { + name: "Test_TransactionsIncludedBlockMetadata", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.TransactionIncludedBlockMetadata(context.Background(), prePreparedAssets.transactionID) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_TransactionsMetadata", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.TransactionMetadata(context.Background(), prePreparedAssets.transactionID) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_Congestion", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.Congestion(context.Background(), d.Node(nodeAlias).AccountAddress(t), 0) + require.NoError(t, err) + require.NotNil(t, resp) + + resp, err = d.Node(nodeAlias).Client.Congestion(context.Background(), prePreparedAssets.accountAddress, 0, sharedAssets.commitmentIDs[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_Validators", + testFunc: func(t *testing.T, nodeAlias string) { + pageSize := uint64(3) + resp, err := d.Node(nodeAlias).Client.Validators(context.Background(), pageSize) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, len(resp.Validators), int(pageSize)) + + resp, err = d.Node(nodeAlias).Client.Validators(context.Background(), pageSize, resp.Cursor) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, len(resp.Validators), 1) + }, + }, + { + name: "Test_ValidatorsAll", + testFunc: func(t *testing.T, nodeAlias string) { + resp, all, err := d.Node(nodeAlias).Client.ValidatorsAll(context.Background()) + require.NoError(t, err) + require.True(t, all) + require.Equal(t, 4, len(resp.Validators)) + }, + }, + { + name: "Test_Rewards", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.Rewards(context.Background(), prePreparedAssets.basicOutputID) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + { + name: "Test_Committee", + testFunc: func(t *testing.T, nodeAlias string) { + resp, err := d.Node(nodeAlias).Client.Committee(context.Background(), prePreparedAssets.epoch) + require.NoError(t, err) + require.NotNil(t, resp) + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + d.requestFromClients(test.testFunc) + }) + } + + // TDO Assert shared assets are the same +} diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index a97910ab0..ab343b994 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -57,6 +57,15 @@ type Node struct { IssueCandidacyPayload bool } +func (n *Node) AccountAddress(t *testing.T) *iotago.AccountAddress { + _, addr, err := iotago.ParseBech32(n.AccountAddressBech32) + require.NoError(t, err) + accAddress, ok := addr.(*iotago.AccountAddress) + require.True(t, ok) + + return accAddress +} + type DockerTestFramework struct { Testing *testing.T @@ -367,6 +376,35 @@ func (d *DockerTestFramework) CreateTaggedDataBlock(issuerId iotago.AccountID, t }, issuerId, congestionResp, issuerResp) } +func (d *DockerTestFramework) CreateValueBlock(nodeAlias string) (*iotago.Block, *iotago.SignedTransaction, iotago.Output) { + ctx := context.Background() + clt := d.Node(nodeAlias).Client + currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now()) + apiForSlot := clt.APIForSlot(currentSlot) + + fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) + + _, ed25519Addr := d.wallet.Address() + input := d.wallet.Output(fundsOutputID) + basicOutput := builder.NewBasicOutputBuilder(ed25519Addr, input.Output.BaseTokenAmount()).MustBuild() + + signedTx, err := builder.NewTransactionBuilder(apiForSlot). + AddInput(&builder.TxInput{ + UnlockTarget: input.Address, + InputID: input.ID, + Input: input.Output, + }). + AddOutput(basicOutput). + SetCreationSlot(currentSlot). + Build(d.wallet.AddressSigner(input.AddressIndex)) + require.NoError(d.wallet.Testing, err) + + issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, d.Node(nodeAlias).AccountAddress(d.Testing)) + block := d.CreateBlock(ctx, signedTx, d.Node(nodeAlias).AccountAddress(d.Testing).AccountID(), congestionResp, issuerResp) + + return block, signedTx, basicOutput +} + // CreateDelegationBlockFromInput consumes the given basic output, then build a block of a transaction that includes a delegation output, in order to delegate the given validator. func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerId iotago.AccountID, validator *Node, inputId iotago.OutputID) (iotago.DelegationID, iotago.OutputID, *iotago.Block) { issuer := d.wallet.Account(issuerId) From d932aac39fe26fb96de228a1ae9c47dd25b7ffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Mon, 4 Mar 2024 14:52:28 +0100 Subject: [PATCH 02/22] Add more assertions, and fixes --- tools/docker-network/tests/coreapi.go | 193 ++++++++++++++ tools/docker-network/tests/coreapi_test.go | 241 +++++++++--------- tools/docker-network/tests/dockerframework.go | 33 ++- 3 files changed, 329 insertions(+), 138 deletions(-) diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index da0e48d5a..ce4d0222f 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -1,9 +1,202 @@ +//go:build dockertests + package tests import ( + "context" + "fmt" "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/iotaledger/hive.go/ds/types" + "github.com/iotaledger/hive.go/lo" + iotago "github.com/iotaledger/iota.go/v4" + "github.com/iotaledger/iota.go/v4/api" ) +type coreAPIAssets map[iotago.SlotIndex]*coreAPISlotAssets + +func (a coreAPIAssets) assetForSlot(slot iotago.SlotIndex, account *AccountData) *coreAPISlotAssets { + _, ok := a[slot] + if !ok { + a[slot] = newAssetsPerSlot() + } + a[slot].accountSlot = account.OutputID.Slot() + a[slot].accountAddress = account.Address + + return a[slot] +} + +func (a coreAPIAssets) assertCommitments(t *testing.T) { + for _, asset := range a { + asset.assertCommitments(t) + } +} + +func (a coreAPIAssets) forEachBlock(t *testing.T, f func(*testing.T, *iotago.Block)) { + for _, asset := range a { + for _, block := range asset.dataBlocks { + f(t, block) + } + for _, block := range asset.valueBlocks { + f(t, block) + } + } +} + +func (a coreAPIAssets) forEachTransaction(t *testing.T, f func(*testing.T, *iotago.SignedTransaction)) { + for _, asset := range a { + for _, tx := range asset.transactions { + f(t, tx) + } + } +} + +func (a coreAPIAssets) forEachOutput(t *testing.T, f func(*testing.T, iotago.OutputID, iotago.Output)) { + for _, asset := range a { + for outID, out := range asset.basicOutputs { + f(t, outID, out) + } + } +} + +func (a coreAPIAssets) forEachSlot(t *testing.T, f func(*testing.T, iotago.SlotIndex, map[string]iotago.CommitmentID)) { + for slot, slotAssets := range a { + f(t, slot, slotAssets.commitmentPerNode) + } +} + +func (a coreAPIAssets) forEachCommitment(t *testing.T, f func(*testing.T, map[string]iotago.CommitmentID)) { + for _, asset := range a { + f(t, asset.commitmentPerNode) + } +} + +func (a coreAPIAssets) forEachAccountAddress(t *testing.T, f func(*testing.T, *iotago.AccountAddress, map[string]iotago.CommitmentID)) { + for _, asset := range a { + f(t, asset.accountAddress, asset.commitmentPerNode) + } +} + +func (a coreAPIAssets) assertUTXOOutputIDsInSlot(t *testing.T, slot iotago.SlotIndex, createdOutputs iotago.OutputIDs, spentOutputs iotago.OutputIDs) { + created := make(map[iotago.OutputID]types.Empty) + spent := make(map[iotago.OutputID]types.Empty) + for _, outputID := range createdOutputs { + + created[outputID] = types.Void + } + + for _, outputID := range spentOutputs { + spent[outputID] = types.Void + } + + for outID := range a[slot].basicOutputs { + _, ok := created[outID] + require.True(t, ok, "Output ID not found in created outputs: %s, for slot %d", outID, slot) + } + + for outID := range a[slot].faucetOutputs { + _, ok := spent[outID] + require.True(t, ok, "Output ID not found in spent outputs: %s, for slot %d", outID, slot) + } +} + +func (a coreAPIAssets) assertUTXOOutputsInSlot(t *testing.T, slot iotago.SlotIndex, created []*api.OutputWithID, spent []*api.OutputWithID) { + createdMap := make(map[iotago.OutputID]iotago.Output) + spentMap := make(map[iotago.OutputID]iotago.Output) + for _, output := range created { + createdMap[output.OutputID] = output.Output + } + for _, output := range spent { + spentMap[output.OutputID] = output.Output + } + + for outID, out := range a[slot].basicOutputs { + _, ok := createdMap[outID] + require.True(t, ok, "Output ID not found in created outputs: %s, for slot %d", outID, slot) + require.Equal(t, out, createdMap[outID], "Output not equal for ID: %s, for slot %d", outID, slot) + } + + for outID, out := range a[slot].faucetOutputs { + _, ok := spentMap[outID] + require.True(t, ok, "Output ID not found in spent outputs: %s, for slot %d", outID, slot) + require.Equal(t, out, spentMap[outID], "Output not equal for ID: %s, for slot %d", outID, slot) + } +} + +type coreAPISlotAssets struct { + //slot iotago.SlotIndex + //epoch iotago.EpochIndex + accountAddress *iotago.AccountAddress + accountSlot iotago.SlotIndex + dataBlocks []*iotago.Block + valueBlocks []*iotago.Block + transactions []*iotago.SignedTransaction + basicOutputs map[iotago.OutputID]iotago.Output + faucetOutputs map[iotago.OutputID]iotago.Output + + commitmentPerNode map[string]iotago.CommitmentID +} + +func (a *coreAPISlotAssets) assertCommitments(t *testing.T) { + prevCommitment := a.commitmentPerNode["V1"] + for _, commitmentID := range a.commitmentPerNode { + if prevCommitment == iotago.EmptyCommitmentID { + require.Fail(t, "commitment is empty") + } + + require.Equal(t, commitmentID, prevCommitment) + } +} + +func newAssetsPerSlot() *coreAPISlotAssets { + return &coreAPISlotAssets{ + commitmentPerNode: make(map[string]iotago.CommitmentID), + dataBlocks: make([]*iotago.Block, 0), + valueBlocks: make([]*iotago.Block, 0), + transactions: make([]*iotago.SignedTransaction, 0), + basicOutputs: make(map[iotago.OutputID]iotago.Output), + faucetOutputs: make(map[iotago.OutputID]iotago.Output), + } +} + +func (d *DockerTestFramework) prepareAssets(totalAssetsNum int) (coreAPIAssets, iotago.SlotIndex) { + assets := make(coreAPIAssets) + ctx := context.Background() + account := d.CreateAccount() + accountSlot := account.OutputID.Slot() + latestSlot := iotago.SlotIndex(0) + assets.assetForSlot(accountSlot, account) + + for i := 0; i < totalAssetsNum; i++ { + fmt.Println("Creating asset: ", i) + block := d.CreateTaggedDataBlock(account.ID, []byte("tag")) + blockSlot := lo.PanicOnErr(block.ID()).Slot() + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot) + assets.assetForSlot(blockSlot, account).dataBlocks = append(assets[blockSlot].dataBlocks, block) + d.SubmitBlock(ctx, block) + + block, signedTx, faucetOutput, basicOut := d.CreateValueBlock(account.ID) + valueBlockSlot := block.MustID().Slot() + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, valueBlockSlot) + d.SubmitBlock(ctx, block) + + assets.assetForSlot(valueBlockSlot, account).valueBlocks = append(assets[valueBlockSlot].valueBlocks, block) + txSlot := lo.PanicOnErr(signedTx.ID()).Slot() + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, txSlot) + + assets.assetForSlot(txSlot, account).transactions = append(assets[txSlot].transactions, signedTx) + basicOutpID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + assets[txSlot].basicOutputs[basicOutpID] = basicOut + assets[txSlot].faucetOutputs[faucetOutput.ID] = faucetOutput.Output + time.Sleep(1 * time.Second) + } + + return assets, latestSlot +} + func (d *DockerTestFramework) requestFromClients(testFunc func(*testing.T, string)) { for alias := range d.nodes { testFunc(d.Testing, alias) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 3a52c3ef2..6053b8cf2 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -10,11 +10,12 @@ import ( "github.com/stretchr/testify/require" + "github.com/iotaledger/hive.go/lo" iotago "github.com/iotaledger/iota.go/v4" "github.com/iotaledger/iota.go/v4/api" ) -func Test_ValidatorAPI(t *testing.T) { +func Test_CoreAPI(t *testing.T) { d := NewDockerTestFramework(t, WithProtocolParametersOptions( iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4), @@ -30,47 +31,15 @@ func Test_ValidatorAPI(t *testing.T) { 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.WaitUntilNetworkReady() - - ctx := context.Background() - - prePreparedAssets := struct { - slot iotago.SlotIndex - epoch iotago.EpochIndex - dataBlock *iotago.Block - valueBlock *iotago.Block - transaction *iotago.SignedTransaction - transactionID iotago.TransactionID - basicOutput iotago.Output - basicOutputID iotago.OutputID - accountAddress *iotago.AccountAddress - }{ - slot: iotago.SlotIndex(2), - } - - sharedAssets := struct { - commitmentIDs map[string]iotago.CommitmentID - }{} - - clt := d.Node("V1").Client - prePreparedAssets.epoch = clt.APIForSlot(prePreparedAssets.slot).TimeProvider().EpochFromSlot(prePreparedAssets.slot) - prePreparedAssets.dataBlock = d.CreateTaggedDataBlock(d.Node("V1").AccountAddress(t).AccountID(), []byte{'t', 'a', 'g'}) + err := d.Run() + require.NoError(t, err) - block, signedTx, basicOut := d.CreateValueBlock("V1") - d.SubmitBlock(ctx, block) - - prePreparedAssets.valueBlock = block - prePreparedAssets.basicOutput = basicOut - prePreparedAssets.transaction = signedTx - txID, err := signedTx.Transaction.ID() - require.NoError(d.Testing, err) - prePreparedAssets.transactionID = txID - prePreparedAssets.basicOutputID = iotago.OutputIDFromTransactionIDAndIndex(txID, 0) + d.WaitUntilNetworkReady() - account := d.CreateAccount() - prePreparedAssets.accountAddress = account.Address + assetsPerSlot, lastSlot := d.prepareAssets(3) - d.AwaitCommitment(prePreparedAssets.slot) + fmt.Println("AwaitCommitment for slot", lastSlot) + d.AwaitCommitment(lastSlot) tests := []struct { name string @@ -79,136 +48,160 @@ func Test_ValidatorAPI(t *testing.T) { { name: "Test_Info", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.Info(context.Background()) + resp, err := d.wallet.Clients[nodeAlias].Info(context.Background()) require.NoError(t, err) require.NotNil(t, resp) - - fmt.Println(resp) }, }, { name: "Test_BlockByBlockID", testFunc: func(t *testing.T, nodeAlias string) { - respBlock, err := d.Node(nodeAlias).Client.BlockByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) - require.NoError(t, err) - require.NotNil(t, respBlock) - require.Equal(t, prePreparedAssets.dataBlock, respBlock) + assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { + respBlock, err := d.wallet.Clients[nodeAlias].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()) + //require.EqualValues(t, block, respBlock) + }) }, }, { name: "Test_BlockMetadataByBlockID", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.BlockMetadataByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) - require.NoError(t, err) - require.NotNil(t, resp) - - require.Equal(t, prePreparedAssets.dataBlock.MustID(), resp.BlockID) - require.Equal(t, api.BlockStateFinalized, resp.BlockState) + assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { + resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), block.MustID()) + require.NoError(t, err) + require.NotNil(t, resp) + //require.Equal(t, block.MustID(), resp.BlockID) + require.Equal(t, api.BlockStateFinalized, resp.BlockState) + }) }, }, { name: "Test_BlockWithMetadata", testFunc: func(t *testing.T, nodeAlias string) { - // TODO missing client side implementation - resp, err := d.Node(nodeAlias).Client.BlockMetadataByBlockID(context.Background(), prePreparedAssets.dataBlock.MustID()) - require.NoError(t, err) - require.NotNil(t, resp) + // TODO missing client side implementation for BlockWithMetadata + assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { + resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), block.MustID()) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, block.MustID(), resp.BlockID) + require.Equal(t, api.BlockStateFinalized, resp.BlockState) + }) }, }, { name: "Test_BlockIssuance", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.BlockIssuance(context.Background()) + resp, err := d.wallet.Clients[nodeAlias].BlockIssuance(context.Background()) require.NoError(t, err) require.NotNil(t, resp) - require.GreaterOrEqual(t, resp.StrongParents, 1) + require.GreaterOrEqual(t, len(resp.StrongParents), 1) }, }, { name: "Test_CommitmentBySlot", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentByIndex(context.Background(), prePreparedAssets.slot) - require.NoError(t, err) - require.NotNil(t, resp) - sharedAssets.commitmentIDs[nodeAlias] = resp.MustID() + assetsPerSlot.forEachSlot(t, func(t *testing.T, slot iotago.SlotIndex, sharedCommitments map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentByIndex(context.Background(), slot) + require.NoError(t, err) + require.NotNil(t, resp) + sharedCommitments[nodeAlias] = resp.MustID() + }) }, }, { name: "Test_CommitmentByID", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, sharedAssets.commitmentIDs[nodeAlias], resp.MustID()) + assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentByID(context.Background(), commitmentsPerNode[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, commitmentsPerNode[nodeAlias], resp.MustID()) + }) }, }, { name: "Test_CommitmentUTXOChangesByID", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) - require.NoError(t, err) - require.NotNil(t, resp) - fmt.Println(resp) + assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesByID(context.Background(), commitmentsPerNode[nodeAlias]) + 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) + }) }, }, { - name: "Test_CommitmentUTXOChangesFullByID", - testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesFullByID(context.Background(), sharedAssets.commitmentIDs[nodeAlias]) - require.NoError(t, err) - require.NotNil(t, resp) - fmt.Println(resp) + "Test_CommitmentUTXOChangesFullByID", + func(t *testing.T, nodeAlias string) { + assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesFullByID(context.Background(), commitmentsPerNode[nodeAlias]) + 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) + }) }, }, { name: "Test_CommitmentUTXOChangesBySlot", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesByIndex(context.Background(), prePreparedAssets.slot) - require.NoError(t, err) - require.NotNil(t, resp) - // check by what I have sent - - resp, err = d.Node(nodeAlias).Client.CommitmentUTXOChangesByIndex(context.Background(), sharedAssets.commitmentIDs[nodeAlias].Slot()) - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, sharedAssets.commitmentIDs[nodeAlias], resp.CommitmentID) - - // todo check with by commitment resp - + assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesByIndex(context.Background(), commitmentsPerNode[nodeAlias].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) + }) }, }, { name: "Test_CommitmentUTXOChangesFullBySlot", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.CommitmentUTXOChangesFullByIndex(context.Background(), prePreparedAssets.slot) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachCommitment(t, func(t *testing.T, commitmentsPerNode map[string]iotago.CommitmentID) { + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesFullByIndex(context.Background(), commitmentsPerNode[nodeAlias].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) + }) }, }, { name: "Test_OutputByID", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.OutputByID(context.Background(), prePreparedAssets.basicOutputID) - require.NoError(t, err) - require.NotNil(t, resp) - // todo calculate outID + assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { + resp, err := d.wallet.Clients[nodeAlias].OutputByID(context.Background(), outputID) + require.NoError(t, err) + require.NotNil(t, resp) + require.EqualValues(t, output, resp) + }) }, }, { name: "Test_OutputMetadata", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.OutputMetadataByID(context.Background(), prePreparedAssets.basicOutputID) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { + resp, err := d.wallet.Clients[nodeAlias].OutputMetadataByID(context.Background(), outputID) + require.NoError(t, err) + require.NotNil(t, resp) + require.EqualValues(t, outputID, resp.OutputID) + require.EqualValues(t, outputID.Slot(), resp.Included.Slot) + require.EqualValues(t, outputID.TransactionID(), resp.Included.TransactionID) + }) }, }, { name: "Test_TransactionsIncludedBlock", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.TransactionIncludedBlock(context.Background(), prePreparedAssets.transactionID) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlock(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) + require.NoError(t, err) + require.NotNil(t, resp) + }) // todo issue second block with the same tx, and make sure that the first one is returned here }, @@ -216,41 +209,49 @@ func Test_ValidatorAPI(t *testing.T) { { name: "Test_TransactionsIncludedBlockMetadata", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.TransactionIncludedBlockMetadata(context.Background(), prePreparedAssets.transactionID) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlockMetadata(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) + require.NoError(t, err) + require.NotNil(t, resp) + }) }, }, { name: "Test_TransactionsMetadata", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.TransactionMetadata(context.Background(), prePreparedAssets.transactionID) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + resp, err := d.wallet.Clients[nodeAlias].TransactionMetadata(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, api.TransactionStateFinalized, resp.TransactionState) + }) }, }, { name: "Test_Congestion", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.Congestion(context.Background(), d.Node(nodeAlias).AccountAddress(t), 0) - require.NoError(t, err) - require.NotNil(t, resp) + assetsPerSlot.forEachAccountAddress(t, func(t *testing.T, accountAddress *iotago.AccountAddress, commitmentPerNode map[string]iotago.CommitmentID) { - resp, err = d.Node(nodeAlias).Client.Congestion(context.Background(), prePreparedAssets.accountAddress, 0, sharedAssets.commitmentIDs[nodeAlias]) - require.NoError(t, err) - require.NotNil(t, resp) + resp, err := d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0) + require.NoError(t, err) + require.NotNil(t, resp) + + resp, err = d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0, commitmentPerNode[nodeAlias]) + require.NoError(t, err) + require.NotNil(t, resp) + }) }, }, { name: "Test_Validators", testFunc: func(t *testing.T, nodeAlias string) { pageSize := uint64(3) - resp, err := d.Node(nodeAlias).Client.Validators(context.Background(), pageSize) + resp, err := d.wallet.Clients[nodeAlias].Validators(context.Background(), pageSize) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, len(resp.Validators), int(pageSize)) - resp, err = d.Node(nodeAlias).Client.Validators(context.Background(), pageSize, resp.Cursor) + resp, err = d.wallet.Clients[nodeAlias].Validators(context.Background(), pageSize, resp.Cursor) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, len(resp.Validators), 1) @@ -259,7 +260,7 @@ func Test_ValidatorAPI(t *testing.T) { { name: "Test_ValidatorsAll", testFunc: func(t *testing.T, nodeAlias string) { - resp, all, err := d.Node(nodeAlias).Client.ValidatorsAll(context.Background()) + resp, all, err := d.wallet.Clients[nodeAlias].ValidatorsAll(context.Background()) require.NoError(t, err) require.True(t, all) require.Equal(t, 4, len(resp.Validators)) @@ -268,15 +269,13 @@ func Test_ValidatorAPI(t *testing.T) { { name: "Test_Rewards", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.Rewards(context.Background(), prePreparedAssets.basicOutputID) - require.NoError(t, err) - require.NotNil(t, resp) + //skip: we will test it with caliming tests }, }, { name: "Test_Committee", testFunc: func(t *testing.T, nodeAlias string) { - resp, err := d.Node(nodeAlias).Client.Committee(context.Background(), prePreparedAssets.epoch) + resp, err := d.wallet.Clients[nodeAlias].Committee(context.Background()) require.NoError(t, err) require.NotNil(t, resp) }, @@ -289,5 +288,5 @@ func Test_ValidatorAPI(t *testing.T) { }) } - // TDO Assert shared assets are the same + assetsPerSlot.assertCommitments(t) } diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index 10e37e03d..249076888 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -369,24 +369,22 @@ func (d *DockerTestFramework) CreateTaggedDataBlock(issuerId iotago.AccountID, t issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - return d.CreateBlock(ctx, &iotago.TaggedData{ + return d.CreateBlock(&iotago.TaggedData{ Tag: tag, }, issuerId, congestionResp, issuerResp) } -func (d *DockerTestFramework) CreateValueBlock(nodeAlias string) (*iotago.Block, *iotago.SignedTransaction, iotago.Output) { +func (d *DockerTestFramework) CreateValueBlock(issuerAccountID iotago.AccountID) (*iotago.Block, *iotago.SignedTransaction, *OutputData, iotago.Output) { + clt := d.wallet.DefaultClient() ctx := context.Background() - clt := d.Node(nodeAlias).Client currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now()) apiForSlot := clt.APIForSlot(currentSlot) - fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) _, ed25519Addr := d.wallet.Address() input := d.wallet.Output(fundsOutputID) basicOutput := builder.NewBasicOutputBuilder(ed25519Addr, input.Output.BaseTokenAmount()).MustBuild() - - signedTx, err := builder.NewTransactionBuilder(apiForSlot). + signedTx, err := builder.NewTransactionBuilder(apiForSlot, d.wallet.AddressSigner(input.AddressIndex)). AddInput(&builder.TxInput{ UnlockTarget: input.Address, InputID: input.ID, @@ -394,13 +392,14 @@ func (d *DockerTestFramework) CreateValueBlock(nodeAlias string) (*iotago.Block, }). AddOutput(basicOutput). SetCreationSlot(currentSlot). - Build(d.wallet.AddressSigner(input.AddressIndex)) + AllotAllMana(currentSlot, issuerAccountID, 0). + Build() require.NoError(d.wallet.Testing, err) - issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, d.Node(nodeAlias).AccountAddress(d.Testing)) - block := d.CreateBlock(ctx, signedTx, d.Node(nodeAlias).AccountAddress(d.Testing).AccountID(), congestionResp, issuerResp) + issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuerAccountID.ToAddress().(*iotago.AccountAddress)) + block := d.CreateBlock(signedTx, issuerAccountID, congestionResp, issuerResp) - return block, signedTx, basicOutput + return block, signedTx, input, basicOutput } // CreateDelegationBlockFromInput consumes the given basic output, then build a block of a transaction that includes a delegation output, in order to delegate the given validator. @@ -416,7 +415,7 @@ func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerId iotago.Acc return iotago.DelegationIDFromOutputID(outputId), outputId, - d.CreateBlock(ctx, signedTx, issuerId, congestionResp, issuerResp) + d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) } // CreateFoundryBlockFromInput consumes the given basic output, then build a block of a transaction that includes a foundry output with the given mintedAmount and maxSupply. @@ -432,7 +431,7 @@ func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerId iotago.Accoun return signedTx.Transaction.Outputs[1].(*iotago.FoundryOutput).MustFoundryID(), iotago.OutputIDFromTransactionIDAndIndex(txId, 1), - d.CreateBlock(ctx, signedTx, issuerId, congestionResp, issuerResp) + d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) } // CreateNFTBlockFromInput consumes the given basic output, then build a block of a transaction that includes a NFT output with the given NFT output options. @@ -447,7 +446,7 @@ func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerId iotago.AccountID, return iotago.NFTIDFromOutputID(outputId), outputId, - d.CreateBlock(ctx, signedTx, issuerId, congestionResp, issuerResp) + d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) } // CreateFoundryTransitionBlockFromInput consumes the given foundry output, then build block by increasing the minted amount by 1. @@ -463,7 +462,7 @@ func (d *DockerTestFramework) CreateFoundryTransitionBlockFromInput(issuerId iot return signedTx.Transaction.Outputs[1].(*iotago.FoundryOutput).MustFoundryID(), iotago.OutputIDFromTransactionIDAndIndex(txId, 1), - d.CreateBlock(ctx, signedTx, issuerId, congestionResp, issuerResp) + d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) } // CreateAccountBlockFromInput consumes the given output, which should be either an basic output with implicit address, then build block with the given account output options. Note that after the returned transaction is issued, remember to update the account information in the wallet with AddAccount(). @@ -485,7 +484,7 @@ func (d *DockerTestFramework) CreateAccountBlockFromInput(inputId iotago.OutputI return fullAccount, iotago.OutputIDFromTransactionIDAndIndex(txId, 0), - d.CreateBlock(ctx, signedTx, fullAccount.ID, congestionResp, issuerResp) + d.CreateBlock(signedTx, fullAccount.ID, congestionResp, issuerResp) } // CreateImplicitAccount requests faucet funds and creates an implicit account. It already wait until the transaction is committed and the created account is useable. @@ -733,7 +732,7 @@ func (d *DockerTestFramework) GetContainersConfigs() { } } -func (d *DockerTestFramework) CreateBlock(ctx context.Context, payload iotago.Payload, issuerId iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.Block { +func (d *DockerTestFramework) CreateBlock(payload iotago.Payload, issuerId iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.Block { clt := d.wallet.DefaultClient() issuingTime := time.Now() apiForSlot := clt.APIForSlot(clt.LatestAPI().TimeProvider().SlotFromTime(issuingTime)) @@ -770,7 +769,7 @@ func (d *DockerTestFramework) SubmitBlock(ctx context.Context, blk *iotago.Block func (d *DockerTestFramework) SubmitPayload(ctx context.Context, payload iotago.Payload, issuerId iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) iotago.BlockID { clt := d.wallet.DefaultClient() - blk := d.CreateBlock(ctx, payload, issuerId, congestionResp, issuerResp) + blk := d.CreateBlock(payload, issuerId, congestionResp, issuerResp) blkID, err := clt.SubmitBlock(ctx, blk) require.NoError(d.Testing, err) From aa0a1d6930100b7453e485545e3fdc2ed46b3892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Wed, 6 Mar 2024 14:26:11 +0100 Subject: [PATCH 03/22] Corrections for HTTP error codes --- components/restapi/core/accounts.go | 21 ++++++++++++++++++--- components/restapi/core/component.go | 22 +++++++++++----------- components/restapi/core/transaction.go | 2 +- pkg/requesthandler/accounts.go | 7 +++++-- pkg/requesthandler/blocks.go | 4 ++-- pkg/requesthandler/commitments.go | 8 ++++---- pkg/requesthandler/transaction.go | 2 +- pkg/requesthandler/utxo.go | 6 +++--- 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 8c09be967..e97ccad18 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -11,7 +11,7 @@ import ( ) func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) { - commitmentID, err := httpserver.ParseCommitmentIDQueryParam(c, api.ParameterCommitmentID) + queryCommitmentID, err := httpserver.ParseCommitmentIDQueryParam(c, api.ParameterCommitmentID) if err != nil { return nil, err } @@ -27,7 +27,7 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) workScores = append(workScores, workScore) } - commitment, err := deps.RequestHandler.GetCommitmentByID(commitmentID) + commitment, err := deps.RequestHandler.GetCommitmentByID(queryCommitmentID) if err != nil { return nil, err } @@ -43,6 +43,16 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(api.ParameterBech32Address)) } + maxCommittableAge := deps.RequestHandler.CommittedAPI().ProtocolParameters().MaxCommittableAge() + latestCommittedSlot := deps.RequestHandler.GetLatestCommitment().Slot() + if latestCommittedSlot >= maxCommittableAge && commitment.Slot()+maxCommittableAge < latestCommittedSlot && queryCommitmentID != iotago.EmptyCommitmentID { + return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, target slot index older than allowed (%d<%d)", commitment.Slot(), latestCommittedSlot-maxCommittableAge) + } + + if commitment.Slot() > latestCommittedSlot && queryCommitmentID != iotago.EmptyCommitmentID { + return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, slot %d is not committed yet, latest committed slot: %d", commitment.Slot(), latestCommittedSlot) + } + return deps.RequestHandler.CongestionByAccountAddress(accountAddress, commitment, workScores...) } @@ -86,6 +96,7 @@ func validatorByAccountAddress(c echo.Context) (*api.ValidatorResponse, error) { } func rewardsByOutputID(c echo.Context) (*api.ManaRewardsResponse, error) { + var err error outputID, err := httpserver.ParseOutputIDParam(c, api.ParameterOutputID) if err != nil { return nil, ierrors.Wrapf(err, "failed to parse output ID %s", c.Param(api.ParameterOutputID)) @@ -93,7 +104,6 @@ func rewardsByOutputID(c echo.Context) (*api.ManaRewardsResponse, error) { var slot iotago.SlotIndex if len(c.QueryParam(api.ParameterSlot)) > 0 { - var err error slot, err = httpserver.ParseSlotQueryParam(c, api.ParameterSlot) if err != nil { return nil, ierrors.Wrapf(err, "failed to parse slot index %s", c.Param(api.ParameterSlot)) @@ -113,6 +123,7 @@ func rewardsByOutputID(c echo.Context) (*api.ManaRewardsResponse, error) { func selectedCommittee(c echo.Context) (*api.CommitteeResponse, error) { var epoch iotago.EpochIndex + if len(c.QueryParam(api.ParameterEpoch)) == 0 { // by default we return current epoch epoch = deps.RequestHandler.CommittedAPI().TimeProvider().CurrentEpoch() @@ -122,6 +133,10 @@ func selectedCommittee(c echo.Context) (*api.CommitteeResponse, error) { if err != nil { return nil, err } + currentEpoch := deps.RequestHandler.CommittedAPI().TimeProvider().CurrentEpoch() + if epoch > currentEpoch { + return nil, ierrors.Wrapf(echo.ErrBadRequest, "provided epoch %d is from the future, current epoch: %d", epoch, currentEpoch) + } } return deps.RequestHandler.SelectedCommittee(epoch) diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index b83b32100..9f576f06b 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -70,7 +70,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointBlockMetadata), func(c echo.Context) error { resp, err := blockMetadataByID(c) @@ -121,7 +121,7 @@ func configure() error { } return responseByHeader(c, commitment.Commitment()) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentByIDUTXOChanges), func(c echo.Context) error { commitmentID, err := httpserver.ParseCommitmentIDParam(c, api.ParameterCommitmentID) @@ -141,7 +141,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentByIDUTXOChangesFull), func(c echo.Context) error { commitmentID, err := httpserver.ParseCommitmentIDParam(c, api.ParameterCommitmentID) @@ -161,7 +161,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlot), func(c echo.Context) error { index, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -175,7 +175,7 @@ func configure() error { } return responseByHeader(c, commitment.Commitment()) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlotUTXOChanges), func(c echo.Context) error { slot, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -194,7 +194,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlotUTXOChangesFull), func(c echo.Context) error { slot, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -213,7 +213,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointOutput), func(c echo.Context) error { resp, err := outputFromOutputID(c) @@ -222,7 +222,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointOutputMetadata), func(c echo.Context) error { resp, err := outputMetadataFromOutputID(c) @@ -231,7 +231,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointOutputWithMetadata), func(c echo.Context) error { resp, err := outputWithMetadataFromOutputID(c) @@ -240,7 +240,7 @@ func configure() error { } return responseByHeader(c, resp) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointTransactionsIncludedBlock), func(c echo.Context) error { block, err := blockFromTransactionID(c) @@ -249,7 +249,7 @@ func configure() error { } return responseByHeader(c, block) - }) + }, checkNodeSynced()) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointTransactionsIncludedBlockMetadata), func(c echo.Context) error { resp, err := blockMetadataFromTransactionID(c) diff --git a/components/restapi/core/transaction.go b/components/restapi/core/transaction.go index de83c9cc4..310ae64d7 100644 --- a/components/restapi/core/transaction.go +++ b/components/restapi/core/transaction.go @@ -49,7 +49,7 @@ func transactionMetadataFromTransactionID(c echo.Context) (*api.TransactionMetad blockID, err := deps.RequestHandler.BlockIDFromTransactionID(txID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "failed to get block ID from transaction ID: %v", err) + return nil, ierrors.Wrapf(echo.ErrBadRequest, "failed to get block ID from transaction ID: %v", err) } metadata, err := deps.RequestHandler.TransactionMetadataByBlockID(blockID) diff --git a/pkg/requesthandler/accounts.go b/pkg/requesthandler/accounts.go index 97f9c97e7..5028bdc5e 100644 --- a/pkg/requesthandler/accounts.go +++ b/pkg/requesthandler/accounts.go @@ -93,7 +93,7 @@ func (r *RequestHandler) ValidatorByAccountAddress(accountAddress *iotago.Accoun func (r *RequestHandler) RewardsByOutputID(outputID iotago.OutputID, slot iotago.SlotIndex) (*api.ManaRewardsResponse, error) { utxoOutput, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) } var stakingPoolValidatorAccountID iotago.AccountID @@ -149,16 +149,19 @@ func (r *RequestHandler) RewardsByOutputID(outputID iotago.OutputID, slot iotago delegationEnd, claimingEpoch, ) + default: + return nil, ierrors.Wrapf(echo.ErrBadRequest, "output %s is neither a delegation output nor account", outputID.ToHex()) } + if err != nil { return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to calculate reward for output %s: %s", outputID.ToHex(), err) } latestCommittedEpochPoolRewards, poolRewardExists, err := r.protocol.Engines.Main.Get().SybilProtection.PoolRewardsForAccount(stakingPoolValidatorAccountID) - if err != nil { return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to retrieve pool rewards for account %s: %s", stakingPoolValidatorAccountID.ToHex(), err) } + if !poolRewardExists { latestCommittedEpochPoolRewards = 0 } diff --git a/pkg/requesthandler/blocks.go b/pkg/requesthandler/blocks.go index b10e6ca34..6b592389e 100644 --- a/pkg/requesthandler/blocks.go +++ b/pkg/requesthandler/blocks.go @@ -23,7 +23,7 @@ func (r *RequestHandler) BlockByID(blockID iotago.BlockID) (*iotago.Block, error func (r *RequestHandler) BlockMetadataByBlockID(blockID iotago.BlockID) (*api.BlockMetadataResponse, error) { blockMetadata, err := r.protocol.Engines.Main.Get().Retainer.BlockMetadata(blockID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "metadata not found for block %s: %s", blockID.ToHex(), err) } return blockMetadata.BlockMetadataResponse(), nil @@ -32,7 +32,7 @@ func (r *RequestHandler) BlockMetadataByBlockID(blockID iotago.BlockID) (*api.Bl func (r *RequestHandler) TransactionMetadataByBlockID(blockID iotago.BlockID) (*api.TransactionMetadataResponse, error) { blockMetadata, err := r.protocol.Engines.Main.Get().Retainer.BlockMetadata(blockID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "transaction metadata not found for block %s: %s", blockID.ToHex(), err) } metadata := blockMetadata.TransactionMetadataResponse() diff --git a/pkg/requesthandler/commitments.go b/pkg/requesthandler/commitments.go index 5cdcf6abc..558a5828a 100644 --- a/pkg/requesthandler/commitments.go +++ b/pkg/requesthandler/commitments.go @@ -19,7 +19,7 @@ func (r *RequestHandler) GetCommitmentBySlot(slot iotago.SlotIndex) (*model.Comm commitment, err := r.protocol.Engines.Main.Get().Storage.Commitments().Load(slot) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, slot: %d, error: %w", slot, err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, slot: %d, error: %v", slot, err) } return commitment, nil @@ -38,7 +38,7 @@ func (r *RequestHandler) GetCommitmentByID(commitmentID iotago.CommitmentID) (*m commitment, err := r.protocol.Engines.Main.Get().Storage.Commitments().Load(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, commitmentID: %s, slot: %d, error: %w", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) } if commitment.ID() != commitmentID { @@ -55,7 +55,7 @@ func (r *RequestHandler) GetLatestCommitment() *model.Commitment { func (r *RequestHandler) GetUTXOChanges(commitmentID iotago.CommitmentID) (*api.UTXOChangesResponse, error) { diffs, err := r.protocol.Engines.Main.Get().Ledger.SlotDiffs(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %w", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) } createdOutputs := make(iotago.OutputIDs, len(diffs.Outputs)) @@ -79,7 +79,7 @@ func (r *RequestHandler) GetUTXOChanges(commitmentID iotago.CommitmentID) (*api. func (r *RequestHandler) GetUTXOChangesFull(commitmentID iotago.CommitmentID) (*api.UTXOChangesFullResponse, error) { diffs, err := r.protocol.Engines.Main.Get().Ledger.SlotDiffs(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %w", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) } createdOutputs := make([]*api.OutputWithID, len(diffs.Outputs)) diff --git a/pkg/requesthandler/transaction.go b/pkg/requesthandler/transaction.go index 8c048b129..24ba4696f 100644 --- a/pkg/requesthandler/transaction.go +++ b/pkg/requesthandler/transaction.go @@ -14,7 +14,7 @@ func (r *RequestHandler) BlockIDFromTransactionID(transactionID iotago.Transacti output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return iotago.EmptyBlockID, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s: %s", outputID.ToHex(), err) + return iotago.EmptyBlockID, ierrors.Wrapf(echo.ErrNotFound, "output %s of transaction %s not found: %s", transactionID.ToHex(), outputID.ToHex(), err) } if output != nil { diff --git a/pkg/requesthandler/utxo.go b/pkg/requesthandler/utxo.go index c9bd951df..f5a2b7a96 100644 --- a/pkg/requesthandler/utxo.go +++ b/pkg/requesthandler/utxo.go @@ -12,7 +12,7 @@ import ( func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.OutputResponse, error) { output, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) } return &api.OutputResponse{ @@ -24,7 +24,7 @@ func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.Outp func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputMetadata, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the ledger: %s", outputID.ToHex(), err) } if spent != nil { @@ -37,7 +37,7 @@ func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (* func (r *RequestHandler) OutputWithMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputWithMetadataResponse, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) } if spent != nil { From d0aca23d73199d5e52624eb5d17cc6729900cf02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Wed, 6 Mar 2024 16:18:45 +0100 Subject: [PATCH 04/22] Clean up and fix linter in docker tests --- tools/docker-network/tests/coreapi_test.go | 8 +- tools/docker-network/tests/dockerframework.go | 112 ++++++++-------- tools/docker-network/tests/eventapi.go | 72 +++++++---- tools/docker-network/tests/eventapi_test.go | 35 +++-- tools/docker-network/tests/options.go | 3 +- tools/docker-network/tests/utils.go | 10 +- tools/docker-network/tests/wallet.go | 122 +++++++++--------- 7 files changed, 194 insertions(+), 168 deletions(-) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 6053b8cf2..49e27d1ae 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -31,8 +31,8 @@ func Test_CoreAPI(t *testing.T) { d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw") d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090") - err := d.Run() - require.NoError(t, err) + runErr := d.Run() + require.NoError(t, runErr) d.WaitUntilNetworkReady() @@ -103,11 +103,11 @@ func Test_CoreAPI(t *testing.T) { { name: "Test_CommitmentBySlot", testFunc: func(t *testing.T, nodeAlias string) { - assetsPerSlot.forEachSlot(t, func(t *testing.T, slot iotago.SlotIndex, sharedCommitments map[string]iotago.CommitmentID) { + assetsPerSlot.forEachSlot(t, func(t *testing.T, slot iotago.SlotIndex, commitmentsPerNode map[string]iotago.CommitmentID) { resp, err := d.wallet.Clients[nodeAlias].CommitmentByIndex(context.Background(), slot) require.NoError(t, err) require.NotNil(t, resp) - sharedCommitments[nodeAlias] = resp.MustID() + commitmentsPerNode[nodeAlias] = resp.MustID() }) }, }, diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index 249076888..c31c30d52 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -30,7 +30,7 @@ import ( ) var ( - // need to build snapshotfile in tools/docker-network + // need to build snapshotfile in tools/docker-network. snapshotFilePath = "../docker-network.snapshot" keyManager = func() *wallet.KeyManager { genesisSeed, err := base58.Decode("7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih") @@ -96,7 +96,7 @@ func NewDockerTestFramework(t *testing.T, opts ...options.Option[DockerTestFrame }, opts, func(d *DockerTestFramework) { d.optsProtocolParameterOptions = append(DefaultProtocolParametersOptions, d.optsProtocolParameterOptions...) protocolParams := iotago.NewV3SnapshotProtocolParameters(d.optsProtocolParameterOptions...) - api := iotago.V3API(protocolParams) + testAPI := iotago.V3API(protocolParams) d.logDirectoryPath = createLogDirectory(t.Name()) d.snapshotPath = snapshotFilePath @@ -104,9 +104,9 @@ func NewDockerTestFramework(t *testing.T, opts ...options.Option[DockerTestFrame []options.Option[snapshotcreator.Options]{ snapshotcreator.WithDatabaseVersion(protocol.DatabaseVersion), snapshotcreator.WithFilePath(d.snapshotPath), - snapshotcreator.WithProtocolParameters(api.ProtocolParameters()), + snapshotcreator.WithProtocolParameters(testAPI.ProtocolParameters()), snapshotcreator.WithRootBlocks(map[iotago.BlockID]iotago.CommitmentID{ - api.ProtocolParameters().GenesisBlockID(): iotago.NewEmptyCommitment(api).MustID(), + testAPI.ProtocolParameters().GenesisBlockID(): iotago.NewEmptyCommitment(testAPI).MustID(), }), snapshotcreator.WithGenesisKeyManager(keyManager()), }...) @@ -346,7 +346,8 @@ func (d *DockerTestFramework) StartIssueCandidacyPayload(nodes ...*Node) { node.IssueCandidacyPayload = true } - d.DockerComposeUp(true) + err := d.DockerComposeUp(true) + require.NoError(d.Testing, err) } func (d *DockerTestFramework) StopIssueCandidacyPayload(nodes ...*Node) { @@ -358,12 +359,13 @@ func (d *DockerTestFramework) StopIssueCandidacyPayload(nodes ...*Node) { node.IssueCandidacyPayload = false } - d.DockerComposeUp(true) + err := d.DockerComposeUp(true) + require.NoError(d.Testing, err) } // CreateTaggedDataBlock creates a block of a tagged data payload. -func (d *DockerTestFramework) CreateTaggedDataBlock(issuerId iotago.AccountID, tag []byte) *iotago.Block { - issuer := d.wallet.Account(issuerId) +func (d *DockerTestFramework) CreateTaggedDataBlock(issuerID iotago.AccountID, tag []byte) *iotago.Block { + issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() @@ -371,7 +373,7 @@ func (d *DockerTestFramework) CreateTaggedDataBlock(issuerId iotago.AccountID, t return d.CreateBlock(&iotago.TaggedData{ Tag: tag, - }, issuerId, congestionResp, issuerResp) + }, issuerID, congestionResp, issuerResp) } func (d *DockerTestFramework) CreateValueBlock(issuerAccountID iotago.AccountID) (*iotago.Block, *iotago.SignedTransaction, *OutputData, iotago.Output) { @@ -403,35 +405,36 @@ func (d *DockerTestFramework) CreateValueBlock(issuerAccountID iotago.AccountID) } // CreateDelegationBlockFromInput consumes the given basic output, then build a block of a transaction that includes a delegation output, in order to delegate the given validator. -func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerId iotago.AccountID, validator *Node, inputId iotago.OutputID) (iotago.DelegationID, iotago.OutputID, *iotago.Block) { - issuer := d.wallet.Account(issuerId) +func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerID iotago.AccountID, validator *Node, inputID iotago.OutputID) (iotago.DelegationID, iotago.OutputID, *iotago.Block) { + issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateDelegationFromInput(issuerId, validator, inputId, issuerResp) - outputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + signedTx := d.wallet.CreateDelegationFromInput(issuerID, validator, inputID, issuerResp) + outputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - return iotago.DelegationIDFromOutputID(outputId), - outputId, - d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) + return iotago.DelegationIDFromOutputID(outputID), + outputID, + d.CreateBlock(signedTx, issuerID, congestionResp, issuerResp) } // CreateFoundryBlockFromInput consumes the given basic output, then build a block of a transaction that includes a foundry output with the given mintedAmount and maxSupply. -func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerId iotago.AccountID, inputId iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { - issuer := d.wallet.Account(issuerId) +func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerID iotago.AccountID, inputId iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { + issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(issuerId, inputId, mintedAmount, maxSupply, issuerResp) - txId, err := signedTx.Transaction.ID() + signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(issuerID, inputId, mintedAmount, maxSupply, issuerResp) + txID, err := signedTx.Transaction.ID() require.NoError(d.Testing, err) + //nolint:forcetypeassert return signedTx.Transaction.Outputs[1].(*iotago.FoundryOutput).MustFoundryID(), - iotago.OutputIDFromTransactionIDAndIndex(txId, 1), - d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) + iotago.OutputIDFromTransactionIDAndIndex(txID, 1), + d.CreateBlock(signedTx, issuerID, congestionResp, issuerResp) } // CreateNFTBlockFromInput consumes the given basic output, then build a block of a transaction that includes a NFT output with the given NFT output options. @@ -442,48 +445,49 @@ func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerId iotago.AccountID, issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) signedTx := d.wallet.CreateNFTFromInput(issuerId, inputId, issuerResp, opts...) - outputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + outputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - return iotago.NFTIDFromOutputID(outputId), - outputId, + return iotago.NFTIDFromOutputID(outputID), + outputID, d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) } // CreateFoundryTransitionBlockFromInput consumes the given foundry output, then build block by increasing the minted amount by 1. -func (d *DockerTestFramework) CreateFoundryTransitionBlockFromInput(issuerId iotago.AccountID, inputId iotago.OutputID) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateFoundryTransitionBlockFromInput(issuerID iotago.AccountID, inputID iotago.OutputID) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { ctx := context.TODO() clt := d.wallet.DefaultClient() - issuer := d.wallet.Account(issuerId) + issuer := d.wallet.Account(issuerID) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.TransitionFoundry(issuerId, inputId, issuerResp) - txId, err := signedTx.Transaction.ID() + signedTx := d.wallet.TransitionFoundry(issuerID, inputID, issuerResp) + txID, err := signedTx.Transaction.ID() require.NoError(d.Testing, err) + //nolint:forcetypeassert return signedTx.Transaction.Outputs[1].(*iotago.FoundryOutput).MustFoundryID(), - iotago.OutputIDFromTransactionIDAndIndex(txId, 1), - d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) + iotago.OutputIDFromTransactionIDAndIndex(txID, 1), + d.CreateBlock(signedTx, issuerID, congestionResp, issuerResp) } // CreateAccountBlockFromInput consumes the given output, which should be either an basic output with implicit address, then build block with the given account output options. Note that after the returned transaction is issued, remember to update the account information in the wallet with AddAccount(). -func (d *DockerTestFramework) CreateAccountBlockFromInput(inputId iotago.OutputID, opts ...options.Option[builder.AccountOutputBuilder]) (*AccountData, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateAccountBlockFromInput(inputID iotago.OutputID, opts ...options.Option[builder.AccountOutputBuilder]) (*AccountData, iotago.OutputID, *iotago.Block) { ctx := context.TODO() clt := d.wallet.DefaultClient() - input := d.wallet.Output(inputId) + input := d.wallet.Output(inputID) // check if the given input is an BasicOutput with implicit address implicitOutput, ok := input.Output.(*iotago.BasicOutput) require.True(d.Testing, ok) require.Equal(d.Testing, iotago.AddressImplicitAccountCreation, implicitOutput.UnlockConditionSet().Address().Address.Type()) - accAddress := iotago.AccountAddressFromOutputID(inputId) + accAddress := iotago.AccountAddressFromOutputID(inputID) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, accAddress) fullAccount, signedTx := d.wallet.TransitionImplicitAccountToAccountOutput(input.ID, issuerResp) - txId, err := signedTx.Transaction.ID() + txID, err := signedTx.Transaction.ID() require.NoError(d.Testing, err) return fullAccount, - iotago.OutputIDFromTransactionIDAndIndex(txId, 0), + iotago.OutputIDFromTransactionIDAndIndex(txID, 0), d.CreateBlock(signedTx, fullAccount.ID, congestionResp, issuerResp) } @@ -536,8 +540,8 @@ func (d *DockerTestFramework) CreateAccount(opts ...options.Option[builder.Accou } // DelegateToValidator requests faucet funds and delegate the UTXO output to the validator. -func (d *DockerTestFramework) DelegateToValidator(fromId iotago.AccountID, validator *Node) iotago.EpochIndex { - from := d.wallet.Account(fromId) +func (d *DockerTestFramework) DelegateToValidator(fromID iotago.AccountID, validator *Node) iotago.EpochIndex { + from := d.wallet.Account(fromID) clt := d.wallet.Clients[validator.Name] // requesting faucet funds as delegation input @@ -545,12 +549,13 @@ func (d *DockerTestFramework) DelegateToValidator(fromId iotago.AccountID, valid fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, from.Address) - signedTx := d.wallet.CreateDelegationFromInput(fromId, validator, fundsOutputID, issuerResp) + signedTx := d.wallet.CreateDelegationFromInput(fromID, validator, fundsOutputID, issuerResp) blkID := d.SubmitPayload(ctx, signedTx, from.ID, congestionResp, issuerResp) d.AwaitTransactionPayloadAccepted(ctx, blkID) - delegationOutput := signedTx.Transaction.Outputs[0].(*iotago.DelegationOutput) + delegationOutput, ok := signedTx.Transaction.Outputs[0].(*iotago.DelegationOutput) + require.True(d.Testing, ok) return delegationOutput.StartEpoch } @@ -567,16 +572,16 @@ func (d *DockerTestFramework) PrepareBlockIssuance(ctx context.Context, clt *nod } // AllotManaTo requests faucet funds then uses it to allots mana from one account to another. -func (d *DockerTestFramework) AllotManaTo(fromId iotago.AccountID, toId iotago.AccountID, manaToAllot iotago.Mana) { - from := d.wallet.Account(fromId) - to := d.wallet.Account(toId) +func (d *DockerTestFramework) AllotManaTo(fromID iotago.AccountID, toID iotago.AccountID, manaToAllot iotago.Mana) { + from := d.wallet.Account(fromID) + to := d.wallet.Account(toID) // requesting faucet funds for allotment ctx := context.TODO() fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, from.Address) - signedTx := d.wallet.AllotManaFromAccount(fromId, toId, manaToAllot, fundsOutputID, issuerResp) + signedTx := d.wallet.AllotManaFromAccount(fromID, toID, manaToAllot, fundsOutputID) blkID := d.SubmitPayload(ctx, signedTx, from.ID, congestionResp, issuerResp) fmt.Println("Allot mana transaction sent, blkID:", blkID.ToHex(), ", txID:", lo.PanicOnErr(signedTx.Transaction.ID()).ToHex(), ", slot:", blkID.Slot()) @@ -598,18 +603,18 @@ func (d *DockerTestFramework) AllotManaTo(fromId iotago.AccountID, toId iotago.A } // CreateNativeToken request faucet funds then use it to create native token for the account, and returns the updated Account. -func (d *DockerTestFramework) CreateNativeToken(fromId iotago.AccountID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) { +func (d *DockerTestFramework) CreateNativeToken(fromID iotago.AccountID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) { require.GreaterOrEqual(d.Testing, maxSupply, mintedAmount) ctx := context.TODO() clt := d.wallet.DefaultClient() - from := d.wallet.Account(fromId) + from := d.wallet.Account(fromID) // requesting faucet funds for native token creation fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, from.Address) - signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(fromId, fundsOutputID, mintedAmount, maxSupply, issuerResp) + signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(fromID, fundsOutputID, mintedAmount, maxSupply, issuerResp) blkID := d.SubmitPayload(ctx, signedTx, from.ID, congestionResp, issuerResp) @@ -620,8 +625,9 @@ func (d *DockerTestFramework) CreateNativeToken(fromId iotago.AccountID, mintedA // wait for the account to be committed d.AwaitCommitment(blkID.Slot()) - from = d.wallet.Account(fromId) + from = d.wallet.Account(fromID) d.AssertIndexerAccount(from) + //nolint:forcetypeassert d.AssertIndexerFoundry(signedTx.Transaction.Outputs[1].(*iotago.FoundryOutput).MustFoundryID()) } @@ -732,12 +738,12 @@ func (d *DockerTestFramework) GetContainersConfigs() { } } -func (d *DockerTestFramework) CreateBlock(payload iotago.Payload, issuerId iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.Block { +func (d *DockerTestFramework) CreateBlock(payload iotago.Payload, issuerID iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.Block { clt := d.wallet.DefaultClient() issuingTime := time.Now() apiForSlot := clt.APIForSlot(clt.LatestAPI().TimeProvider().SlotFromTime(issuingTime)) blockBuilder := builder.NewBasicBlockBuilder(apiForSlot) - issuer := d.wallet.Account(issuerId) + issuer := d.wallet.Account(issuerID) commitmentID, err := issuerResp.LatestCommitment.ID() require.NoError(d.Testing, err) @@ -751,7 +757,7 @@ func (d *DockerTestFramework) CreateBlock(payload iotago.Payload, issuerId iotag ShallowLikeParents(issuerResp.ShallowLikeParents). Payload(payload). CalculateAndSetMaxBurnedMana(congestionResp.ReferenceManaCost). - Sign(issuerId, lo.Return1(d.wallet.KeyPair(issuer.AddressIndex))) + Sign(issuerID, lo.Return1(d.wallet.KeyPair(issuer.AddressIndex))) blk, err := blockBuilder.Build() require.NoError(d.Testing, err) @@ -766,10 +772,10 @@ func (d *DockerTestFramework) SubmitBlock(ctx context.Context, blk *iotago.Block require.NoError(d.Testing, err) } -func (d *DockerTestFramework) SubmitPayload(ctx context.Context, payload iotago.Payload, issuerId iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) iotago.BlockID { +func (d *DockerTestFramework) SubmitPayload(ctx context.Context, payload iotago.Payload, issuerID iotago.AccountID, congestionResp *api.CongestionResponse, issuerResp *api.IssuanceBlockHeaderResponse) iotago.BlockID { clt := d.wallet.DefaultClient() - blk := d.CreateBlock(payload, issuerId, congestionResp, issuerResp) + blk := d.CreateBlock(payload, issuerID, congestionResp, issuerResp) blkID, err := clt.SubmitBlock(ctx, blk) require.NoError(d.Testing, err) diff --git a/tools/docker-network/tests/eventapi.go b/tools/docker-network/tests/eventapi.go index 021412045..78ed9a4ea 100644 --- a/tools/docker-network/tests/eventapi.go +++ b/tools/docker-network/tests/eventapi.go @@ -189,6 +189,7 @@ func (d *DockerTestFramework) AssertTransactionMetadataByTransactionID(ctx conte if txID.Compare(metadata.TransactionID) == 0 { fmt.Println(metadata.TransactionState) finishChan <- struct{}{} + return } @@ -219,17 +220,14 @@ func (d *DockerTestFramework) AssertBlockMetadataConfirmedBlocks(ctx context.Con }() } -func (d *DockerTestFramework) AssertOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, outputId iotago.OutputID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputWithMetadataByOutputID(outputId) +func (d *DockerTestFramework) AssertOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, outputID iotago.OutputID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputWithMetadataByOutputID(outputID) require.Nil(d.Testing, subInfo.Error()) go func() { defer subInfo.Close() d.assertOutputMetadataTopics(ctx, "AssertOutput", outputMetadataChan, func(resp *api.OutputWithMetadataResponse) bool { - if outputId.Compare(resp.Metadata.OutputID) == 0 { - return true - } - return false + return outputID.Compare(resp.Metadata.OutputID) == 0 }, finishChan) }() } @@ -270,90 +268,102 @@ func (d *DockerTestFramework) AssertOutputsWithMetadataByUnlockConditionAndAddre return true } } + return false }, finishChan) }() } -func (d *DockerTestFramework) AssertDelegationOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, delegationId iotago.DelegationID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByDelegationID(delegationId) +func (d *DockerTestFramework) AssertDelegationOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, delegationID iotago.DelegationID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByDelegationID(delegationID) require.Nil(d.Testing, subInfo.Error()) go func() { defer subInfo.Close() d.assertOutputMetadataTopics(ctx, "AssertDelegationOutput", outputMetadataChan, func(resp *api.OutputWithMetadataResponse) bool { if resp.Output.Type() == iotago.OutputDelegation { - o := resp.Output.(*iotago.DelegationOutput) + o, ok := resp.Output.(*iotago.DelegationOutput) + require.True(d.Testing, ok) actualDelegationID := o.DelegationID if actualDelegationID.Empty() { actualDelegationID = iotago.DelegationIDFromOutputID(resp.Metadata.OutputID) } - return delegationId.Matches(actualDelegationID) + return delegationID.Matches(actualDelegationID) } + return false }, finishChan) }() } -func (d *DockerTestFramework) AssertFoundryOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, foundryId iotago.FoundryID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByFoundryID(foundryId) +func (d *DockerTestFramework) AssertFoundryOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, foundryID iotago.FoundryID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByFoundryID(foundryID) require.Nil(d.Testing, subInfo.Error()) go func() { defer subInfo.Close() d.assertOutputMetadataTopics(ctx, "AssertFoundryOutput", outputMetadataChan, func(resp *api.OutputWithMetadataResponse) bool { if resp.Output.Type() == iotago.OutputFoundry { - o := resp.Output.(*iotago.FoundryOutput) - return foundryId.Matches(o.MustFoundryID()) + o, ok := resp.Output.(*iotago.FoundryOutput) + require.True(d.Testing, ok) + + return foundryID.Matches(o.MustFoundryID()) } + return false }, finishChan) }() } -func (d *DockerTestFramework) AssertAccountOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, accountId iotago.AccountID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByAccountID(accountId) +func (d *DockerTestFramework) AssertAccountOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, accountID iotago.AccountID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByAccountID(accountID) require.Nil(d.Testing, subInfo.Error()) go func() { defer subInfo.Close() d.assertOutputMetadataTopics(ctx, "AssertAccountOutput", outputMetadataChan, func(resp *api.OutputWithMetadataResponse) bool { if resp.Output.Type() == iotago.OutputAccount { - o := resp.Output.(*iotago.AccountOutput) + o, ok := resp.Output.(*iotago.AccountOutput) + require.True(d.Testing, ok) actualAccountID := o.AccountID if actualAccountID.Empty() { actualAccountID = iotago.AccountIDFromOutputID(resp.Metadata.OutputID) } - return accountId.Matches(o.AccountID) + + return accountID.Matches(actualAccountID) } + return false }, finishChan) }() } -func (d *DockerTestFramework) AssertAnchorOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, anchorId iotago.AnchorID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByAnchorID(anchorId) +func (d *DockerTestFramework) AssertAnchorOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, anchorID iotago.AnchorID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByAnchorID(anchorID) require.Nil(d.Testing, subInfo.Error()) go func() { defer subInfo.Close() d.assertOutputMetadataTopics(ctx, "AssertNFTOutput", outputMetadataChan, func(resp *api.OutputWithMetadataResponse) bool { if resp.Output.Type() == iotago.OutputAnchor { - o := resp.Output.(*iotago.AnchorOutput) + o, ok := resp.Output.(*iotago.AnchorOutput) + require.True(d.Testing, ok) actualAnchorID := o.AnchorID if actualAnchorID.Empty() { actualAnchorID = iotago.AnchorIDFromOutputID(resp.Metadata.OutputID) } - return anchorId.Matches(o.AnchorID) + + return anchorID.Matches(actualAnchorID) } + return false }, finishChan) }() } -func (d *DockerTestFramework) AssertNFTOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, nftId iotago.NFTID, finishChan chan struct{}) { - outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByNFTID(nftId) +func (d *DockerTestFramework) AssertNFTOutput(ctx context.Context, eventClt *nodeclient.EventAPIClient, nftID iotago.NFTID, finishChan chan struct{}) { + outputMetadataChan, subInfo := eventClt.OutputsWithMetadataByNFTID(nftID) require.Nil(d.Testing, subInfo.Error()) go func() { @@ -365,8 +375,10 @@ func (d *DockerTestFramework) AssertNFTOutput(ctx context.Context, eventClt *nod if actualNFTID.Empty() { actualNFTID = iotago.NFTIDFromOutputID(resp.Metadata.OutputID) } - return nftId.Matches(actualNFTID) + + return nftID.Matches(actualNFTID) } + return false }, finishChan) }() @@ -388,10 +400,12 @@ func (d *DockerTestFramework) assertCommitmentsTopics(ctx context.Context, calle require.ElementsMatch(d.Testing, expectedSlots, slots) finishChan <- struct{}{} + return } case <-ctx.Done(): - fmt.Println("topic", callerName, "does not get expected commitments, recieved slots:", slots) + fmt.Println("topic", callerName, "does not get expected commitments, received slots:", slots) + return } } @@ -414,11 +428,13 @@ func (d *DockerTestFramework) assertBlocksTopics(ctx context.Context, callerName if len(blkIDs) == len(expectedBlocks) { require.ElementsMatch(d.Testing, expectedBlockIDsSlice, blkIDs) finishChan <- struct{}{} + return } } case <-ctx.Done(): fmt.Println("topic", callerName, "does not get expected Blocks, received blocks:", blkIDs) + return } } @@ -442,11 +458,13 @@ func (d *DockerTestFramework) assertBlockMetadataTopics(ctx context.Context, cal if len(blkIDs) == len(expectedBlocks) { require.ElementsMatch(d.Testing, expectedBlockIDsSlice, blkIDs) finishChan <- struct{}{} + return } } case <-ctx.Done(): fmt.Println("topic", callerName, "does not get expected BlockMetadata, received blocks:", blkIDs) + return } } @@ -461,10 +479,12 @@ func (d *DockerTestFramework) assertOutputMetadataTopics(ctx context.Context, ca case outputMetadata := <-receivedChan: if matchFunc(outputMetadata) { finishChan <- struct{}{} + return } case <-ctx.Done(): fmt.Println("topic", callerName, "does not get expected outputs") + return } } diff --git a/tools/docker-network/tests/eventapi_test.go b/tools/docker-network/tests/eventapi_test.go index 02b78f59b..3fac76078 100644 --- a/tools/docker-network/tests/eventapi_test.go +++ b/tools/docker-network/tests/eventapi_test.go @@ -68,12 +68,12 @@ func test_Commitments(t *testing.T, d *DockerTestFramework) { // prepare the expected commitments to be received expectedLatestSlots := make([]iotago.SlotIndex, 0) for i := infoResp.Status.LatestCommitmentID.Slot() + 2; i < infoResp.Status.LatestCommitmentID.Slot()+6; i++ { - expectedLatestSlots = append(expectedLatestSlots, iotago.SlotIndex(i)) + expectedLatestSlots = append(expectedLatestSlots, i) } expectedFinalizedSlots := make([]iotago.SlotIndex, 0) for i := infoResp.Status.LatestFinalizedSlot + 2; i < infoResp.Status.LatestFinalizedSlot+6; i++ { - expectedFinalizedSlots = append(expectedFinalizedSlots, iotago.SlotIndex(i)) + expectedFinalizedSlots = append(expectedFinalizedSlots, i) } assertions := []func(){ @@ -87,7 +87,7 @@ func test_Commitments(t *testing.T, d *DockerTestFramework) { } // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } @@ -104,7 +104,7 @@ func test_ValidationBlocks(t *testing.T, d *DockerTestFramework) { defer eventClt.Close() // prepare the expected commitments to be received - validators := make(map[string]struct{}, 0) + validators := make(map[string]struct{}) nodes := d.Nodes("V1", "V2", "V3", "V4") for _, node := range nodes { validators[node.AccountAddressBech32] = struct{}{} @@ -122,7 +122,7 @@ func test_ValidationBlocks(t *testing.T, d *DockerTestFramework) { } // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } @@ -140,7 +140,7 @@ func test_BasicTaggedDataBlocks(t *testing.T, d *DockerTestFramework) { account := d.CreateAccount() // prepare data blocks to send - expectedBlocks := make(map[string]*iotago.Block, 0) + expectedBlocks := make(map[string]*iotago.Block) for i := 0; i < 10; i++ { blk := d.CreateTaggedDataBlock(account.ID, []byte("tag")) expectedBlocks[blk.MustID().ToHex()] = blk @@ -162,7 +162,7 @@ func test_BasicTaggedDataBlocks(t *testing.T, d *DockerTestFramework) { } // wait until all topics starts listening - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) // issue blocks @@ -174,7 +174,7 @@ func test_BasicTaggedDataBlocks(t *testing.T, d *DockerTestFramework) { }() // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } @@ -224,7 +224,7 @@ func test_DelegationTransactionBlocks(t *testing.T, d *DockerTestFramework) { // d.AssertTransactionMetadataIncludedBlocks(ctx, eventClt, outputId.TransactionID(), finish) // wait until all topics starts listening - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) // issue blocks @@ -236,7 +236,7 @@ func test_DelegationTransactionBlocks(t *testing.T, d *DockerTestFramework) { }() // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } @@ -286,7 +286,7 @@ func test_AccountTransactionBlocks(t *testing.T, d *DockerTestFramework) { // d.AssertTransactionMetadataIncludedBlocks(ctx, eventClt, outputId.TransactionID(), finish) // wait until all topics starts listening - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) // issue blocks @@ -301,7 +301,7 @@ func test_AccountTransactionBlocks(t *testing.T, d *DockerTestFramework) { d.wallet.AddAccount(fullAccount.ID, fullAccount) // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } } @@ -354,7 +354,7 @@ func test_FoundryTransactionBlocks(t *testing.T, d *DockerTestFramework) { // d.AssertTransactionMetadataIncludedBlocks(ctx, eventClt, outputId.TransactionID(), finish) // wait until all topics starts listening - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) // issue blocks @@ -366,7 +366,7 @@ func test_FoundryTransactionBlocks(t *testing.T, d *DockerTestFramework) { }() // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } } @@ -413,11 +413,8 @@ func test_NFTTransactionBlocks(t *testing.T, d *DockerTestFramework) { assertion() } - // d.AssertTransactionMetadataByTransactionID(ctx, eventClt, outputId.TransactionID(), finish) - // d.AssertTransactionMetadataIncludedBlocks(ctx, eventClt, outputId.TransactionID(), finish) - // wait until all topics starts listening - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) // issue blocks @@ -429,7 +426,7 @@ func test_NFTTransactionBlocks(t *testing.T, d *DockerTestFramework) { }() // wait until all topics receives all expected objects - err = AwaitEventAPITopics(t, d.optsWaitFor, cancel, finish, totalTopics) + err = AwaitEventAPITopics(d.optsWaitFor, cancel, finish, totalTopics) require.NoError(t, err) } } diff --git a/tools/docker-network/tests/options.go b/tools/docker-network/tests/options.go index 314eeee00..7cb79d3d9 100644 --- a/tools/docker-network/tests/options.go +++ b/tools/docker-network/tests/options.go @@ -16,7 +16,7 @@ var DefaultProtocolParametersOptions = []options.Option[iotago.V3ProtocolParamet iotago.WithNetworkOptions("docker", iotago.PrefixTestnet), } -// DefaultSnapshotOptions are the default snapshot options for the docker network. +// DefaultAccountOptions are the default snapshot options for the docker network. func DefaultAccountOptions(protocolParams *iotago.V3ProtocolParameters) []options.Option[snapshotcreator.Options] { return []options.Option[snapshotcreator.Options]{ snapshotcreator.WithAccounts(presets.AccountsDockerFunc(protocolParams)...), @@ -60,7 +60,6 @@ func WithTick(tick time.Duration) options.Option[DockerTestFramework] { } } -// ///// Account Output options func WithStakingFeature(amount iotago.BaseToken, fixedCost iotago.Mana, startEpoch iotago.EpochIndex, optEndEpoch ...iotago.EpochIndex) options.Option[builder.AccountOutputBuilder] { return func(accountBuilder *builder.AccountOutputBuilder) { accountBuilder.Staking(amount, fixedCost, startEpoch, optEndEpoch...) diff --git a/tools/docker-network/tests/utils.go b/tools/docker-network/tests/utils.go index ea7502ec6..dc542be69 100644 --- a/tools/docker-network/tests/utils.go +++ b/tools/docker-network/tests/utils.go @@ -11,7 +11,6 @@ import ( "net/http" "os" "sort" - "testing" "time" "github.com/stretchr/testify/require" @@ -112,12 +111,12 @@ func (d *DockerTestFramework) AssertCommittee(expectedEpoch iotago.EpochIndex, e sort.Strings(expectedCommitteeMember) status := d.NodeStatus("V1") - api := d.wallet.DefaultClient().CommittedAPI() - expectedSlotStart := api.TimeProvider().EpochStart(expectedEpoch) + testAPI := d.wallet.DefaultClient().CommittedAPI() + expectedSlotStart := testAPI.TimeProvider().EpochStart(expectedEpoch) require.Greater(d.Testing, expectedSlotStart, status.LatestAcceptedBlockSlot) slotToWait := expectedSlotStart - status.LatestAcceptedBlockSlot - secToWait := time.Duration(slotToWait) * time.Duration(api.ProtocolParameters().SlotDurationInSeconds()) * time.Second + secToWait := time.Duration(slotToWait) * time.Duration(testAPI.ProtocolParameters().SlotDurationInSeconds()) * time.Second fmt.Println("Wait for ", secToWait, "until expected epoch: ", expectedEpoch) time.Sleep(secToWait) @@ -309,7 +308,7 @@ func createLogDirectory(testName string) string { return dir } -func AwaitEventAPITopics(t *testing.T, duration time.Duration, cancleFunc context.CancelFunc, receiveChan chan struct{}, numOfTopics int) error { +func AwaitEventAPITopics(duration time.Duration, cancleFunc context.CancelFunc, receiveChan chan struct{}, numOfTopics int) error { counter := 0 timer := time.NewTimer(duration) defer timer.Stop() @@ -338,5 +337,6 @@ func getDelegationStartEpoch(api iotago.API, commitmentSlot iotago.SlotIndex) io if pastBoundedSlot <= registrationSlot { return pastBoundedEpoch + 1 } + return pastBoundedEpoch + 2 } diff --git a/tools/docker-network/tests/wallet.go b/tools/docker-network/tests/wallet.go index ba0e5e765..1393465e3 100644 --- a/tools/docker-network/tests/wallet.go +++ b/tools/docker-network/tests/wallet.go @@ -76,12 +76,12 @@ func (w *DockerWallet) DefaultClient() *nodeclient.Client { return w.Clients["V1"] } -func (w *DockerWallet) AddOutput(outputId iotago.OutputID, output *OutputData) { - w.outputs[outputId] = output +func (w *DockerWallet) AddOutput(outputID iotago.OutputID, output *OutputData) { + w.outputs[outputID] = output } -func (w *DockerWallet) AddAccount(accountId iotago.AccountID, data *AccountData) { - w.accounts[accountId] = data +func (w *DockerWallet) AddAccount(accountID iotago.AccountID, data *AccountData) { + w.accounts[accountID] = data } func (w *DockerWallet) Output(outputName iotago.OutputID) *OutputData { @@ -93,10 +93,10 @@ func (w *DockerWallet) Output(outputName iotago.OutputID) *OutputData { return output } -func (w *DockerWallet) Account(accountId iotago.AccountID) *AccountData { - acc, exists := w.accounts[accountId] +func (w *DockerWallet) Account(accountID iotago.AccountID) *AccountData { + acc, exists := w.accounts[accountID] if !exists { - panic(ierrors.Errorf("account %s not registered in wallet", accountId.ToHex())) + panic(ierrors.Errorf("account %s not registered in wallet", accountID.ToHex())) } return acc @@ -130,10 +130,10 @@ func (w *DockerWallet) AddressSigner(indexes ...uint32) iotago.AddressSigner { return w.keyManager.AddressSigner(indexes...) } -func (w *DockerWallet) AllotManaFromAccount(fromId iotago.AccountID, toId iotago.AccountID, manaToAllot iotago.Mana, inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { - from := w.Account(fromId) - to := w.Account(toId) - input := w.Output(inputId) +func (w *DockerWallet) AllotManaFromAccount(fromID iotago.AccountID, toID iotago.AccountID, manaToAllot iotago.Mana, inputID iotago.OutputID) *iotago.SignedTransaction { + from := w.Account(fromID) + to := w.Account(toID) + input := w.Output(inputID) currentSlot := w.DefaultClient().LatestAPI().TimeProvider().CurrentSlot() apiForSlot := w.DefaultClient().APIForSlot(currentSlot) @@ -164,9 +164,9 @@ func (w *DockerWallet) AllotManaFromAccount(fromId iotago.AccountID, toId iotago Build() require.NoError(w.Testing, err) - allotmentOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - w.AddOutput(allotmentOutputId, &OutputData{ - ID: allotmentOutputId, + allotmentOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + w.AddOutput(allotmentOutputID, &OutputData{ + ID: allotmentOutputID, Output: basicOutput, Address: input.Address, AddressIndex: input.AddressIndex, @@ -175,9 +175,9 @@ func (w *DockerWallet) AllotManaFromAccount(fromId iotago.AccountID, toId iotago return signedTx } -func (w *DockerWallet) AllotManaFromInput(toId iotago.AccountID, inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { - to := w.Account(toId) - input := w.Output(inputId) +func (w *DockerWallet) AllotManaFromInput(toID iotago.AccountID, inputID iotago.OutputID) *iotago.SignedTransaction { + to := w.Account(toID) + input := w.Output(inputID) currentSlot := w.DefaultClient().LatestAPI().TimeProvider().CurrentSlot() apiForSlot := w.DefaultClient().APIForSlot(currentSlot) @@ -195,10 +195,11 @@ func (w *DockerWallet) AllotManaFromInput(toId iotago.AccountID, inputId iotago. AllotAllMana(currentSlot, to.ID, 0). SetCreationSlot(currentSlot). Build() + require.NoError(w.Testing, err) - delegationOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - w.AddOutput(delegationOutputId, &OutputData{ - ID: delegationOutputId, + delegationOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + w.AddOutput(delegationOutputID, &OutputData{ + ID: delegationOutputID, Output: basicOutput, Address: input.Address, AddressIndex: input.AddressIndex, @@ -207,8 +208,8 @@ func (w *DockerWallet) AllotManaFromInput(toId iotago.AccountID, inputId iotago. return signedTx } -func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse, opts ...options.Option[builder.AccountOutputBuilder]) (*AccountData, *iotago.SignedTransaction) { - input := w.Output(inputId) +func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse, opts ...options.Option[builder.AccountOutputBuilder]) (*AccountData, *iotago.SignedTransaction) { + input := w.Output(inputID) accountID := iotago.AccountIDFromOutputID(input.ID) accountAddress, ok := accountID.ToAddress().(*iotago.AccountAddress) @@ -220,6 +221,7 @@ func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputId iotago.O // transition to a full account with new Ed25519 address and staking feature accEd25519AddrIndex, accEd25519Addr := w.Address() accPrivateKey, _ := w.KeyPair(accEd25519AddrIndex) + //nolint:forcetypeassert accBlockIssuerKey := iotago.Ed25519PublicKeyHashBlockIssuerKeyFromPublicKey(hiveEd25519.PublicKey(accPrivateKey.Public().(ed25519.PublicKey))) accountOutput := options.Apply(builder.NewAccountOutputBuilder(accEd25519Addr, input.Output.BaseTokenAmount()), opts, func(b *builder.AccountOutputBuilder) { @@ -241,9 +243,9 @@ func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputId iotago.O Build() require.NoError(w.Testing, err) - accountOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - w.AddOutput(accountOutputId, &OutputData{ - ID: accountOutputId, + accountOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + w.AddOutput(accountOutputID, &OutputData{ + ID: accountOutputID, Output: accountOutput, Address: accEd25519Addr, AddressIndex: accEd25519AddrIndex, @@ -254,14 +256,14 @@ func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputId iotago.O Address: accountAddress, AddressIndex: accEd25519AddrIndex, Output: accountOutput, - OutputID: accountOutputId, + OutputID: accountOutputID, } return accountInfo, signedTx } -func (w *DockerWallet) CreateDelegationFromInput(issuerId iotago.AccountID, validator *Node, inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { - input := w.Output(inputId) +func (w *DockerWallet) CreateDelegationFromInput(issuerID iotago.AccountID, validator *Node, inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { + input := w.Output(inputID) _, validatorAccountAddr, err := iotago.ParseBech32(validator.AccountAddressBech32) require.NoError(w.Testing, err) @@ -270,10 +272,10 @@ func (w *DockerWallet) CreateDelegationFromInput(issuerId iotago.AccountID, vali apiForSlot := w.DefaultClient().APIForSlot(currentSlot) // construct delegation transaction + //nolint:forcetypeassert delegationOutput := builder.NewDelegationOutputBuilder(validatorAccountAddr.(*iotago.AccountAddress), input.Address, input.Output.BaseTokenAmount()). StartEpoch(getDelegationStartEpoch(apiForSlot, issuerResp.LatestCommitment.Slot)). DelegatedAmount(input.Output.BaseTokenAmount()).MustBuild() - signedTx, err := builder.NewTransactionBuilder(apiForSlot, w.AddressSigner(input.AddressIndex)). AddInput(&builder.TxInput{ UnlockTarget: input.Address, @@ -283,13 +285,13 @@ func (w *DockerWallet) CreateDelegationFromInput(issuerId iotago.AccountID, vali AddOutput(delegationOutput). SetCreationSlot(currentSlot). AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}). - AllotAllMana(currentSlot, issuerId, 0). + AllotAllMana(currentSlot, issuerID, 0). Build() require.NoError(w.Testing, err) - delegationOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - w.AddOutput(delegationOutputId, &OutputData{ - ID: delegationOutputId, + delegationOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + w.AddOutput(delegationOutputID, &OutputData{ + ID: delegationOutputID, Output: delegationOutput, Address: input.Address, AddressIndex: input.AddressIndex, @@ -298,10 +300,10 @@ func (w *DockerWallet) CreateDelegationFromInput(issuerId iotago.AccountID, vali return signedTx } -func (w *DockerWallet) CreateFoundryAndNativeTokensFromInput(issuerId iotago.AccountID, inputId iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { - input := w.Output(inputId) +func (w *DockerWallet) CreateFoundryAndNativeTokensFromInput(issuerID iotago.AccountID, inputID iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { + input := w.Output(inputID) - issuer := w.Account(issuerId) + issuer := w.Account(issuerID) currentSlot := w.DefaultClient().LatestAPI().TimeProvider().CurrentSlot() apiForSlot := w.DefaultClient().APIForSlot(currentSlot) @@ -338,21 +340,22 @@ func (w *DockerWallet) CreateFoundryAndNativeTokensFromInput(issuerId iotago.Acc AddOutput(accTransitionOutput). AddOutput(foundryOutput). SetCreationSlot(currentSlot). - AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: issuerId}). + AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: issuerID}). AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}). - AllotAllMana(currentSlot, issuerId, 0). + AllotAllMana(currentSlot, issuerID, 0). Build() require.NoError(w.Testing, err) - foundryOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 1) - w.AddOutput(foundryOutputId, &OutputData{ - ID: foundryOutputId, + foundryOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 1) + w.AddOutput(foundryOutputID, &OutputData{ + ID: foundryOutputID, Output: foundryOutput, Address: issuer.Address, }) - w.AddAccount(issuerId, &AccountData{ - ID: issuerId, + //nolint:forcetypeassert + w.AddAccount(issuerID, &AccountData{ + ID: issuerID, Address: issuer.Address, AddressIndex: issuer.AddressIndex, Output: signedTx.Transaction.Outputs[0].(*iotago.AccountOutput), @@ -363,9 +366,9 @@ func (w *DockerWallet) CreateFoundryAndNativeTokensFromInput(issuerId iotago.Acc } // TransitionFoundry transitions a FoundryOutput by increasing the native token amount on the output by one. -func (w *DockerWallet) TransitionFoundry(issuerId iotago.AccountID, inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { - issuer := w.Account(issuerId) - input := w.Output(inputId) +func (w *DockerWallet) TransitionFoundry(issuerID iotago.AccountID, inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { + issuer := w.Account(issuerID) + input := w.Output(inputID) inputFoundry, isFoundry := input.Output.(*iotago.FoundryOutput) require.True(w.Testing, isFoundry) @@ -411,19 +414,20 @@ func (w *DockerWallet) TransitionFoundry(issuerId iotago.AccountID, inputId iota SetCreationSlot(currentSlot). AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: issuer.ID}). AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}). - AllotAllMana(currentSlot, issuerId, 0). + AllotAllMana(currentSlot, issuerID, 0). Build() require.NoError(w.Testing, err) - foundryOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 1) - w.AddOutput(foundryOutputId, &OutputData{ - ID: foundryOutputId, + foundryOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 1) + w.AddOutput(foundryOutputID, &OutputData{ + ID: foundryOutputID, Output: outputFoundry, Address: issuer.Address, }) - w.AddAccount(issuerId, &AccountData{ - ID: issuerId, + //nolint:forcetypeassert + w.AddAccount(issuerID, &AccountData{ + ID: issuerID, Address: issuer.Address, AddressIndex: issuer.AddressIndex, Output: signedTx.Transaction.Outputs[0].(*iotago.AccountOutput), @@ -433,8 +437,8 @@ func (w *DockerWallet) TransitionFoundry(issuerId iotago.AccountID, inputId iota return signedTx } -func (w *DockerWallet) CreateNFTFromInput(issuerId iotago.AccountID, inputId iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse, opts ...options.Option[builder.NFTOutputBuilder]) *iotago.SignedTransaction { - input := w.Output(inputId) +func (w *DockerWallet) CreateNFTFromInput(issuerID iotago.AccountID, inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse, opts ...options.Option[builder.NFTOutputBuilder]) *iotago.SignedTransaction { + input := w.Output(inputID) currentSlot := w.DefaultClient().LatestAPI().TimeProvider().CurrentSlot() apiForSlot := w.DefaultClient().APIForSlot(currentSlot) @@ -452,15 +456,15 @@ func (w *DockerWallet) CreateNFTFromInput(issuerId iotago.AccountID, inputId iot }). AddOutput(nftOutput). SetCreationSlot(currentSlot). - AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: issuerId}). + AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: issuerID}). AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}). - AllotAllMana(currentSlot, issuerId, 0). + AllotAllMana(currentSlot, issuerID, 0). Build() require.NoError(w.Testing, err) - nftOutputId := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - w.AddOutput(nftOutputId, &OutputData{ - ID: nftOutputId, + nftOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + w.AddOutput(nftOutputID, &OutputData{ + ID: nftOutputID, Output: nftOutput, Address: nftAddress, AddressIndex: nftAddressIndex, From c030d3608a80b4f1cf6745f19439e91993ef29d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 12:27:32 +0100 Subject: [PATCH 05/22] Fix UTXO diffs and congestion tests --- tools/docker-network/tests/coreapi.go | 54 ++++++++++------------ tools/docker-network/tests/coreapi_test.go | 42 +++++++++-------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index ce4d0222f..da7a16050 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -4,9 +4,7 @@ package tests import ( "context" - "fmt" "testing" - "time" "github.com/stretchr/testify/require" @@ -18,15 +16,11 @@ import ( type coreAPIAssets map[iotago.SlotIndex]*coreAPISlotAssets -func (a coreAPIAssets) assetForSlot(slot iotago.SlotIndex, account *AccountData) *coreAPISlotAssets { +func (a coreAPIAssets) setupAssetsForSlot(slot iotago.SlotIndex) { _, ok := a[slot] if !ok { a[slot] = newAssetsPerSlot() } - a[slot].accountSlot = account.OutputID.Slot() - a[slot].accountAddress = account.Address - - return a[slot] } func (a coreAPIAssets) assertCommitments(t *testing.T) { @@ -76,6 +70,10 @@ func (a coreAPIAssets) forEachCommitment(t *testing.T, f func(*testing.T, map[st func (a coreAPIAssets) forEachAccountAddress(t *testing.T, f func(*testing.T, *iotago.AccountAddress, map[string]iotago.CommitmentID)) { for _, asset := range a { + if asset.accountAddress == nil { + // no account created in this slot + continue + } f(t, asset.accountAddress, asset.commitmentPerNode) } } @@ -84,7 +82,6 @@ func (a coreAPIAssets) assertUTXOOutputIDsInSlot(t *testing.T, slot iotago.SlotI created := make(map[iotago.OutputID]types.Empty) spent := make(map[iotago.OutputID]types.Empty) for _, outputID := range createdOutputs { - created[outputID] = types.Void } @@ -127,10 +124,7 @@ func (a coreAPIAssets) assertUTXOOutputsInSlot(t *testing.T, slot iotago.SlotInd } type coreAPISlotAssets struct { - //slot iotago.SlotIndex - //epoch iotago.EpochIndex accountAddress *iotago.AccountAddress - accountSlot iotago.SlotIndex dataBlocks []*iotago.Block valueBlocks []*iotago.Block transactions []*iotago.SignedTransaction @@ -165,33 +159,35 @@ func newAssetsPerSlot() *coreAPISlotAssets { func (d *DockerTestFramework) prepareAssets(totalAssetsNum int) (coreAPIAssets, iotago.SlotIndex) { assets := make(coreAPIAssets) ctx := context.Background() - account := d.CreateAccount() - accountSlot := account.OutputID.Slot() + latestSlot := iotago.SlotIndex(0) - assets.assetForSlot(accountSlot, account) for i := 0; i < totalAssetsNum; i++ { - fmt.Println("Creating asset: ", i) + // account + account := d.CreateAccount() + assets.setupAssetsForSlot(account.OutputID.Slot()) + assets[account.OutputID.Slot()].accountAddress = account.Address + + // data block block := d.CreateTaggedDataBlock(account.ID, []byte("tag")) blockSlot := lo.PanicOnErr(block.ID()).Slot() - latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot) - assets.assetForSlot(blockSlot, account).dataBlocks = append(assets[blockSlot].dataBlocks, block) + assets.setupAssetsForSlot(blockSlot) + assets[blockSlot].dataBlocks = append(assets[blockSlot].dataBlocks, block) d.SubmitBlock(ctx, block) - block, signedTx, faucetOutput, basicOut := d.CreateValueBlock(account.ID) - valueBlockSlot := block.MustID().Slot() - latestSlot = lo.Max[iotago.SlotIndex](latestSlot, valueBlockSlot) - d.SubmitBlock(ctx, block) + // transaction + valueBlock, signedTx, faucetOutput, basicOut := d.CreateValueBlock(account.ID) + valueBlockSlot := valueBlock.MustID().Slot() + assets.setupAssetsForSlot(valueBlockSlot) - assets.assetForSlot(valueBlockSlot, account).valueBlocks = append(assets[valueBlockSlot].valueBlocks, block) - txSlot := lo.PanicOnErr(signedTx.ID()).Slot() - latestSlot = lo.Max[iotago.SlotIndex](latestSlot, txSlot) + assets[valueBlockSlot].valueBlocks = append(assets[valueBlockSlot].valueBlocks, valueBlock) + assets[valueBlockSlot].transactions = append(assets[valueBlockSlot].transactions, signedTx) + assets[valueBlockSlot].basicOutputs[iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0)] = basicOut + assets[valueBlockSlot].faucetOutputs[faucetOutput.ID] = faucetOutput.Output + d.SubmitBlock(ctx, valueBlock) + d.AwaitTransactionPayloadAccepted(ctx, valueBlock.MustID()) - assets.assetForSlot(txSlot, account).transactions = append(assets[txSlot].transactions, signedTx) - basicOutpID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) - assets[txSlot].basicOutputs[basicOutpID] = basicOut - assets[txSlot].faucetOutputs[faucetOutput.ID] = faucetOutput.Output - time.Sleep(1 * time.Second) + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot, valueBlockSlot) } return assets, latestSlot diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 49e27d1ae..e2c164c4f 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -36,7 +36,7 @@ func Test_CoreAPI(t *testing.T) { d.WaitUntilNetworkReady() - assetsPerSlot, lastSlot := d.prepareAssets(3) + assetsPerSlot, lastSlot := d.prepareAssets(5) fmt.Println("AwaitCommitment for slot", lastSlot) d.AwaitCommitment(lastSlot) @@ -61,7 +61,6 @@ func Test_CoreAPI(t *testing.T) { 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()) - //require.EqualValues(t, block, respBlock) }) }, }, @@ -72,7 +71,7 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), block.MustID()) require.NoError(t, err) require.NotNil(t, resp) - //require.Equal(t, block.MustID(), resp.BlockID) + require.Equal(t, block.MustID(), resp.BlockID, "BlockID of retrieved block does not match: %s != %s", block.MustID(), resp.BlockID) require.Equal(t, api.BlockStateFinalized, resp.BlockState) }) }, @@ -80,13 +79,12 @@ func Test_CoreAPI(t *testing.T) { { name: "Test_BlockWithMetadata", testFunc: func(t *testing.T, nodeAlias string) { - // TODO missing client side implementation for BlockWithMetadata assetsPerSlot.forEachBlock(t, func(t *testing.T, block *iotago.Block) { - resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), block.MustID()) + resp, err := d.wallet.Clients[nodeAlias].BlockWithMetadataByID(context.Background(), block.MustID()) require.NoError(t, err) require.NotNil(t, resp) - require.Equal(t, block.MustID(), resp.BlockID) - require.Equal(t, api.BlockStateFinalized, resp.BlockState) + require.Equal(t, block.MustID(), resp.Block.MustID(), "BlockID of retrieved block does not match: %s != %s", block.MustID(), resp.Block.MustID()) + require.Equal(t, api.BlockStateFinalized, resp.Metadata.BlockState) }) }, }, @@ -97,7 +95,7 @@ func Test_CoreAPI(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) - require.GreaterOrEqual(t, len(resp.StrongParents), 1) + require.GreaterOrEqual(t, len(resp.StrongParents), 1, "There should be at least 1 strong parent provided") }, }, { @@ -118,7 +116,7 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].CommitmentByID(context.Background(), commitmentsPerNode[nodeAlias]) require.NoError(t, err) require.NotNil(t, resp) - require.Equal(t, commitmentsPerNode[nodeAlias], resp.MustID()) + 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()) }) }, }, @@ -130,7 +128,7 @@ func Test_CoreAPI(t *testing.T) { 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) + require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) }) }, }, @@ -142,7 +140,7 @@ func Test_CoreAPI(t *testing.T) { 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) + require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) }) }, }, @@ -154,7 +152,7 @@ func Test_CoreAPI(t *testing.T) { 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) + require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) }) }, }, @@ -166,7 +164,7 @@ func Test_CoreAPI(t *testing.T) { 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) + require.Equal(t, commitmentsPerNode[nodeAlias], resp.CommitmentID, "CommitmentID of retrieved UTXO changes does not match: %s != %s", commitmentsPerNode[nodeAlias], resp.CommitmentID) }) }, }, @@ -177,7 +175,7 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].OutputByID(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, resp) - require.EqualValues(t, output, resp) + require.EqualValues(t, output, resp, "Output created is different than retrieved from the API: %s != %s", output, resp) }) }, }, @@ -188,9 +186,8 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].OutputMetadataByID(context.Background(), outputID) require.NoError(t, err) require.NotNil(t, resp) - require.EqualValues(t, outputID, resp.OutputID) - require.EqualValues(t, outputID.Slot(), resp.Included.Slot) - require.EqualValues(t, outputID.TransactionID(), resp.Included.TransactionID) + require.EqualValues(t, outputID, resp.OutputID, "OutputID of retrieved output does not match: %s != %s", outputID, resp.OutputID) + require.EqualValues(t, outputID.TransactionID(), resp.Included.TransactionID, "TransactionID of retrieved output does not match: %s != %s", outputID.TransactionID(), resp.Included.TransactionID) }) }, }, @@ -213,6 +210,7 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlockMetadata(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) require.NoError(t, err) require.NotNil(t, resp) + require.EqualValues(t, api.BlockStateFinalized, resp.BlockState) }) }, }, @@ -231,12 +229,17 @@ func Test_CoreAPI(t *testing.T) { name: "Test_Congestion", testFunc: func(t *testing.T, nodeAlias string) { assetsPerSlot.forEachAccountAddress(t, func(t *testing.T, accountAddress *iotago.AccountAddress, commitmentPerNode map[string]iotago.CommitmentID) { - resp, err := d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0) require.NoError(t, err) require.NotNil(t, resp) - resp, err = d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0, commitmentPerNode[nodeAlias]) + // node allows to get account only for the slot newer than lastCommittedSlot - MCA, we need fresh commitment + infoRes, err := d.wallet.Clients[nodeAlias].Info(context.Background()) + require.NoError(t, err) + commitment, err := d.wallet.Clients[nodeAlias].CommitmentByIndex(context.Background(), infoRes.Status.LatestCommitmentID.Slot()) + require.NoError(t, err) + + resp, err = d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0, commitment.MustID()) require.NoError(t, err) require.NotNil(t, resp) }) @@ -278,6 +281,7 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].Committee(context.Background()) require.NoError(t, err) require.NotNil(t, resp) + require.EqualValues(t, 4, len(resp.Committee)) }, }, } From 4431d0ba0f25b5688856c7c10f5e86a4a87ce1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 14:05:54 +0100 Subject: [PATCH 06/22] Finish up rewards, and validator API --- components/restapi/core/accounts.go | 2 +- .../tests/committeerotation_test.go | 8 +-- tools/docker-network/tests/coreapi.go | 57 +++++++++++++++---- tools/docker-network/tests/coreapi_test.go | 31 ++++++++-- tools/docker-network/tests/dockerframework.go | 14 +++-- tools/docker-network/tests/eventapi_test.go | 2 +- tools/docker-network/tests/wallet.go | 7 +-- 7 files changed, 87 insertions(+), 34 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index e97ccad18..3e279580d 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -77,7 +77,7 @@ func validators(c echo.Context) (*api.ValidatorsResponse, error) { } slotRange := uint32(requestedSlot) / restapi.ParamsRestAPI.RequestsMemoryCacheGranularity - return deps.RequestHandler.Validators(slotRange, pageSize, cursorIndex) + return deps.RequestHandler.Validators(slotRange, cursorIndex, pageSize) } func validatorByAccountAddress(c echo.Context) (*api.ValidatorResponse, error) { diff --git a/tools/docker-network/tests/committeerotation_test.go b/tools/docker-network/tests/committeerotation_test.go index a96745491..80d560486 100644 --- a/tools/docker-network/tests/committeerotation_test.go +++ b/tools/docker-network/tests/committeerotation_test.go @@ -245,10 +245,10 @@ func Test_Delegation(t *testing.T) { account := d.CreateAccount() // delegate all faucet funds to V2, V2 should replace V3 - delegationStartEpoch := d.DelegateToValidator(account.ID, d.Node("V2")) - d.AssertCommittee(delegationStartEpoch+1, d.AccountsFromNodes(d.Nodes("V1", "V2", "V4")...)) + _, delegationOutput := d.DelegateToValidator(account.ID, d.Node("V2").AccountAddress(t)) + d.AssertCommittee(delegationOutput.StartEpoch+1, d.AccountsFromNodes(d.Nodes("V1", "V2", "V4")...)) // delegate all faucet funds to V3, V3 should replace V1 - delegationStartEpoch = d.DelegateToValidator(account.ID, d.Node("V3")) - d.AssertCommittee(delegationStartEpoch+1, d.AccountsFromNodes(d.Nodes("V2", "V3", "V4")...)) + _, delegationOutput = d.DelegateToValidator(account.ID, d.Node("V3").AccountAddress(t)) + d.AssertCommittee(delegationOutput.StartEpoch+1, d.AccountsFromNodes(d.Nodes("V2", "V3", "V4")...)) } diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index da7a16050..b72b06787 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -4,6 +4,7 @@ package tests import ( "context" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -29,6 +30,12 @@ func (a coreAPIAssets) assertCommitments(t *testing.T) { } } +func (a coreAPIAssets) assertBICs(t *testing.T) { + for _, asset := range a { + asset.assertBICs(t) + } +} + func (a coreAPIAssets) forEachBlock(t *testing.T, f func(*testing.T, *iotago.Block)) { for _, asset := range a { for _, block := range asset.dataBlocks { @@ -53,6 +60,12 @@ func (a coreAPIAssets) forEachOutput(t *testing.T, f func(*testing.T, iotago.Out for outID, out := range asset.basicOutputs { f(t, outID, out) } + for outID, out := range asset.faucetOutputs { + f(t, outID, out) + } + for outID, out := range asset.delegationOutputs { + f(t, outID, out) + } } } @@ -68,13 +81,13 @@ func (a coreAPIAssets) forEachCommitment(t *testing.T, f func(*testing.T, map[st } } -func (a coreAPIAssets) forEachAccountAddress(t *testing.T, f func(*testing.T, *iotago.AccountAddress, map[string]iotago.CommitmentID)) { +func (a coreAPIAssets) forEachAccountAddress(t *testing.T, f func(t *testing.T, accountAddress *iotago.AccountAddress, commitmentPerNode map[string]iotago.CommitmentID, bicPerNode map[string]iotago.BlockIssuanceCredits)) { for _, asset := range a { if asset.accountAddress == nil { // no account created in this slot continue } - f(t, asset.accountAddress, asset.commitmentPerNode) + f(t, asset.accountAddress, asset.commitmentPerNode, asset.bicPerNode) } } @@ -124,14 +137,16 @@ func (a coreAPIAssets) assertUTXOOutputsInSlot(t *testing.T, slot iotago.SlotInd } type coreAPISlotAssets struct { - accountAddress *iotago.AccountAddress - dataBlocks []*iotago.Block - valueBlocks []*iotago.Block - transactions []*iotago.SignedTransaction - basicOutputs map[iotago.OutputID]iotago.Output - faucetOutputs map[iotago.OutputID]iotago.Output + accountAddress *iotago.AccountAddress + dataBlocks []*iotago.Block + valueBlocks []*iotago.Block + transactions []*iotago.SignedTransaction + basicOutputs map[iotago.OutputID]iotago.Output + faucetOutputs map[iotago.OutputID]iotago.Output + delegationOutputs map[iotago.OutputID]iotago.Output commitmentPerNode map[string]iotago.CommitmentID + bicPerNode map[string]iotago.BlockIssuanceCredits } func (a *coreAPISlotAssets) assertCommitments(t *testing.T) { @@ -145,14 +160,23 @@ func (a *coreAPISlotAssets) assertCommitments(t *testing.T) { } } +func (a *coreAPISlotAssets) assertBICs(t *testing.T) { + prevBIC := a.bicPerNode["V1"] + for _, bic := range a.bicPerNode { + require.Equal(t, bic, prevBIC) + } +} + func newAssetsPerSlot() *coreAPISlotAssets { return &coreAPISlotAssets{ - commitmentPerNode: make(map[string]iotago.CommitmentID), dataBlocks: make([]*iotago.Block, 0), valueBlocks: make([]*iotago.Block, 0), transactions: make([]*iotago.SignedTransaction, 0), basicOutputs: make(map[iotago.OutputID]iotago.Output), faucetOutputs: make(map[iotago.OutputID]iotago.Output), + delegationOutputs: make(map[iotago.OutputID]iotago.Output), + commitmentPerNode: make(map[string]iotago.CommitmentID), + bicPerNode: make(map[string]iotago.BlockIssuanceCredits), } } @@ -179,15 +203,24 @@ func (d *DockerTestFramework) prepareAssets(totalAssetsNum int) (coreAPIAssets, valueBlock, signedTx, faucetOutput, basicOut := d.CreateValueBlock(account.ID) valueBlockSlot := valueBlock.MustID().Slot() assets.setupAssetsForSlot(valueBlockSlot) - + // transaction and outputs are stored with the earliest included block assets[valueBlockSlot].valueBlocks = append(assets[valueBlockSlot].valueBlocks, valueBlock) assets[valueBlockSlot].transactions = append(assets[valueBlockSlot].transactions, signedTx) - assets[valueBlockSlot].basicOutputs[iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0)] = basicOut + basicOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + assets[valueBlockSlot].basicOutputs[basicOutputID] = basicOut assets[valueBlockSlot].faucetOutputs[faucetOutput.ID] = faucetOutput.Output d.SubmitBlock(ctx, valueBlock) d.AwaitTransactionPayloadAccepted(ctx, valueBlock.MustID()) - latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot, valueBlockSlot) + delegationOutputID, delegationOutput := d.DelegateToValidator(account.ID, d.Node("V1").AccountAddress(d.Testing)) + assets.setupAssetsForSlot(delegationOutputID.CreationSlot()) + assets[delegationOutputID.CreationSlot()].delegationOutputs[delegationOutputID] = delegationOutput + + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot, valueBlockSlot, delegationOutputID.CreationSlot()) + + fmt.Printf("Assets for slot %d\n: dataBlock: %s block: %s\ntx: %s\nbasic output: %s, faucet output: %s\n delegation output: %s\n", + valueBlockSlot, block.MustID().String(), valueBlock.MustID().String(), lo.PanicOnErr(signedTx.ID()).String(), + basicOutputID.String(), faucetOutput.ID.String(), delegationOutputID.String()) } return assets, latestSlot diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index e2c164c4f..9ed42de1e 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -36,7 +36,7 @@ func Test_CoreAPI(t *testing.T) { d.WaitUntilNetworkReady() - assetsPerSlot, lastSlot := d.prepareAssets(5) + assetsPerSlot, lastSlot := d.prepareAssets(1) fmt.Println("AwaitCommitment for slot", lastSlot) d.AwaitCommitment(lastSlot) @@ -228,7 +228,12 @@ func Test_CoreAPI(t *testing.T) { { name: "Test_Congestion", testFunc: func(t *testing.T, nodeAlias string) { - assetsPerSlot.forEachAccountAddress(t, func(t *testing.T, accountAddress *iotago.AccountAddress, commitmentPerNode map[string]iotago.CommitmentID) { + assetsPerSlot.forEachAccountAddress(t, func( + t *testing.T, + accountAddress *iotago.AccountAddress, + commitmentPerNode map[string]iotago.CommitmentID, + bicPerNoode map[string]iotago.BlockIssuanceCredits, + ) { resp, err := d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0) require.NoError(t, err) require.NotNil(t, resp) @@ -242,6 +247,8 @@ func Test_CoreAPI(t *testing.T) { resp, err = d.wallet.Clients[nodeAlias].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 }) }, }, @@ -252,12 +259,14 @@ func Test_CoreAPI(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].Validators(context.Background(), pageSize) require.NoError(t, err) require.NotNil(t, resp) - require.Equal(t, len(resp.Validators), int(pageSize)) + //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) resp, err = d.wallet.Clients[nodeAlias].Validators(context.Background(), pageSize, resp.Cursor) require.NoError(t, err) require.NotNil(t, resp) - require.Equal(t, len(resp.Validators), 1) + //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") }, }, { @@ -272,7 +281,17 @@ func Test_CoreAPI(t *testing.T) { { name: "Test_Rewards", testFunc: func(t *testing.T, nodeAlias string) { - //skip: we will test it with caliming tests + assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { + if output.Type() != iotago.OutputDelegation { + return + } + + resp, err := d.wallet.Clients[nodeAlias].Rewards(context.Background(), outputID) + require.NoError(t, err) + require.NotNil(t, resp) + // rewards are zero, because we do not wait for the epoch end + require.EqualValues(t, 0, resp.Rewards) + }) }, }, { @@ -292,5 +311,7 @@ func Test_CoreAPI(t *testing.T) { }) } + // check if the same values were returned by all nodes for the same slot assetsPerSlot.assertCommitments(t) + assetsPerSlot.assertBICs(t) } diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index c31c30d52..81953e6f8 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -405,14 +405,14 @@ func (d *DockerTestFramework) CreateValueBlock(issuerAccountID iotago.AccountID) } // CreateDelegationBlockFromInput consumes the given basic output, then build a block of a transaction that includes a delegation output, in order to delegate the given validator. -func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerID iotago.AccountID, validator *Node, inputID iotago.OutputID) (iotago.DelegationID, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerID iotago.AccountID, accountAdddress *iotago.AccountAddress, inputID iotago.OutputID) (iotago.DelegationID, iotago.OutputID, *iotago.Block) { issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateDelegationFromInput(issuerID, validator, inputID, issuerResp) + signedTx := d.wallet.CreateDelegationFromInput(issuerID, accountAdddress, inputID, issuerResp) outputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) return iotago.DelegationIDFromOutputID(outputID), @@ -540,16 +540,16 @@ func (d *DockerTestFramework) CreateAccount(opts ...options.Option[builder.Accou } // DelegateToValidator requests faucet funds and delegate the UTXO output to the validator. -func (d *DockerTestFramework) DelegateToValidator(fromID iotago.AccountID, validator *Node) iotago.EpochIndex { +func (d *DockerTestFramework) DelegateToValidator(fromID iotago.AccountID, accountAddress *iotago.AccountAddress) (iotago.OutputID, *iotago.DelegationOutput) { from := d.wallet.Account(fromID) - clt := d.wallet.Clients[validator.Name] + clt := d.wallet.DefaultClient() // requesting faucet funds as delegation input ctx := context.TODO() fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, from.Address) - signedTx := d.wallet.CreateDelegationFromInput(fromID, validator, fundsOutputID, issuerResp) + signedTx := d.wallet.CreateDelegationFromInput(fromID, accountAddress, fundsOutputID, issuerResp) blkID := d.SubmitPayload(ctx, signedTx, from.ID, congestionResp, issuerResp) d.AwaitTransactionPayloadAccepted(ctx, blkID) @@ -557,7 +557,9 @@ func (d *DockerTestFramework) DelegateToValidator(fromID iotago.AccountID, valid delegationOutput, ok := signedTx.Transaction.Outputs[0].(*iotago.DelegationOutput) require.True(d.Testing, ok) - return delegationOutput.StartEpoch + delegationOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) + + return delegationOutputID, delegationOutput } // PrepareBlockIssuance prepares the BlockIssuance and Congestion response, and increase BIC of the issuer if necessary. diff --git a/tools/docker-network/tests/eventapi_test.go b/tools/docker-network/tests/eventapi_test.go index 3fac76078..e764ee8c7 100644 --- a/tools/docker-network/tests/eventapi_test.go +++ b/tools/docker-network/tests/eventapi_test.go @@ -193,7 +193,7 @@ func test_DelegationTransactionBlocks(t *testing.T, d *DockerTestFramework) { fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) // prepare data blocks to send - delegationId, outputId, blk := d.CreateDelegationBlockFromInput(account.ID, d.Node("V2"), fundsOutputID) + delegationId, outputId, blk := d.CreateDelegationBlockFromInput(account.ID, d.Node("V2").AccountAddress(t), fundsOutputID) expectedBlocks := map[string]*iotago.Block{ blk.MustID().ToHex(): blk, } diff --git a/tools/docker-network/tests/wallet.go b/tools/docker-network/tests/wallet.go index 1393465e3..8c574115d 100644 --- a/tools/docker-network/tests/wallet.go +++ b/tools/docker-network/tests/wallet.go @@ -262,18 +262,15 @@ func (w *DockerWallet) TransitionImplicitAccountToAccountOutput(inputID iotago.O return accountInfo, signedTx } -func (w *DockerWallet) CreateDelegationFromInput(issuerID iotago.AccountID, validator *Node, inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { +func (w *DockerWallet) CreateDelegationFromInput(issuerID iotago.AccountID, validatorAccountAddr *iotago.AccountAddress, inputID iotago.OutputID, issuerResp *api.IssuanceBlockHeaderResponse) *iotago.SignedTransaction { input := w.Output(inputID) - _, validatorAccountAddr, err := iotago.ParseBech32(validator.AccountAddressBech32) - require.NoError(w.Testing, err) - currentSlot := w.DefaultClient().LatestAPI().TimeProvider().CurrentSlot() apiForSlot := w.DefaultClient().APIForSlot(currentSlot) // construct delegation transaction //nolint:forcetypeassert - delegationOutput := builder.NewDelegationOutputBuilder(validatorAccountAddr.(*iotago.AccountAddress), input.Address, input.Output.BaseTokenAmount()). + delegationOutput := builder.NewDelegationOutputBuilder(validatorAccountAddr, input.Address, input.Output.BaseTokenAmount()). StartEpoch(getDelegationStartEpoch(apiForSlot, issuerResp.LatestCommitment.Slot)). DelegatedAmount(input.Output.BaseTokenAmount()).MustBuild() signedTx, err := builder.NewTransactionBuilder(apiForSlot, w.AddressSigner(input.AddressIndex)). From 485b34066f28378b37e2c56bd012f8a0170b179c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 14:09:07 +0100 Subject: [PATCH 07/22] Increase created assets num --- tools/docker-network/tests/coreapi_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 9ed42de1e..25671534f 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -36,7 +36,7 @@ func Test_CoreAPI(t *testing.T) { d.WaitUntilNetworkReady() - assetsPerSlot, lastSlot := d.prepareAssets(1) + assetsPerSlot, lastSlot := d.prepareAssets(5) fmt.Println("AwaitCommitment for slot", lastSlot) d.AwaitCommitment(lastSlot) From 94e00d914659d6c1171cd59ded845407fc3a7c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 15:29:03 +0100 Subject: [PATCH 08/22] Add status codes test --- tools/docker-network/tests/coreapi_test.go | 202 ++++++++++++++++++ tools/docker-network/tests/dockerframework.go | 14 +- tools/docker-network/tests/utils.go | 29 +++ 3 files changed, 238 insertions(+), 7 deletions(-) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 25671534f..0145b8e2f 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -5,6 +5,7 @@ package tests import ( "context" "fmt" + "net/http" "testing" "time" @@ -13,6 +14,7 @@ import ( "github.com/iotaledger/hive.go/lo" iotago "github.com/iotaledger/iota.go/v4" "github.com/iotaledger/iota.go/v4/api" + "github.com/iotaledger/iota.go/v4/tpkg" ) func Test_CoreAPI(t *testing.T) { @@ -315,3 +317,203 @@ func Test_CoreAPI(t *testing.T) { assetsPerSlot.assertCommitments(t) assetsPerSlot.assertBICs(t) } + +func TestCoreAPI_BadRequests(t *testing.T) { + d := NewDockerTestFramework(t, + WithProtocolParametersOptions( + iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4), + iotago.WithLivenessOptions(10, 10, 2, 4, 8), + iotago.WithRewardsOptions(8, 10, 2, 384), + iotago.WithTargetCommitteeSize(4), + )) + defer d.Stop() + + d.AddValidatorNode("V1", "docker-network-inx-validator-1-1", "http://localhost:8050", "rms1pzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3y5rx2w6") + 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") + + runErr := d.Run() + require.NoError(t, runErr) + + d.WaitUntilNetworkReady() + + tests := []struct { + name string + testFunc func(t *testing.T, nodeAlias string) + }{ + { + name: "Test_BlockByBlockID_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + blockID := tpkg.RandBlockID() + respBlock, err := d.wallet.Clients[nodeAlias].BlockByBlockID(context.Background(), blockID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, respBlock) + }, + }, + { + name: "Test_BlockMetadataByBlockID_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + blockID := tpkg.RandBlockID() + resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), blockID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_BlockWithMetadata_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + blockID := tpkg.RandBlockID() + resp, err := d.wallet.Clients[nodeAlias].BlockWithMetadataByID(context.Background(), blockID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_CommitmentBySlot_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + slot := iotago.SlotIndex(1000_000_000) + resp, err := d.wallet.Clients[nodeAlias].CommitmentByIndex(context.Background(), slot) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_CommitmentByID_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + committmentID := tpkg.RandCommitmentID() + resp, err := d.wallet.Clients[nodeAlias].CommitmentByID(context.Background(), committmentID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_CommitmentUTXOChangesByID_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + committmentID := tpkg.RandCommitmentID() + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesByID(context.Background(), committmentID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + "Test_CommitmentUTXOChangesFullByID_Failure", + func(t *testing.T, nodeAlias string) { + committmentID := tpkg.RandCommitmentID() + + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesFullByID(context.Background(), committmentID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_CommitmentUTXOChangesBySlot_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + slot := iotago.SlotIndex(1000_000_000) + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesByIndex(context.Background(), slot) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_CommitmentUTXOChangesFullBySlot_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + slot := iotago.SlotIndex(1000_000_000) + + resp, err := d.wallet.Clients[nodeAlias].CommitmentUTXOChangesFullByIndex(context.Background(), slot) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_OutputByID_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + outputID := tpkg.RandOutputID(0) + resp, err := d.wallet.Clients[nodeAlias].OutputByID(context.Background(), outputID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_OutputMetadata_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + outputID := tpkg.RandOutputID(0) + + resp, err := d.wallet.Clients[nodeAlias].OutputMetadataByID(context.Background(), outputID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_TransactionsIncludedBlock_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + txID := tpkg.RandTransactionID() + resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlock(context.Background(), txID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_TransactionsIncludedBlockMetadata_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + txID := tpkg.RandTransactionID() + + resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlockMetadata(context.Background(), txID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_TransactionsMetadata_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + txID := tpkg.RandTransactionID() + + resp, err := d.wallet.Clients[nodeAlias].TransactionMetadata(context.Background(), txID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + { + name: "Test_Congestion_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + accountAddress := tpkg.RandAccountAddress() + commitmentID := tpkg.RandCommitmentID() + resp, err := d.wallet.Clients[nodeAlias].Congestion(context.Background(), accountAddress, 0, commitmentID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusBadRequest)) + require.Nil(t, resp) + }, + }, + { + name: "Test_Rewards_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + outputID := tpkg.RandOutputID(0) + resp, err := d.wallet.Clients[nodeAlias].Rewards(context.Background(), outputID) + require.Error(t, err) + require.True(t, isStatusCode(err, http.StatusNotFound)) + require.Nil(t, resp) + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + d.requestFromClients(test.testFunc) + }) + } +} diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index 81953e6f8..bd1fb7191 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -421,13 +421,13 @@ func (d *DockerTestFramework) CreateDelegationBlockFromInput(issuerID iotago.Acc } // CreateFoundryBlockFromInput consumes the given basic output, then build a block of a transaction that includes a foundry output with the given mintedAmount and maxSupply. -func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerID iotago.AccountID, inputId iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerID iotago.AccountID, inputID iotago.OutputID, mintedAmount iotago.BaseToken, maxSupply iotago.BaseToken) (iotago.FoundryID, iotago.OutputID, *iotago.Block) { issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(issuerID, inputId, mintedAmount, maxSupply, issuerResp) + signedTx := d.wallet.CreateFoundryAndNativeTokensFromInput(issuerID, inputID, mintedAmount, maxSupply, issuerResp) txID, err := signedTx.Transaction.ID() require.NoError(d.Testing, err) @@ -438,18 +438,18 @@ func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerID iotago.Accoun } // CreateNFTBlockFromInput consumes the given basic output, then build a block of a transaction that includes a NFT output with the given NFT output options. -func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerId iotago.AccountID, inputId iotago.OutputID, opts ...options.Option[builder.NFTOutputBuilder]) (iotago.NFTID, iotago.OutputID, *iotago.Block) { - issuer := d.wallet.Account(issuerId) +func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerID iotago.AccountID, inputId iotago.OutputID, opts ...options.Option[builder.NFTOutputBuilder]) (iotago.NFTID, iotago.OutputID, *iotago.Block) { + issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateNFTFromInput(issuerId, inputId, issuerResp, opts...) + signedTx := d.wallet.CreateNFTFromInput(issuerID, inputId, issuerResp, opts...) outputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0) return iotago.NFTIDFromOutputID(outputID), outputID, - d.CreateBlock(signedTx, issuerId, congestionResp, issuerResp) + d.CreateBlock(signedTx, issuerID, congestionResp, issuerResp) } // CreateFoundryTransitionBlockFromInput consumes the given foundry output, then build block by increasing the minted amount by 1. @@ -470,7 +470,7 @@ func (d *DockerTestFramework) CreateFoundryTransitionBlockFromInput(issuerID iot } // CreateAccountBlockFromInput consumes the given output, which should be either an basic output with implicit address, then build block with the given account output options. Note that after the returned transaction is issued, remember to update the account information in the wallet with AddAccount(). -func (d *DockerTestFramework) CreateAccountBlockFromInput(inputID iotago.OutputID, opts ...options.Option[builder.AccountOutputBuilder]) (*AccountData, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateAccountBlockFromInput(inputID iotago.OutputID) (*AccountData, iotago.OutputID, *iotago.Block) { ctx := context.TODO() clt := d.wallet.DefaultClient() input := d.wallet.Output(inputID) diff --git a/tools/docker-network/tests/utils.go b/tools/docker-network/tests/utils.go index dc542be69..6192590f3 100644 --- a/tools/docker-network/tests/utils.go +++ b/tools/docker-network/tests/utils.go @@ -10,7 +10,9 @@ import ( "io" "net/http" "os" + "regexp" "sort" + "strconv" "time" "github.com/stretchr/testify/require" @@ -340,3 +342,30 @@ func getDelegationStartEpoch(api iotago.API, commitmentSlot iotago.SlotIndex) io return pastBoundedEpoch + 2 } + +func isStatusCode(err error, status int) bool { + if err == nil { + return false + } + code, err := extractStatusCode(err.Error()) + if err != nil { + return false + } + + return code == status +} + +func extractStatusCode(errorMessage string) (int, error) { + re := regexp.MustCompile(`code=(\d+)`) + matches := re.FindStringSubmatch(errorMessage) + if len(matches) != 2 { + return 0, ierrors.Errorf("unable to extract status code from error message") + } + + statusCode, err := strconv.Atoi(matches[1]) + if err != nil { + return 0, err + } + + return statusCode, nil +} From 8e4705940e0410e5a459057c2c4e97dbbdc000d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 15:48:01 +0100 Subject: [PATCH 09/22] Update iota.go --- go.mod | 6 +++--- go.sum | 12 ++++++------ tools/gendoc/go.mod | 6 +++--- tools/gendoc/go.sum | 12 ++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 344ef99bf..e5a3956f6 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/iotaledger/hive.go/stringify v0.0.0-20240307102857-7e23a3c59bd2 github.com/iotaledger/inx-app v1.0.0-rc.3.0.20240216141618-d7dfe94bdc1e github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5 - github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0 + github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd github.com/labstack/echo/v4 v4.11.4 github.com/labstack/gommon v0.4.2 github.com/libp2p/go-libp2p v0.32.2 @@ -43,7 +43,7 @@ require ( github.com/zyedidia/generic v1.2.1 go.uber.org/atomic v1.11.0 go.uber.org/dig v1.17.1 - golang.org/x/crypto v0.19.0 + golang.org/x/crypto v0.21.0 google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 ) @@ -172,7 +172,7 @@ require ( golang.org/x/mod v0.15.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.18.0 // indirect diff --git a/go.sum b/go.sum index b571042b1..a37de3d2c 100644 --- a/go.sum +++ b/go.sum @@ -311,8 +311,8 @@ github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5 h1:ebh2IK github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5/go.mod h1:Go1Gp6s+RCwNyaTjSw/TCk1Li5xd3+926aCu61kL+ks= github.com/iotaledger/iota-crypto-demo v0.0.0-20240216103559-27ca8dffd1e7 h1:t6k4MqiUov0FrBb2o2JhKlOVSdlPbIQWM8ivYHL0G0g= github.com/iotaledger/iota-crypto-demo v0.0.0-20240216103559-27ca8dffd1e7/go.mod h1:do+N3LpeDEi9qselEC4XcjqGoRc7cWGiqBtIeBOKEMs= -github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0 h1:NiCqSq9oUgZA963fT5BItiE81ssUVQn+dCRKmSxCl8w= -github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0/go.mod h1:T+r7s/NHTIBeumXGiHdRrCCri1Z98bKEX7JkuHo0Blg= +github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd h1:XwvLybclVcTcuYLgJkMvNdh947hPQzMAJMNLrCUWlzc= +github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd/go.mod h1:8UQOTI7CC5R/3TurawUFuBZbkb37RzW8m4q8Hp7ct30= github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -712,8 +712,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= @@ -815,8 +815,8 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/tools/gendoc/go.mod b/tools/gendoc/go.mod index 70b938e1e..b175698f8 100644 --- a/tools/gendoc/go.mod +++ b/tools/gendoc/go.mod @@ -72,7 +72,7 @@ require ( github.com/iotaledger/inx-app v1.0.0-rc.3.0.20240216141618-d7dfe94bdc1e // indirect github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5 // indirect github.com/iotaledger/iota-crypto-demo v0.0.0-20240216103559-27ca8dffd1e7 // indirect - github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0 // indirect + github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd // indirect github.com/ipfs/boxo v0.17.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect @@ -162,13 +162,13 @@ require ( go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.19.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect golang.org/x/image v0.15.0 // indirect golang.org/x/mod v0.15.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.18.0 // indirect diff --git a/tools/gendoc/go.sum b/tools/gendoc/go.sum index 65388aeb0..d7344ee31 100644 --- a/tools/gendoc/go.sum +++ b/tools/gendoc/go.sum @@ -315,8 +315,8 @@ github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5 h1:ebh2IK github.com/iotaledger/inx/go v1.0.0-rc.2.0.20240216141023-6d5f4ef12ac5/go.mod h1:Go1Gp6s+RCwNyaTjSw/TCk1Li5xd3+926aCu61kL+ks= github.com/iotaledger/iota-crypto-demo v0.0.0-20240216103559-27ca8dffd1e7 h1:t6k4MqiUov0FrBb2o2JhKlOVSdlPbIQWM8ivYHL0G0g= github.com/iotaledger/iota-crypto-demo v0.0.0-20240216103559-27ca8dffd1e7/go.mod h1:do+N3LpeDEi9qselEC4XcjqGoRc7cWGiqBtIeBOKEMs= -github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0 h1:NiCqSq9oUgZA963fT5BItiE81ssUVQn+dCRKmSxCl8w= -github.com/iotaledger/iota.go/v4 v4.0.0-20240305173701-2dae7ac7d3a0/go.mod h1:T+r7s/NHTIBeumXGiHdRrCCri1Z98bKEX7JkuHo0Blg= +github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd h1:XwvLybclVcTcuYLgJkMvNdh947hPQzMAJMNLrCUWlzc= +github.com/iotaledger/iota.go/v4 v4.0.0-20240307144250-b67e2d066bcd/go.mod h1:8UQOTI7CC5R/3TurawUFuBZbkb37RzW8m4q8Hp7ct30= github.com/ipfs/boxo v0.17.0 h1:fVXAb12dNbraCX1Cdid5BB6Kl62gVLNVA+e0EYMqAU0= github.com/ipfs/boxo v0.17.0/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= @@ -714,8 +714,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= @@ -817,8 +817,8 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 99c816ff5b8e666f0d71597c84c23c9ad93da63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 20:57:25 +0100 Subject: [PATCH 10/22] Fix check synced --- components/restapi/core/component.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index b00344fcc..46fd270b8 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -61,7 +61,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointBlockMetadata), func(c echo.Context) error { resp, err := blockMetadataByID(c) @@ -112,7 +112,7 @@ func configure() error { } return responseByHeader(c, commitment.Commitment()) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentByIDUTXOChanges), func(c echo.Context) error { commitmentID, err := httpserver.ParseCommitmentIDParam(c, api.ParameterCommitmentID) @@ -132,7 +132,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentByIDUTXOChangesFull), func(c echo.Context) error { commitmentID, err := httpserver.ParseCommitmentIDParam(c, api.ParameterCommitmentID) @@ -152,7 +152,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlot), func(c echo.Context) error { index, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -166,7 +166,7 @@ func configure() error { } return responseByHeader(c, commitment.Commitment()) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlotUTXOChanges), func(c echo.Context) error { slot, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -185,7 +185,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointCommitmentBySlotUTXOChangesFull), func(c echo.Context) error { slot, err := httpserver.ParseSlotParam(c, api.ParameterSlot) @@ -204,7 +204,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointOutput), func(c echo.Context) error { resp, err := outputFromOutputID(c) @@ -213,7 +213,7 @@ func configure() error { } return responseByHeader(c, resp) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointOutputMetadata), func(c echo.Context) error { resp, err := outputMetadataFromOutputID(c) @@ -240,7 +240,7 @@ func configure() error { } return responseByHeader(c, block) - }, checkNodeSynced()) + }) routeGroup.GET(api.EndpointWithEchoParameters(api.CoreEndpointTransactionsIncludedBlockMetadata), func(c echo.Context) error { resp, err := blockMetadataFromTransactionID(c) From cd7d007d12f3bcf2ca0443e1e287a1dd985b608b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 20:59:24 +0100 Subject: [PATCH 11/22] Apply suggestions for errors --- pkg/requesthandler/commitments.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/requesthandler/commitments.go b/pkg/requesthandler/commitments.go index 558a5828a..928f80945 100644 --- a/pkg/requesthandler/commitments.go +++ b/pkg/requesthandler/commitments.go @@ -19,7 +19,7 @@ func (r *RequestHandler) GetCommitmentBySlot(slot iotago.SlotIndex) (*model.Comm commitment, err := r.protocol.Engines.Main.Get().Storage.Commitments().Load(slot) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, slot: %d, error: %v", slot, err) + return nil, ierrors.Join(echo.ErrInternalServerError, ierrors.Wrapf(err, "failed to load commitment, slot: %d", slot)) } return commitment, nil @@ -38,11 +38,11 @@ func (r *RequestHandler) GetCommitmentByID(commitmentID iotago.CommitmentID) (*m commitment, err := r.protocol.Engines.Main.Get().Storage.Commitments().Load(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Join(echo.ErrInternalServerError, ierrors.Wrapf(err, "failed to load commitment, commitmentID: %s, slot: %d", commitmentID, commitmentID.Slot())) } if commitment.ID() != commitmentID { - return nil, ierrors.Wrapf(echo.ErrBadRequest, "commitment in the store for slot %d does not match the given commitmentID (%s != %s)", commitmentID.Slot(), commitment.ID(), commitmentID) + return nil, ierrors.Join(echo.ErrBadRequest, ierrors.Wrapf(err, "commitment in the store for slot %d does not match the given commitmentID (%s != %s)", commitmentID.Slot(), commitment.ID(), commitmentID)) } return commitment, nil @@ -55,7 +55,7 @@ func (r *RequestHandler) GetLatestCommitment() *model.Commitment { func (r *RequestHandler) GetUTXOChanges(commitmentID iotago.CommitmentID) (*api.UTXOChangesResponse, error) { diffs, err := r.protocol.Engines.Main.Get().Ledger.SlotDiffs(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Join(echo.ErrInternalServerError, ierrors.Wrapf(err, "failed to get slot diffs, commitmentID: %s, slot: %d", commitmentID, commitmentID.Slot())) } createdOutputs := make(iotago.OutputIDs, len(diffs.Outputs)) @@ -79,7 +79,7 @@ func (r *RequestHandler) GetUTXOChanges(commitmentID iotago.CommitmentID) (*api. func (r *RequestHandler) GetUTXOChangesFull(commitmentID iotago.CommitmentID) (*api.UTXOChangesFullResponse, error) { diffs, err := r.protocol.Engines.Main.Get().Ledger.SlotDiffs(commitmentID.Slot()) if err != nil { - return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs, commitmentID: %s, slot: %d, error: %v", commitmentID, commitmentID.Slot(), err) + return nil, ierrors.Join(echo.ErrInternalServerError, ierrors.Wrapf(err, "failed to get slot diffs, commitmentID: %s, slot: %d", commitmentID, commitmentID.Slot())) } createdOutputs := make([]*api.OutputWithID, len(diffs.Outputs)) From ef94cd5b7de99b3fb1b783e0ee98795c1236c03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 21:23:55 +0100 Subject: [PATCH 12/22] Revert to InternalServerErrors --- pkg/requesthandler/accounts.go | 2 +- pkg/requesthandler/blocks.go | 2 +- pkg/requesthandler/transaction.go | 2 +- pkg/requesthandler/utxo.go | 6 +++--- tools/docker-network/tests/coreapi_test.go | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/requesthandler/accounts.go b/pkg/requesthandler/accounts.go index fcc83cc20..e2aabaeb9 100644 --- a/pkg/requesthandler/accounts.go +++ b/pkg/requesthandler/accounts.go @@ -99,7 +99,7 @@ func (r *RequestHandler) ValidatorByAccountAddress(accountAddress *iotago.Accoun func (r *RequestHandler) RewardsByOutputID(outputID iotago.OutputID, slot iotago.SlotIndex) (*api.ManaRewardsResponse, error) { utxoOutput, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from ledger: %s", outputID.ToHex(), err) } var stakingPoolValidatorAccountID iotago.AccountID diff --git a/pkg/requesthandler/blocks.go b/pkg/requesthandler/blocks.go index baaf5e07a..1838848d9 100644 --- a/pkg/requesthandler/blocks.go +++ b/pkg/requesthandler/blocks.go @@ -23,7 +23,7 @@ func (r *RequestHandler) BlockByID(blockID iotago.BlockID) (*iotago.Block, error func (r *RequestHandler) BlockMetadataByBlockID(blockID iotago.BlockID) (*api.BlockMetadataResponse, error) { blockMetadata, err := r.protocol.Engines.Main.Get().BlockRetainer.BlockMetadata(blockID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "metadata not found for block %s: %s", blockID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err) } return blockMetadata, nil diff --git a/pkg/requesthandler/transaction.go b/pkg/requesthandler/transaction.go index 69ba17dd2..290c17d63 100644 --- a/pkg/requesthandler/transaction.go +++ b/pkg/requesthandler/transaction.go @@ -16,7 +16,7 @@ func (r *RequestHandler) BlockIDFromTransactionID(transactionID iotago.Transacti output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return iotago.EmptyBlockID, ierrors.Wrapf(echo.ErrNotFound, "output %s of transaction %s not found: %s", transactionID.ToHex(), outputID.ToHex(), err) + return iotago.EmptyBlockID, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s: %s", outputID.ToHex(), err) } if output != nil { diff --git a/pkg/requesthandler/utxo.go b/pkg/requesthandler/utxo.go index f5a2b7a96..c9bd951df 100644 --- a/pkg/requesthandler/utxo.go +++ b/pkg/requesthandler/utxo.go @@ -12,7 +12,7 @@ import ( func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.OutputResponse, error) { output, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } return &api.OutputResponse{ @@ -24,7 +24,7 @@ func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.Outp func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputMetadata, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } if spent != nil { @@ -37,7 +37,7 @@ func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (* func (r *RequestHandler) OutputWithMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputWithMetadataResponse, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { - return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger: %s", outputID.ToHex(), err) + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } if spent != nil { diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 985e76d36..00bc08de0 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -359,7 +359,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { blockID := tpkg.RandBlockID() resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), blockID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, @@ -441,7 +441,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { outputID := tpkg.RandOutputID(0) resp, err := d.wallet.Clients[nodeAlias].OutputByID(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, @@ -452,7 +452,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].OutputMetadataByID(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, @@ -462,7 +462,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { txID := tpkg.RandTransactionID() resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlock(context.Background(), txID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, @@ -473,7 +473,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlockMetadata(context.Background(), txID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, @@ -505,7 +505,7 @@ func TestCoreAPI_BadRequests(t *testing.T) { outputID := tpkg.RandOutputID(0) resp, err := d.wallet.Clients[nodeAlias].Rewards(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusNotFound)) + require.True(t, isStatusCode(err, http.StatusInternalServerError)) require.Nil(t, resp) }, }, From ea889257a2bd4a0586ce709b8696ab13de067721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Thu, 7 Mar 2024 21:33:00 +0100 Subject: [PATCH 13/22] Add forgotten Test_OutputWithMetadata --- tools/docker-network/tests/coreapi_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 00bc08de0..1050158a0 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -193,6 +193,20 @@ func Test_CoreAPI(t *testing.T) { }) }, }, + { + name: "Test_OutputWithMetadata", + testFunc: func(t *testing.T, nodeAlias string) { + assetsPerSlot.forEachOutput(t, func(t *testing.T, outputID iotago.OutputID, output iotago.Output) { + out, outMetadata, err := d.wallet.Clients[nodeAlias].OutputWithMetadataByID(context.Background(), outputID) + require.NoError(t, err) + require.NotNil(t, outMetadata) + require.NotNil(t, out) + require.EqualValues(t, outputID, outMetadata.OutputID, "OutputID of retrieved output does not match: %s != %s", outputID, outMetadata.OutputID) + require.EqualValues(t, outputID.TransactionID(), outMetadata.Included.TransactionID, "TransactionID of retrieved output does not match: %s != %s", outputID.TransactionID(), outMetadata.Included.TransactionID) + require.EqualValues(t, output, out, "OutputID of retrieved output does not match: %s != %s", output, out) + }) + }, + }, { name: "Test_TransactionsIncludedBlock", testFunc: func(t *testing.T, nodeAlias string) { @@ -318,7 +332,7 @@ func Test_CoreAPI(t *testing.T) { assetsPerSlot.assertBICs(t) } -func TestCoreAPI_BadRequests(t *testing.T) { +func Test_CoreAPI_BadRequests(t *testing.T) { d := NewDockerTestFramework(t, WithProtocolParametersOptions( iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4), From 0ed1b3090932270ac2d40f23ab4e33ae5388808c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Mon, 11 Mar 2024 10:51:40 +0100 Subject: [PATCH 14/22] Remove incorrect validators check --- components/restapi/core/accounts.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index 25c050c9d..c3a7147d1 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -71,10 +71,6 @@ func validators(c echo.Context) (*api.ValidatorsResponse, error) { } } - // do not respond to really old requests - if requestedSlot+iotago.SlotIndex(restapi.ParamsRestAPI.MaxRequestedSlotAge) < latestCommittedSlot { - return nil, ierrors.Wrapf(echo.ErrBadRequest, "request is too old, request started at %d, latest committed slot index is %d", requestedSlot, latestCommittedSlot) - } slotRange := uint32(requestedSlot) / restapi.ParamsRestAPI.RequestsMemoryCacheGranularity return deps.RequestHandler.Validators(slotRange, cursorIndex, pageSize) From 8c489abcc4571c60c0075f04bfa129c35aa510bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Mon, 11 Mar 2024 10:53:27 +0100 Subject: [PATCH 15/22] Await finalisation instead of commitment --- tools/docker-network/tests/coreapi_test.go | 4 ++-- tools/docker-network/tests/dockerframework.go | 2 +- tools/docker-network/tests/utils.go | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 1050158a0..15325d726 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -40,8 +40,8 @@ func Test_CoreAPI(t *testing.T) { assetsPerSlot, lastSlot := d.prepareAssets(5) - fmt.Println("AwaitCommitment for slot", lastSlot) - d.AwaitCommitment(lastSlot) + fmt.Println("Await finalisation of slot", lastSlot) + d.AwaitFinalization(lastSlot) tests := []struct { name string diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index 99db4f501..0f66c56df 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -656,7 +656,7 @@ func (d *DockerTestFramework) RequestFaucetFunds(ctx context.Context, addressTyp Output: output, }) - fmt.Println("Faucet funds received, txID:", outputID.TransactionID().ToHex(), ", amount:", output.BaseTokenAmount(), ", mana:", output.StoredMana()) + fmt.Printf("Faucet funds received, txID: %s, amount: %d, mana: %d", outputID.TransactionID().ToHex(), output.BaseTokenAmount(), output.StoredMana()) return outputID } diff --git a/tools/docker-network/tests/utils.go b/tools/docker-network/tests/utils.go index 890bd0464..eaffcfd24 100644 --- a/tools/docker-network/tests/utils.go +++ b/tools/docker-network/tests/utils.go @@ -228,6 +228,17 @@ func (d *DockerTestFramework) AwaitCommitment(targetSlot iotago.SlotIndex) { } } +func (d *DockerTestFramework) AwaitFinalization(targetSlot iotago.SlotIndex) { + d.Eventually(func() error { + currentFinalisedSlot := d.NodeStatus("V1").LatestFinalizedSlot + if targetSlot > currentFinalisedSlot { + return ierrors.Errorf("finalized slot %d is not reached yet", targetSlot) + } + + return nil + }) +} + func (d *DockerTestFramework) AwaitAddressUnspentOutputAccepted(ctx context.Context, addr iotago.Address) (outputID iotago.OutputID, output iotago.Output, err error) { indexerClt, err := d.wallet.DefaultClient().Indexer(ctx) require.NoError(d.Testing, err) From f75e926986bc1383f3c2926204668186af4d79c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Mon, 11 Mar 2024 10:53:48 +0100 Subject: [PATCH 16/22] Issue reattachment, and check the first included block --- tools/docker-network/tests/coreapi.go | 25 ++++++++++++++++++---- tools/docker-network/tests/coreapi_test.go | 19 +++++++++++----- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index d1fd8793f..36af1044d 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -47,10 +47,19 @@ func (a coreAPIAssets) forEachBlock(t *testing.T, f func(*testing.T, *iotago.Blo } } -func (a coreAPIAssets) forEachTransaction(t *testing.T, f func(*testing.T, *iotago.SignedTransaction)) { +func (a coreAPIAssets) forEachTransaction(t *testing.T, f func(*testing.T, *iotago.SignedTransaction, iotago.BlockID)) { for _, asset := range a { - for _, tx := range asset.transactions { - f(t, tx) + for i, tx := range asset.transactions { + blockID := asset.valueBlocks[i].MustID() + f(t, tx, blockID) + } + } +} + +func (a coreAPIAssets) forEachReattachment(t *testing.T, f func(*testing.T, iotago.BlockID)) { + for _, asset := range a { + for _, reattachment := range asset.reattachments { + f(t, reattachment) } } } @@ -141,6 +150,7 @@ type coreAPISlotAssets struct { dataBlocks []*iotago.Block valueBlocks []*iotago.Block transactions []*iotago.SignedTransaction + reattachments []iotago.BlockID basicOutputs map[iotago.OutputID]iotago.Output faucetOutputs map[iotago.OutputID]iotago.Output delegationOutputs map[iotago.OutputID]iotago.Output @@ -172,6 +182,7 @@ func newAssetsPerSlot() *coreAPISlotAssets { dataBlocks: make([]*iotago.Block, 0), valueBlocks: make([]*iotago.Block, 0), transactions: make([]*iotago.SignedTransaction, 0), + reattachments: make([]iotago.BlockID, 0), basicOutputs: make(map[iotago.OutputID]iotago.Output), faucetOutputs: make(map[iotago.OutputID]iotago.Output), delegationOutputs: make(map[iotago.OutputID]iotago.Output), @@ -212,11 +223,17 @@ func (d *DockerTestFramework) prepareAssets(totalAssetsNum int) (coreAPIAssets, d.SubmitBlock(ctx, valueBlock) d.AwaitTransactionPayloadAccepted(ctx, signedTx.Transaction.MustID()) + // issue reattachment after the fisrt one is already included + issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, d.wallet.DefaultClient(), account.Address) + secondAttachment := d.SubmitPayload(ctx, signedTx, account.Address.AccountID(), congestionResp, issuerResp) + assets[valueBlockSlot].reattachments = append(assets[valueBlockSlot].reattachments, secondAttachment) + + // delegation delegationOutputID, delegationOutput := d.DelegateToValidator(account.ID, d.Node("V1").AccountAddress(d.Testing)) assets.setupAssetsForSlot(delegationOutputID.CreationSlot()) assets[delegationOutputID.CreationSlot()].delegationOutputs[delegationOutputID] = delegationOutput - latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot, valueBlockSlot, delegationOutputID.CreationSlot()) + latestSlot = lo.Max[iotago.SlotIndex](latestSlot, blockSlot, valueBlockSlot, delegationOutputID.CreationSlot(), secondAttachment.Slot()) fmt.Printf("Assets for slot %d\n: dataBlock: %s block: %s\ntx: %s\nbasic output: %s, faucet output: %s\n delegation output: %s\n", valueBlockSlot, block.MustID().String(), valueBlock.MustID().String(), lo.PanicOnErr(signedTx.ID()).String(), diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index 15325d726..e5d2567bc 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -76,6 +76,14 @@ func Test_CoreAPI(t *testing.T) { require.Equal(t, block.MustID(), resp.BlockID, "BlockID of retrieved block does not match: %s != %s", block.MustID(), resp.BlockID) require.Equal(t, api.BlockStateFinalized, resp.BlockState) }) + + assetsPerSlot.forEachReattachment(t, func(t *testing.T, blockID iotago.BlockID) { + resp, err := d.wallet.Clients[nodeAlias].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) + require.Equal(t, api.BlockStateFinalized, resp.BlockState) + }) }, }, { @@ -210,34 +218,35 @@ func Test_CoreAPI(t *testing.T) { { name: "Test_TransactionsIncludedBlock", testFunc: func(t *testing.T, nodeAlias string) { - assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlock(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) require.NoError(t, err) require.NotNil(t, resp) + require.EqualValues(t, firstAttachmentID, resp.MustID()) }) - - // todo issue second block with the same tx, and make sure that the first one is returned here }, }, { name: "Test_TransactionsIncludedBlockMetadata", testFunc: func(t *testing.T, nodeAlias string) { - assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { resp, err := d.wallet.Clients[nodeAlias].TransactionIncludedBlockMetadata(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) require.NoError(t, err) require.NotNil(t, resp) require.EqualValues(t, api.BlockStateFinalized, resp.BlockState) + require.EqualValues(t, firstAttachmentID, resp.BlockID, "Inclusion BlockID of retrieved transaction does not match: %s != %s", firstAttachmentID, resp.BlockID) }) }, }, { name: "Test_TransactionsMetadata", testFunc: func(t *testing.T, nodeAlias string) { - assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction) { + assetsPerSlot.forEachTransaction(t, func(t *testing.T, transaction *iotago.SignedTransaction, firstAttachmentID iotago.BlockID) { resp, err := d.wallet.Clients[nodeAlias].TransactionMetadata(context.Background(), lo.PanicOnErr(transaction.Transaction.ID())) require.NoError(t, err) require.NotNil(t, resp) require.Equal(t, api.TransactionStateFinalized, resp.TransactionState) + require.EqualValues(t, resp.EarliestAttachmentSlot, firstAttachmentID.Slot()) }) }, }, From 126b4f4b9a5f19ab22d59ea632c459fbf2b6768c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 11:00:07 +0100 Subject: [PATCH 17/22] Move basic output tx creation to wallet, add todo --- tools/docker-network/tests/coreapi.go | 4 +-- tools/docker-network/tests/dockerframework.go | 27 +++++-------------- tools/docker-network/tests/eventapi_test.go | 1 + tools/docker-network/tests/wallet.go | 21 +++++++++++++++ 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index 36af1044d..bb85f3445 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -211,14 +211,14 @@ func (d *DockerTestFramework) prepareAssets(totalAssetsNum int) (coreAPIAssets, d.SubmitBlock(ctx, block) // transaction - valueBlock, signedTx, faucetOutput, basicOut := d.CreateValueBlock(account.ID) + valueBlock, signedTx, faucetOutput := d.CreateBasicOutputBlock(account.ID) valueBlockSlot := valueBlock.MustID().Slot() assets.setupAssetsForSlot(valueBlockSlot) // transaction and outputs are stored with the earliest included block assets[valueBlockSlot].valueBlocks = append(assets[valueBlockSlot].valueBlocks, valueBlock) assets[valueBlockSlot].transactions = append(assets[valueBlockSlot].transactions, signedTx) basicOutputID := iotago.OutputIDFromTransactionIDAndIndex(signedTx.Transaction.MustID(), 0) - assets[valueBlockSlot].basicOutputs[basicOutputID] = basicOut + assets[valueBlockSlot].basicOutputs[basicOutputID] = signedTx.Transaction.Outputs[0] assets[valueBlockSlot].faucetOutputs[faucetOutput.ID] = faucetOutput.Output d.SubmitBlock(ctx, valueBlock) d.AwaitTransactionPayloadAccepted(ctx, signedTx.Transaction.MustID()) diff --git a/tools/docker-network/tests/dockerframework.go b/tools/docker-network/tests/dockerframework.go index 0f66c56df..6fde74dd2 100644 --- a/tools/docker-network/tests/dockerframework.go +++ b/tools/docker-network/tests/dockerframework.go @@ -376,32 +376,19 @@ func (d *DockerTestFramework) CreateTaggedDataBlock(issuerID iotago.AccountID, t }, issuerID, congestionResp, issuerResp) } -func (d *DockerTestFramework) CreateValueBlock(issuerAccountID iotago.AccountID) (*iotago.Block, *iotago.SignedTransaction, *OutputData, iotago.Output) { +func (d *DockerTestFramework) CreateBasicOutputBlock(issuerAccountID iotago.AccountID) (*iotago.Block, *iotago.SignedTransaction, *OutputData) { clt := d.wallet.DefaultClient() ctx := context.Background() - currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now()) - apiForSlot := clt.APIForSlot(currentSlot) + fundsOutputID := d.RequestFaucetFunds(ctx, iotago.AddressEd25519) - _, ed25519Addr := d.wallet.Address() input := d.wallet.Output(fundsOutputID) - basicOutput := builder.NewBasicOutputBuilder(ed25519Addr, input.Output.BaseTokenAmount()).MustBuild() - signedTx, err := builder.NewTransactionBuilder(apiForSlot, d.wallet.AddressSigner(input.AddressIndex)). - AddInput(&builder.TxInput{ - UnlockTarget: input.Address, - InputID: input.ID, - Input: input.Output, - }). - AddOutput(basicOutput). - SetCreationSlot(currentSlot). - AllotAllMana(currentSlot, issuerAccountID, 0). - Build() - require.NoError(d.wallet.Testing, err) + signedTx := d.wallet.CreateBasicOutputFromInput(input, issuerAccountID) issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuerAccountID.ToAddress().(*iotago.AccountAddress)) block := d.CreateBlock(signedTx, issuerAccountID, congestionResp, issuerResp) - return block, signedTx, input, basicOutput + return block, signedTx, input } // CreateDelegationBlockFromInput consumes the given basic output, then build a block of a transaction that includes a delegation output, in order to delegate the given validator. @@ -438,13 +425,13 @@ func (d *DockerTestFramework) CreateFoundryBlockFromInput(issuerID iotago.Accoun } // CreateNFTBlockFromInput consumes the given basic output, then build a block of a transaction that includes a NFT output with the given NFT output options. -func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerID iotago.AccountID, inputId iotago.OutputID, opts ...options.Option[builder.NFTOutputBuilder]) (iotago.NFTID, iotago.OutputID, *iotago.Block) { +func (d *DockerTestFramework) CreateNFTBlockFromInput(issuerID iotago.AccountID, inputID iotago.OutputID, opts ...options.Option[builder.NFTOutputBuilder]) (iotago.NFTID, iotago.OutputID, *iotago.Block) { issuer := d.wallet.Account(issuerID) ctx := context.TODO() clt := d.wallet.DefaultClient() issuerResp, congestionResp := d.PrepareBlockIssuance(ctx, clt, issuer.Address) - signedTx := d.wallet.CreateNFTFromInput(issuerID, inputId, issuerResp, opts...) + signedTx := d.wallet.CreateNFTFromInput(issuerID, inputID, issuerResp, opts...) outputID := iotago.OutputIDFromTransactionIDAndIndex(signedTx.Transaction.MustID(), 0) return iotago.NFTIDFromOutputID(outputID), @@ -666,7 +653,7 @@ func (d *DockerTestFramework) Stop() { defer fmt.Println("Stop the network.....done") _ = exec.Command("docker", "compose", "down").Run() - _ = exec.Command("rm", d.snapshotPath).Run() + _ = exec.Command("rm", d.snapshotPath).Run() //nolint:gosec } func (d *DockerTestFramework) StopContainer(containerName ...string) error { diff --git a/tools/docker-network/tests/eventapi_test.go b/tools/docker-network/tests/eventapi_test.go index e764ee8c7..ed87a064e 100644 --- a/tools/docker-network/tests/eventapi_test.go +++ b/tools/docker-network/tests/eventapi_test.go @@ -282,6 +282,7 @@ func test_AccountTransactionBlocks(t *testing.T, d *DockerTestFramework) { assertion() } + // TODO test transactioMetadataTopics // d.AssertTransactionMetadataByTransactionID(ctx, eventClt, outputId.TransactionID(), finish) // d.AssertTransactionMetadataIncludedBlocks(ctx, eventClt, outputId.TransactionID(), finish) diff --git a/tools/docker-network/tests/wallet.go b/tools/docker-network/tests/wallet.go index c8cd7d1e0..dd2bdd5ed 100644 --- a/tools/docker-network/tests/wallet.go +++ b/tools/docker-network/tests/wallet.go @@ -7,6 +7,7 @@ import ( "math/big" "sync/atomic" "testing" + "time" "github.com/stretchr/testify/require" @@ -469,3 +470,23 @@ func (w *DockerWallet) CreateNFTFromInput(issuerID iotago.AccountID, inputID iot return signedTx } + +func (w *DockerWallet) CreateBasicOutputFromInput(input *OutputData, issuerAccountID iotago.AccountID) *iotago.SignedTransaction { + currentSlot := w.DefaultClient().LatestAPI().TimeProvider().SlotFromTime(time.Now()) + apiForSlot := w.DefaultClient().APIForSlot(currentSlot) + _, ed25519Addr := w.Address() + basicOutput := builder.NewBasicOutputBuilder(ed25519Addr, input.Output.BaseTokenAmount()).MustBuild() + signedTx, err := builder.NewTransactionBuilder(apiForSlot, w.AddressSigner(input.AddressIndex)). + AddInput(&builder.TxInput{ + UnlockTarget: input.Address, + InputID: input.ID, + Input: input.Output, + }). + AddOutput(basicOutput). + SetCreationSlot(currentSlot). + AllotAllMana(currentSlot, issuerAccountID, 0). + Build() + require.NoError(w.Testing, err) + + return signedTx +} From 9f0539930d8d9815b1c5503e2684fd86ca6e2154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 11:32:28 +0100 Subject: [PATCH 18/22] Fix assert --- tools/docker-network/tests/coreapi.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/docker-network/tests/coreapi.go b/tools/docker-network/tests/coreapi.go index bb85f3445..bafa2d80e 100644 --- a/tools/docker-network/tests/coreapi.go +++ b/tools/docker-network/tests/coreapi.go @@ -167,6 +167,7 @@ func (a *coreAPISlotAssets) assertCommitments(t *testing.T) { } require.Equal(t, commitmentID, prevCommitment) + prevCommitment = commitmentID } } @@ -174,6 +175,7 @@ func (a *coreAPISlotAssets) assertBICs(t *testing.T) { prevBIC := a.bicPerNode["V1"] for _, bic := range a.bicPerNode { require.Equal(t, bic, prevBIC) + prevBIC = bic } } From 109f4aeb204f969a98b8708319ad9ac49a8c4596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 11:33:03 +0100 Subject: [PATCH 19/22] Move checks before getting commitment --- components/restapi/core/accounts.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index c3a7147d1..a951645aa 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -26,6 +26,17 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) if workScore != 0 { workScores = append(workScores, workScore) } + maxCommittableAge := deps.RequestHandler.CommittedAPI().ProtocolParameters().MaxCommittableAge() + latestCommittedSlot := deps.RequestHandler.GetLatestCommitment().Slot() + if queryCommitmentID != iotago.EmptyCommitmentID { + if latestCommittedSlot >= maxCommittableAge && queryCommitmentID.Slot()+maxCommittableAge < latestCommittedSlot { + return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, target slot index older than allowed (%d<%d)", queryCommitmentID.Slot(), latestCommittedSlot-maxCommittableAge) + } + + if queryCommitmentID.Slot() > latestCommittedSlot { + return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, slot %d is not committed yet, latest committed slot: %d", queryCommitmentID.Slot(), latestCommittedSlot) + } + } commitment, err := deps.RequestHandler.GetCommitmentByID(queryCommitmentID) if err != nil { @@ -43,16 +54,6 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(api.ParameterBech32Address)) } - maxCommittableAge := deps.RequestHandler.CommittedAPI().ProtocolParameters().MaxCommittableAge() - latestCommittedSlot := deps.RequestHandler.GetLatestCommitment().Slot() - if latestCommittedSlot >= maxCommittableAge && commitment.Slot()+maxCommittableAge < latestCommittedSlot && queryCommitmentID != iotago.EmptyCommitmentID { - return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, target slot index older than allowed (%d<%d)", commitment.Slot(), latestCommittedSlot-maxCommittableAge) - } - - if commitment.Slot() > latestCommittedSlot && queryCommitmentID != iotago.EmptyCommitmentID { - return nil, ierrors.Wrapf(echo.ErrBadRequest, "invalid commitmentID, slot %d is not committed yet, latest committed slot: %d", commitment.Slot(), latestCommittedSlot) - } - return deps.RequestHandler.CongestionByAccountAddress(accountAddress, commitment, workScores...) } From 6c96755da3aa337db35e41021b355f3204e5c849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 12:56:11 +0100 Subject: [PATCH 20/22] Rename --- components/restapi/core/accounts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go index a951645aa..5e7a4babf 100644 --- a/components/restapi/core/accounts.go +++ b/components/restapi/core/accounts.go @@ -38,7 +38,7 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) } } - commitment, err := deps.RequestHandler.GetCommitmentByID(queryCommitmentID) + queryCommittment, err := deps.RequestHandler.GetCommitmentByID(queryCommitmentID) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func congestionByAccountAddress(c echo.Context) (*api.CongestionResponse, error) return nil, ierrors.Wrapf(httpserver.ErrInvalidParameter, "address %s is not an account address", c.Param(api.ParameterBech32Address)) } - return deps.RequestHandler.CongestionByAccountAddress(accountAddress, commitment, workScores...) + return deps.RequestHandler.CongestionByAccountAddress(accountAddress, queryCommittment, workScores...) } func validators(c echo.Context) (*api.ValidatorsResponse, error) { From 41146f04dcee70be8dc3d95e0703a3d100097cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 17:57:01 +0100 Subject: [PATCH 21/22] Better check for StatusNotFound --- pkg/requesthandler/accounts.go | 4 ++++ pkg/requesthandler/blocks.go | 4 ++++ pkg/requesthandler/utxo.go | 10 ++++++++ pkg/retainer/blockretainer/block_retainer.go | 23 +++++++++---------- .../prunable/slotstore/block_metadata.go | 6 ++--- tools/docker-network/tests/coreapi_test.go | 20 ++++++++++++---- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/pkg/requesthandler/accounts.go b/pkg/requesthandler/accounts.go index 07c16f9d3..b8b3ea82d 100644 --- a/pkg/requesthandler/accounts.go +++ b/pkg/requesthandler/accounts.go @@ -7,6 +7,7 @@ import ( "github.com/labstack/echo/v4" "github.com/iotaledger/hive.go/ierrors" + "github.com/iotaledger/hive.go/kvstore" "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/iota-core/pkg/core/account" "github.com/iotaledger/iota-core/pkg/model" @@ -100,6 +101,9 @@ func (r *RequestHandler) ValidatorByAccountAddress(accountAddress *iotago.Accoun func (r *RequestHandler) RewardsByOutputID(outputID iotago.OutputID, slot iotago.SlotIndex) (*api.ManaRewardsResponse, error) { utxoOutput, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { + if ierrors.Is(err, kvstore.ErrKeyNotFound) { + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found", outputID.ToHex()) + } return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from ledger: %s", outputID.ToHex(), err) } diff --git a/pkg/requesthandler/blocks.go b/pkg/requesthandler/blocks.go index 1838848d9..204f6d3ca 100644 --- a/pkg/requesthandler/blocks.go +++ b/pkg/requesthandler/blocks.go @@ -6,6 +6,7 @@ import ( "github.com/labstack/echo/v4" "github.com/iotaledger/hive.go/ierrors" + "github.com/iotaledger/hive.go/kvstore" "github.com/iotaledger/inx-app/pkg/httpserver" iotago "github.com/iotaledger/iota.go/v4" "github.com/iotaledger/iota.go/v4/api" @@ -23,6 +24,9 @@ func (r *RequestHandler) BlockByID(blockID iotago.BlockID) (*iotago.Block, error func (r *RequestHandler) BlockMetadataByBlockID(blockID iotago.BlockID) (*api.BlockMetadataResponse, error) { blockMetadata, err := r.protocol.Engines.Main.Get().BlockRetainer.BlockMetadata(blockID) if err != nil { + if ierrors.Is(err, kvstore.ErrKeyNotFound) { + return nil, ierrors.Wrapf(echo.ErrNotFound, "block not found: %s", blockID.ToHex()) + } return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err) } diff --git a/pkg/requesthandler/utxo.go b/pkg/requesthandler/utxo.go index c9bd951df..e82d1cf56 100644 --- a/pkg/requesthandler/utxo.go +++ b/pkg/requesthandler/utxo.go @@ -4,6 +4,7 @@ import ( "github.com/labstack/echo/v4" "github.com/iotaledger/hive.go/ierrors" + "github.com/iotaledger/hive.go/kvstore" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger" iotago "github.com/iotaledger/iota.go/v4" "github.com/iotaledger/iota.go/v4/api" @@ -12,6 +13,9 @@ import ( func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.OutputResponse, error) { output, err := r.protocol.Engines.Main.Get().Ledger.Output(outputID) if err != nil { + if ierrors.Is(err, kvstore.ErrKeyNotFound) { + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) + } return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } @@ -24,6 +28,9 @@ func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.Outp func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputMetadata, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { + if ierrors.Is(err, kvstore.ErrKeyNotFound) { + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) + } return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } @@ -37,6 +44,9 @@ func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (* func (r *RequestHandler) OutputWithMetadataFromOutputID(outputID iotago.OutputID) (*api.OutputWithMetadataResponse, error) { output, spent, err := r.protocol.Engines.Main.Get().Ledger.OutputOrSpent(outputID) if err != nil { + if ierrors.Is(err, kvstore.ErrKeyNotFound) { + return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) + } return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } diff --git a/pkg/retainer/blockretainer/block_retainer.go b/pkg/retainer/blockretainer/block_retainer.go index 2a77371ab..27363bd06 100644 --- a/pkg/retainer/blockretainer/block_retainer.go +++ b/pkg/retainer/blockretainer/block_retainer.go @@ -105,18 +105,18 @@ func (r *BlockRetainer) getBlockMetadata(blockID iotago.BlockID) (*slotstore.Blo return nil, err } - data, found := store.BlockMetadata(blockID) - if !found { - return nil, ierrors.Errorf("block %s not found", blockID.String()) + data, err := store.BlockMetadata(blockID) + if err != nil { + return nil, ierrors.Wrapf(err, "block %s not found", blockID.String()) } return data, nil } func (r *BlockRetainer) BlockMetadata(blockID iotago.BlockID) (*api.BlockMetadataResponse, error) { - blockStatus := r.blockState(blockID) - if blockStatus == api.BlockStateUnknown { - return nil, ierrors.Errorf("block %s not found", blockID.ToHex()) + blockStatus, err := r.blockState(blockID) + if err != nil { + return nil, ierrors.Wrapf(err, "block %s not found", blockID.ToHex()) } // we do not expose accepted flag @@ -130,25 +130,24 @@ func (r *BlockRetainer) BlockMetadata(blockID iotago.BlockID) (*api.BlockMetadat }, nil } -func (r *BlockRetainer) blockState(blockID iotago.BlockID) api.BlockState { +func (r *BlockRetainer) blockState(blockID iotago.BlockID) (api.BlockState, error) { blockMetadata, err := r.getBlockMetadata(blockID) if err != nil { - r.errorHandler(ierrors.Wrapf(err, "could not get block data for slot %d", blockID.Slot())) - return api.BlockStateUnknown + return api.BlockStateUnknown, err } switch blockMetadata.State { case api.BlockStatePending, api.BlockStateDropped: if blockID.Slot() <= r.latestCommittedSlotFunc() { - return api.BlockStateOrphaned + return api.BlockStateOrphaned, nil } case api.BlockStateAccepted, api.BlockStateConfirmed: if blockID.Slot() <= r.finalizedSlotFunc() { - return api.BlockStateFinalized + return api.BlockStateFinalized, nil } } - return blockMetadata.State + return blockMetadata.State, nil } // OnBlockBooked triggers storing block in the retainer on block booked event. diff --git a/pkg/storage/prunable/slotstore/block_metadata.go b/pkg/storage/prunable/slotstore/block_metadata.go index 220c55389..b57851c47 100644 --- a/pkg/storage/prunable/slotstore/block_metadata.go +++ b/pkg/storage/prunable/slotstore/block_metadata.go @@ -98,11 +98,11 @@ func (r *BlockMetadataStore) StoreBlockDropped(blockID iotago.BlockID) error { return r.blockMetadataStore.Set(blockID, blockMetadata) } -func (r *BlockMetadataStore) BlockMetadata(blockID iotago.BlockID) (*BlockMetadata, bool) { +func (r *BlockMetadataStore) BlockMetadata(blockID iotago.BlockID) (*BlockMetadata, error) { blockMetadata, err := r.blockMetadataStore.Get(blockID) if err != nil { - return nil, false + return nil, err } - return blockMetadata, true + return blockMetadata, nil } diff --git a/tools/docker-network/tests/coreapi_test.go b/tools/docker-network/tests/coreapi_test.go index e5d2567bc..f543963fd 100644 --- a/tools/docker-network/tests/coreapi_test.go +++ b/tools/docker-network/tests/coreapi_test.go @@ -382,7 +382,7 @@ func Test_CoreAPI_BadRequests(t *testing.T) { blockID := tpkg.RandBlockID() resp, err := d.wallet.Clients[nodeAlias].BlockMetadataByBlockID(context.Background(), blockID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusInternalServerError)) + require.True(t, isStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) }, }, @@ -464,7 +464,7 @@ func Test_CoreAPI_BadRequests(t *testing.T) { outputID := tpkg.RandOutputID(0) resp, err := d.wallet.Clients[nodeAlias].OutputByID(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusInternalServerError)) + require.True(t, isStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) }, }, @@ -475,10 +475,22 @@ func Test_CoreAPI_BadRequests(t *testing.T) { resp, err := d.wallet.Clients[nodeAlias].OutputMetadataByID(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusInternalServerError)) + require.True(t, isStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) }, }, + { + name: "Test_OutputWithMetadata_Failure", + testFunc: func(t *testing.T, nodeAlias string) { + outputID := tpkg.RandOutputID(0) + + out, outMetadata, err := d.wallet.Clients[nodeAlias].OutputWithMetadataByID(context.Background(), outputID) + require.Error(t, err) + require.Nil(t, out) + require.Nil(t, outMetadata) + require.True(t, isStatusCode(err, http.StatusNotFound)) + }, + }, { name: "Test_TransactionsIncludedBlock_Failure", testFunc: func(t *testing.T, nodeAlias string) { @@ -528,7 +540,7 @@ func Test_CoreAPI_BadRequests(t *testing.T) { outputID := tpkg.RandOutputID(0) resp, err := d.wallet.Clients[nodeAlias].Rewards(context.Background(), outputID) require.Error(t, err) - require.True(t, isStatusCode(err, http.StatusInternalServerError)) + require.True(t, isStatusCode(err, http.StatusNotFound)) require.Nil(t, resp) }, }, From 6a74c6b2a9cb7d14ed2c3cf7ca687bd130a2ac6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daria=20Dziuba=C5=82towska?= Date: Tue, 12 Mar 2024 18:12:23 +0100 Subject: [PATCH 22/22] Please the linter --- pkg/requesthandler/accounts.go | 1 + pkg/requesthandler/blocks.go | 1 + pkg/requesthandler/utxo.go | 3 +++ 3 files changed, 5 insertions(+) diff --git a/pkg/requesthandler/accounts.go b/pkg/requesthandler/accounts.go index b8b3ea82d..4317ed163 100644 --- a/pkg/requesthandler/accounts.go +++ b/pkg/requesthandler/accounts.go @@ -104,6 +104,7 @@ func (r *RequestHandler) RewardsByOutputID(outputID iotago.OutputID, slot iotago if ierrors.Is(err, kvstore.ErrKeyNotFound) { return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found", outputID.ToHex()) } + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from ledger: %s", outputID.ToHex(), err) } diff --git a/pkg/requesthandler/blocks.go b/pkg/requesthandler/blocks.go index 204f6d3ca..7d42b94e5 100644 --- a/pkg/requesthandler/blocks.go +++ b/pkg/requesthandler/blocks.go @@ -27,6 +27,7 @@ func (r *RequestHandler) BlockMetadataByBlockID(blockID iotago.BlockID) (*api.Bl if ierrors.Is(err, kvstore.ErrKeyNotFound) { return nil, ierrors.Wrapf(echo.ErrNotFound, "block not found: %s", blockID.ToHex()) } + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err) } diff --git a/pkg/requesthandler/utxo.go b/pkg/requesthandler/utxo.go index e82d1cf56..e0b492d58 100644 --- a/pkg/requesthandler/utxo.go +++ b/pkg/requesthandler/utxo.go @@ -16,6 +16,7 @@ func (r *RequestHandler) OutputFromOutputID(outputID iotago.OutputID) (*api.Outp if ierrors.Is(err, kvstore.ErrKeyNotFound) { return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) } + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } @@ -31,6 +32,7 @@ func (r *RequestHandler) OutputMetadataFromOutputID(outputID iotago.OutputID) (* if ierrors.Is(err, kvstore.ErrKeyNotFound) { return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) } + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) } @@ -47,6 +49,7 @@ func (r *RequestHandler) OutputWithMetadataFromOutputID(outputID iotago.OutputID if ierrors.Is(err, kvstore.ErrKeyNotFound) { return nil, ierrors.Wrapf(echo.ErrNotFound, "output %s not found in the Ledger", outputID.ToHex()) } + return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err) }