Skip to content

Commit

Permalink
Merge pull request #2892 from jorgemmsilva/impr/misc
Browse files Browse the repository at this point in the history
test: add NFT deposit estimation cluster test
  • Loading branch information
jorgemmsilva authored Sep 27, 2023
2 parents 8059402 + 28ff044 commit c362291
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/chainutil/runvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func runISCTask(
TimeAssumption: blockTime,
Entropy: hashing.PseudoRandomHash(nil),
ValidatorFeeTarget: accounts.CommonAccount(),
EnableGasBurnLogging: false,
EnableGasBurnLogging: estimateGasMode,
EstimateGasMode: estimateGasMode,
EVMTracer: evmTracer,
Log: ch.Log().Desugar().WithOptions(zap.AddCallerSkip(1)).Sugar(),
Expand Down
36 changes: 36 additions & 0 deletions tools/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,3 +872,39 @@ func (clu *Cluster) AssertAddressBalances(addr iotago.Address, expected *isc.Ass
func (clu *Cluster) GetOutputs(addr iotago.Address) (map[iotago.OutputID]iotago.Output, error) {
return clu.l1.OutputMap(addr)
}

func (clu *Cluster) MintL1NFT(immutableMetadata []byte, target iotago.Address, issuerKeypair *cryptolib.KeyPair) (iotago.OutputID, *iotago.NFTOutput, error) {
outputsSet, err := clu.l1.OutputMap(issuerKeypair.Address())
if err != nil {
return iotago.OutputID{}, nil, err
}
tx, err := transaction.NewMintNFTsTransaction(transaction.MintNFTsTransactionParams{
IssuerKeyPair: issuerKeypair,
CollectionOutputID: nil,
Target: target,
ImmutableMetadata: [][]byte{immutableMetadata},
UnspentOutputs: outputsSet,
UnspentOutputIDs: isc.OutputSetToOutputIDs(outputsSet),
})
if err != nil {
return iotago.OutputID{}, nil, err
}
_, err = clu.l1.PostTxAndWaitUntilConfirmation(tx)
if err != nil {
return iotago.OutputID{}, nil, err
}

// go through the tx and find the newly minted NFT
outputSet, err := tx.OutputsSet()
if err != nil {
return iotago.OutputID{}, nil, err
}

for oID, o := range outputSet {
if oNFT, ok := o.(*iotago.NFTOutput); ok && oNFT.NFTID.Empty() {
return oID, oNFT, nil
}
}

return iotago.OutputID{}, nil, fmt.Errorf("inconsistency: couldn't find newly minted NFT in tx")
}
1 change: 1 addition & 0 deletions tools/cluster/tests/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestClusterMultiNodeCommittee(t *testing.T) {
t.Run("inccounter timelock", func(t *testing.T) { run(t, testIncCounterTimelock) })

t.Run("webapi ISC estimategas onledger", func(t *testing.T) { run(t, testEstimateGasOnLedger) })
t.Run("webapi ISC estimategas onledger NFT", func(t *testing.T) { run(t, testEstimateGasOnLedgerNFT) })
t.Run("webapi ISC estimategas offledger", func(t *testing.T) { run(t, testEstimateGasOffLedger) })
}

Expand Down
88 changes: 87 additions & 1 deletion tools/cluster/tests/estimategas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package tests

import (
"context"
"strconv"
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/serializer/v2"
Expand Down Expand Up @@ -53,14 +55,20 @@ func testEstimateGasOnLedger(t *testing.T, env *ChainEnv) {
keyPair, _, err := env.Clu.NewKeyPairWithFunds()
require.NoError(t, err)

feeCharged, err := strconv.ParseUint(estimatedReceipt.GasFeeCharged, 10, 64)
require.NoError(t, err)

accountsClient := env.Chain.SCClient(accounts.Contract.Hname(), keyPair)
par := chainclient.PostRequestParams{
Transfer: isc.NewAssetsBaseTokens(feeCharged),
Args: map[kv.Key][]byte{
accounts.ParamAgentID: isc.NewAgentID(&iotago.Ed25519Address{}).Bytes(),
},
Allowance: isc.NewAssetsBaseTokens(5000),
}
par.WithGasBudget(1 * isc.Million)
gasBudget, err := strconv.ParseUint(estimatedReceipt.GasBurned, 10, 64)
require.NoError(t, err)
par.WithGasBudget(gasBudget)

tx, err := accountsClient.PostRequest(accounts.FuncTransferAllowanceTo.Name,
par,
Expand All @@ -72,6 +80,84 @@ func testEstimateGasOnLedger(t *testing.T, env *ChainEnv) {
require.Equal(t, recs[0].GasFeeCharged, estimatedReceipt.GasFeeCharged)
}

func testEstimateGasOnLedgerNFT(t *testing.T, env *ChainEnv) {
// estimate on-ledger request, using and NFT with minSD
keyPair, addr, err := env.Clu.NewKeyPairWithFunds()
require.NoError(t, err)

metadata, err := iotago.DecodeHex("0x7b227374616e64617264223a224952433237222c2276657273696f6e223a2276312e30222c226e616d65223a2254657374416761696e4e667432222c2274797065223a22696d6167652f6a706567222c22757269223a2268747470733a2f2f696d616765732e756e73706c6173682e636f6d2f70686f746f2d313639353539373737383238392d6663316635633731353935383f69786c69623d72622d342e302e3326697869643d4d3377784d6a4133664442384d48787761473930627931775957646c664878386647567566444238664878386641253344253344266175746f3d666f726d6174266669743d63726f7026773d3335343226713d3830227d")
require.NoError(t, err)

nftID, _, err := env.Clu.MintL1NFT(metadata, addr, keyPair)
require.NoError(t, err)
nft := &isc.NFT{
ID: iotago.NFTIDFromOutputID(nftID),
Issuer: addr,
Metadata: metadata,
}

targetAgentID := isc.NewEthereumAddressAgentID(env.Chain.ChainID, common.Address{})

output := transaction.NFTOutputFromPostData(
tpkg.RandEd25519Address(),
isc.EmptyContractIdentity(),
isc.RequestParameters{
Assets: isc.NewEmptyAssets(),
AdjustToMinimumStorageDeposit: true,
TargetAddress: env.Chain.ChainAddress(),
Metadata: &isc.SendMetadata{
TargetContract: accounts.Contract.Hname(),
EntryPoint: accounts.FuncTransferAllowanceTo.Hname(),
Params: map[kv.Key][]byte{
accounts.ParamAgentID: targetAgentID.Bytes(),
},
Allowance: isc.NewEmptyAssets().AddNFTs(nft.ID),
GasBudget: 1 * isc.Million,
},
Options: isc.SendOptions{
Expiration: &isc.Expiration{
Time: time.Now().Add(100 * time.Hour),
ReturnAddress: addr,
},
},
},
nft,
)

outputBytes, err := output.Serialize(serializer.DeSeriModePerformLexicalOrdering, nil)
require.NoError(t, err)

estimatedReceipt, _, err := env.Chain.Cluster.WaspClient(0).ChainsApi.EstimateGasOnledger(context.Background(),
env.Chain.ChainID.String(),
).Request(apiclient.EstimateGasRequestOnledger{
OutputBytes: iotago.EncodeHex(outputBytes),
}).Execute()
require.NoError(t, err)
require.Empty(t, estimatedReceipt.ErrorMessage)

accountsClient := env.Chain.SCClient(accounts.Contract.Hname(), keyPair)
par := chainclient.PostRequestParams{
Transfer: isc.NewAssetsBaseTokens(output.Deposit()),
Args: map[kv.Key][]byte{
accounts.ParamAgentID: targetAgentID.Bytes(),
},
Allowance: isc.NewEmptyAssets().AddNFTs(nft.ID),
NFT: nft,
AutoAdjustStorageDeposit: false,
}
gasBudget, err := strconv.ParseUint(estimatedReceipt.GasBurned, 10, 64)
require.NoError(t, err)
par.WithGasBudget(gasBudget)

tx, err := accountsClient.PostRequest(accounts.FuncTransferAllowanceTo.Name, par)
require.NoError(t, err)
recs, err := env.Clu.MultiClient().WaitUntilAllRequestsProcessedSuccessfully(env.Chain.ChainID, tx, false, 10*time.Second)
require.NoError(t, err)
require.Equal(t, recs[0].GasBurned, estimatedReceipt.GasBurned)
require.Equal(t, recs[0].GasFeeCharged, estimatedReceipt.GasFeeCharged)
require.Len(t, env.getAccountNFTs(targetAgentID), 1)
}

func testEstimateGasOffLedger(t *testing.T, env *ChainEnv) {
// estimate off-ledger request, then send the same request, assert the gas used/fees match
keyPair, _, err := env.Clu.NewKeyPairWithFunds()
Expand Down
22 changes: 20 additions & 2 deletions tools/cluster/tests/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/stretchr/testify/require"

iotago "github.com/iotaledger/iota.go/v3"
"github.com/iotaledger/wasp/clients/apiclient"
"github.com/iotaledger/wasp/clients/apiextensions"
"github.com/iotaledger/wasp/contracts/native/inccounter"
Expand Down Expand Up @@ -126,11 +127,28 @@ func (e *ChainEnv) getBalancesOnChain() map[string]*isc.Assets {
assets, err := apiextensions.AssetsFromAPIResponse(balance)
require.NoError(e.t, err)

ret[string(agentID.Bytes())] = assets
ret[agentID.String()] = assets
}
return ret
}

func (e *ChainEnv) getAccountNFTs(agentID isc.AgentID) []iotago.NFTID {
nftsResp, _, err := e.Chain.Cluster.WaspClient().CorecontractsApi.
AccountsGetAccountNFTIDs(context.Background(), e.Chain.ChainID.String(), agentID.String()).
Execute()
require.NoError(e.t, err)

ret := make([]iotago.NFTID, len(nftsResp.NftIds))
for i, nftIDStr := range nftsResp.NftIds {
nftIDBytes, err := iotago.DecodeHex(nftIDStr)
require.NoError(e.t, err)
ret[i] = iotago.NFTID{}
copy(ret[i][:], nftIDBytes)
}

return ret
}

func (e *ChainEnv) getTotalBalance() *isc.Assets {
totalAssets, _, err := e.Chain.Cluster.WaspClient().CorecontractsApi.
AccountsGetTotalAssets(context.Background(), e.Chain.ChainID.String()).
Expand All @@ -147,7 +165,7 @@ func (e *ChainEnv) printAccounts(title string) {
allBalances := e.getBalancesOnChain()
s := fmt.Sprintf("------------------------------------- %s\n", title)
for k, bals := range allBalances {
aid, err := isc.AgentIDFromBytes([]byte(k))
aid, err := isc.AgentIDFromString(k)
require.NoError(e.t, err)
s += fmt.Sprintf(" %s\n", aid.String())
s += fmt.Sprintf("%s\n", bals.String())
Expand Down

0 comments on commit c362291

Please sign in to comment.