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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions daemon/algod/api/server/v2/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,12 @@ func convertLogs(txn node.TxnWithStatus) *[][]byte {
func convertInners(txn *node.TxnWithStatus) *[]preEncodedTxInfo {
inner := make([]preEncodedTxInfo, len(txn.ApplyData.EvalDelta.InnerTxns))
for i, itxn := range txn.ApplyData.EvalDelta.InnerTxns {
inner[i] = convertTxn(&itxn)
inner[i] = convertInnerTxn(&itxn)
}
return &inner
}

func convertTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
func convertInnerTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
// This copies from handlers.PendingTransactionInformation, with
// simplifications because we have a SignedTxnWithAD rather than
// TxnWithStatus, and we know this txn has committed.
Expand All @@ -319,8 +319,10 @@ func convertTxn(txn *transactions.SignedTxnWithAD) preEncodedTxInfo {
response.ReceiverRewards = &txn.ApplyData.ReceiverRewards.Raw
response.CloseRewards = &txn.ApplyData.CloseRewards.Raw

response.AssetIndex = (*uint64)(&txn.ApplyData.ConfigAsset)
response.ApplicationIndex = (*uint64)(&txn.ApplyData.ApplicationID)
// Since this is an inner txn, we know these indexes will be populated. No
// need to search payset for IDs
response.AssetIndex = numOrNil(uint64(txn.ApplyData.ConfigAsset))
response.ApplicationIndex = numOrNil(uint64(txn.ApplyData.ApplicationID))

// Deltas, Logs, and Inners can not be set until we allow appl
// response.LocalStateDelta, response.GlobalStateDelta = convertToDeltas(txn)
Expand Down
119 changes: 119 additions & 0 deletions test/e2e-go/restAPI/restClient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package restapi

import (
"context"
"encoding/hex"
"errors"
"flag"
"math"
Expand Down Expand Up @@ -1030,3 +1031,121 @@ return
}

}

func TestPendingTransactionInfoInnerTxnAssetCreate(t *testing.T) {
partitiontest.PartitionTest(t)

a := require.New(fixtures.SynchronizedTest(t))
var localFixture fixtures.RestClientFixture
localFixture.Setup(t, filepath.Join("nettemplates", "TwoNodes50EachFuture.json"))
defer localFixture.Shutdown()

testClient := localFixture.LibGoalClient

testClient.WaitForRound(1)

testClient.SetAPIVersionAffinity(algodclient.APIVersionV2, kmdclient.APIVersionV1)

wh, err := testClient.GetUnencryptedWalletHandle()
a.NoError(err)
addresses, err := testClient.ListAddresses(wh)
a.NoError(err)
_, someAddress := getMaxBalAddr(t, testClient, addresses)
if someAddress == "" {
t.Error("no addr with funds")
}
a.NoError(err)

prog := `#pragma version 5
txn ApplicationID
bz end
itxn_begin
int acfg
itxn_field TypeEnum
int 1000000
itxn_field ConfigAssetTotal
int 3
itxn_field ConfigAssetDecimals
byte "oz"
itxn_field ConfigAssetUnitName
byte "Gold"
itxn_field ConfigAssetName
byte "https://gold.rush/"
itxn_field ConfigAssetURL
byte 0x67f0cd61653bd34316160bc3f5cd3763c85b114d50d38e1f4e72c3b994411e7b
itxn_field ConfigAssetMetadataHash
itxn_submit
end:
int 1
return
`
ops, err := logic.AssembleString(prog)
approv := ops.Program
ops, err = logic.AssembleString("#pragma version 5 \nint 1")
clst := ops.Program

gl := basics.StateSchema{}
lc := basics.StateSchema{}

// create app
appCreateTxn, err := testClient.MakeUnsignedApplicationCallTx(0, nil, nil, nil, nil, transactions.NoOpOC, approv, clst, gl, lc, 0)
a.NoError(err)
appCreateTxn, err = testClient.FillUnsignedTxTemplate(someAddress, 0, 0, 0, appCreateTxn)
a.NoError(err)
appCreateTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCreateTxn)
a.NoError(err)
_, err = waitForTransaction(t, testClient, someAddress, appCreateTxID, 30*time.Second)
a.NoError(err)

// get app ID
submittedAppCreateTxn, err := testClient.PendingTransactionInformationV2(appCreateTxID)
a.NoError(err)
a.NotNil(submittedAppCreateTxn.ApplicationIndex)
createdAppID := basics.AppIndex(*submittedAppCreateTxn.ApplicationIndex)
a.Greater(uint64(createdAppID), uint64(0))

// fund app account
appFundTxn, err := testClient.SendPaymentFromWallet(wh, nil, someAddress, createdAppID.Address().String(), 0, 1_000_000, nil, "", 0, 0)
a.NoError(err)
appFundTxID := appFundTxn.ID()
_, err = waitForTransaction(t, testClient, someAddress, appFundTxID.String(), 30*time.Second)
a.NoError(err)

// call app, which will issue an ASA create inner txn
appCallTxn, err := testClient.MakeUnsignedAppNoOpTx(uint64(createdAppID), nil, nil, nil, nil)
a.NoError(err)
appCallTxn, err = testClient.FillUnsignedTxTemplate(someAddress, 0, 0, 0, appCallTxn)
a.NoError(err)
appCallTxnTxID, err := testClient.SignAndBroadcastTransaction(wh, nil, appCallTxn)
a.NoError(err)
_, err = waitForTransaction(t, testClient, someAddress, appCallTxnTxID, 30*time.Second)
a.NoError(err)

// verify pending txn info of outer txn
submittedAppCallTxn, err := testClient.PendingTransactionInformationV2(appCallTxnTxID)
a.NoError(err)
a.Nil(submittedAppCallTxn.ApplicationIndex)
a.Nil(submittedAppCallTxn.AssetIndex)
a.NotNil(submittedAppCallTxn.InnerTxns)
a.Len(*submittedAppCallTxn.InnerTxns, 1)

// verify pending txn info of inner txn
innerTxn := (*submittedAppCallTxn.InnerTxns)[0]
a.Nil(innerTxn.ApplicationIndex)
a.NotNil(innerTxn.AssetIndex)
createdAssetID := *innerTxn.AssetIndex
a.Greater(createdAssetID, uint64(0))

createdAssetInfo, err := testClient.AssetInformationV2(createdAssetID)
a.NoError(err)
a.Equal(createdAssetID, createdAssetInfo.Index)
a.Equal(createdAppID.Address().String(), createdAssetInfo.Params.Creator)
a.Equal(uint64(1000000), createdAssetInfo.Params.Total)
a.Equal(uint64(3), createdAssetInfo.Params.Decimals)
a.Equal("oz", *createdAssetInfo.Params.UnitName)
a.Equal("Gold", *createdAssetInfo.Params.Name)
a.Equal("https://gold.rush/", *createdAssetInfo.Params.Url)
expectedMetadata, err := hex.DecodeString("67f0cd61653bd34316160bc3f5cd3763c85b114d50d38e1f4e72c3b994411e7b")
a.NoError(err)
a.Equal(expectedMetadata, *createdAssetInfo.Params.MetadataHash)
}