Skip to content
This repository has been archived by the owner on Jan 24, 2025. It is now read-only.

Commit

Permalink
Implement Test_AccountTransitions
Browse files Browse the repository at this point in the history
  • Loading branch information
jkrvivian committed Jan 18, 2024
1 parent a99d53d commit 4bae5f2
Show file tree
Hide file tree
Showing 2 changed files with 219 additions and 0 deletions.
48 changes: 48 additions & 0 deletions tools/docker-network/tests/accounttransition_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package tests

import (
"context"
"testing"
"time"

iotago "github.com/iotaledger/iota.go/v4"
"github.com/stretchr/testify/require"
)

func Test_AccountTransitions(t *testing.T) {
d := NewDockerTestFramework(t,

Check failure on line 13 in tools/docker-network/tests/accounttransition_test.go

View workflow job for this annotation

GitHub Actions / Unit tests

undefined: NewDockerTestFramework

Check failure on line 13 in tools/docker-network/tests/accounttransition_test.go

View workflow job for this annotation

GitHub Actions / Unit tests -race

undefined: NewDockerTestFramework
WithProtocolParametersOptions(

Check failure on line 14 in tools/docker-network/tests/accounttransition_test.go

View workflow job for this annotation

GitHub Actions / Unit tests

undefined: WithProtocolParametersOptions

Check failure on line 14 in tools/docker-network/tests/accounttransition_test.go

View workflow job for this annotation

GitHub Actions / Unit tests -race

undefined: WithProtocolParametersOptions
iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4),
iotago.WithLivenessOptions(10, 10, 2, 4, 8),
iotago.WithRewardsOptions(8, 8, 10, 2, 1, 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")

err := d.Run()
require.NoError(t, err)

err = d.WaitUntilSync()
require.NoError(t, err)

// create account1
account1 := d.CreateAccount()
// create account2
account2 := d.CreateAccount()

// request faucet funds
fundsAddr, _ := d.getAddress(iotago.AddressEd25519)
d.RequestFaucetFunds(context.TODO(), fundsAddr)

// allot 1000 mana from account1 to account2
d.AllotManaTo(account1, account2, 1000)

// create native token
account2 = d.CreateNativeToken(account2)
}
171 changes: 171 additions & 0 deletions tools/docker-network/tests/dockerframework.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/ed25519"
"fmt"
"log"
"math/big"
"os/exec"
"sort"
"strings"
Expand Down Expand Up @@ -61,6 +62,8 @@ type Account struct {
AccountID iotago.AccountID
AccountAddress *iotago.AccountAddress
BlockIssuerKey ed25519.PrivateKey
AccountOutput *iotago.AccountOutput
OutputID iotago.OutputID
}

type DockerTestFramework struct {
Expand Down Expand Up @@ -375,6 +378,8 @@ func (d *DockerTestFramework) CreateAccount(opts ...options.Option[builder.Accou
AccountID: accountID,
AccountAddress: accountAddress,
BlockIssuerKey: accPrivateKey,
AccountOutput: accountOutput,
OutputID: accOutputID,
}
}

Expand Down Expand Up @@ -425,6 +430,135 @@ func (d *DockerTestFramework) DelegateToValidator(from *Account, validator *Node
return delegationOutput.StartEpoch
}

// AllotManaTo allots amount of mana from one account to another.
func (d *DockerTestFramework) AllotManaTo(from *Account, to *Account, manaToAllot iotago.Mana) {
// requesting faucet funds for allotment
ctx := context.TODO()
fundsAddr, privateKey := d.getAddress(iotago.AddressEd25519)
fundsOutputID, fundsUTXOOutput := d.RequestFaucetFunds(ctx, fundsAddr)
fundsAddrSigner := iotago.NewInMemoryAddressSigner(iotago.NewAddressKeysForEd25519Address(fundsAddr.(*iotago.Ed25519Address), privateKey))

clt := d.Node("V1").Client
currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now())
apiForSlot := clt.APIForSlot(currentSlot)

basicOutput, ok := fundsUTXOOutput.(*iotago.BasicOutput)
require.True(d.Testing, ok)

// Subtract stored mana from source outputs to fund Allotment.
outputBuilder := builder.NewBasicOutputBuilderFromPrevious(basicOutput)
actualAllottedMana := manaToAllot
if manaToAllot >= basicOutput.StoredMana() {
actualAllottedMana = basicOutput.StoredMana()
outputBuilder.Mana(0)
} else {
outputBuilder.Mana(basicOutput.StoredMana() - manaToAllot)
}

issuerResp, err := clt.BlockIssuance(ctx)
require.NoError(d.Testing, err)

congestionResp, err := clt.Congestion(ctx, from.AccountAddress, lo.PanicOnErr(issuerResp.LatestCommitment.ID()))
require.NoError(d.Testing, err)

signedTx, err := builder.NewTransactionBuilder(apiForSlot).
AddInput(&builder.TxInput{
UnlockTarget: fundsAddr,
InputID: fundsOutputID,
Input: fundsUTXOOutput,
}).
IncreaseAllotment(to.AccountID, actualAllottedMana).
AddOutput(basicOutput).
SetCreationSlot(currentSlot).
AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}).
WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything())).
Build(fundsAddrSigner)
require.NoError(d.Testing, err)

blkID := d.SubmitPayload(ctx, signedTx, wallet.NewEd25519Account(from.AccountID, from.BlockIssuerKey), congestionResp, issuerResp)

d.AwaitTransactionPayloadAccepted(ctx, blkID)
}

func (d *DockerTestFramework) CreateNativeToken(from *Account) (updatedAccount *Account) {
// requesting faucet funds for native token creation
ctx := context.TODO()
fundsAddr, privateKey := d.getAddress(iotago.AddressEd25519)
fundsOutputID, fundsUTXOOutput := d.RequestFaucetFunds(ctx, fundsAddr)

mintedAmount := fundsUTXOOutput.BaseTokenAmount()

clt := d.Node("V1").Client
currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now())
apiForSlot := clt.APIForSlot(currentSlot)

// increase foundry counter
accTransitionOutput := builder.NewAccountOutputBuilderFromPrevious(from.AccountOutput).
FoundriesToGenerate(1).MustBuild()

// build foundry output, consume all amount from the UTXO output
foundryID, _ := iotago.FoundryIDFromAddressAndSerialNumberAndTokenScheme(from.AccountAddress, accTransitionOutput.FoundryCounter, iotago.TokenSchemeSimple)
tokenScheme := &iotago.SimpleTokenScheme{
MintedTokens: big.NewInt(int64(mintedAmount)),
MaximumSupply: big.NewInt(int64(mintedAmount)),
MeltedTokens: big.NewInt(0),
}

foundryOutput := builder.NewFoundryOutputBuilder(from.AccountAddress, tokenScheme, mintedAmount).
NativeToken(&iotago.NativeTokenFeature{
ID: foundryID,
Amount: big.NewInt(int64(mintedAmount)),
}).
SerialNumber(accTransitionOutput.FoundryCounter).MustBuild()

// prepare transaction
issuerResp, err := clt.BlockIssuance(ctx)
require.NoError(d.Testing, err)

congestionResp, err := clt.Congestion(ctx, from.AccountAddress, lo.PanicOnErr(issuerResp.LatestCommitment.ID()))
require.NoError(d.Testing, err)

signer := iotago.NewInMemoryAddressSigner(iotago.NewAddressKeysForEd25519Address(fundsAddr.(*iotago.Ed25519Address), privateKey),
iotago.NewAddressKeysForEd25519Address(from.AccountOutput.UnlockConditionSet().Address().Address.(*iotago.Ed25519Address), from.BlockIssuerKey))

signedTx, err := builder.NewTransactionBuilder(apiForSlot).
AddInput(&builder.TxInput{
UnlockTarget: fundsAddr,
InputID: fundsOutputID,
Input: fundsUTXOOutput,
}).
AddInput(&builder.TxInput{
UnlockTarget: from.AccountOutput.UnlockConditionSet().Address().Address,
InputID: from.OutputID,
Input: from.AccountOutput,
}).
AddOutput(accTransitionOutput).
AddOutput(foundryOutput).
SetCreationSlot(currentSlot).
AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: from.AccountID}).
AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}).
WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything())).
AllotAllMana(currentSlot, from.AccountID).
Build(signer)
require.NoError(d.Testing, err)

blkID := d.SubmitPayload(ctx, signedTx, wallet.NewEd25519Account(from.AccountID, from.BlockIssuerKey), congestionResp, issuerResp)

updatedAccount = &Account{
AccountID: from.AccountID,
AccountAddress: from.AccountAddress,
BlockIssuerKey: from.BlockIssuerKey,
AccountOutput: accTransitionOutput,
OutputID: iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0),
}

d.AwaitTransactionPayloadAccepted(ctx, blkID)
d.AssertIndexerAccountExists(updatedAccount)
d.AssertIndexerFoundryExists(foundryID)

return updatedAccount
}

func (d *DockerTestFramework) CheckAccountStatus(ctx context.Context, blkID iotago.BlockID, txID iotago.TransactionID, creationOutputID iotago.OutputID, accountAddress *iotago.AccountAddress, checkIndexer ...bool) {
// request by blockID if provided, otherwise use txID
// we take the slot from the blockID in case the tx is created earlier than the block.
Expand Down Expand Up @@ -469,6 +603,43 @@ func (d *DockerTestFramework) RequestFaucetFunds(ctx context.Context, receiveAdd
return outputID, output
}

func (d *DockerTestFramework) AssertIndexerAccountExists(account *Account) {
d.Eventually(func() error {
ctx := context.TODO()
indexerClt, err := d.Node("V1").Client.Indexer(ctx)
if err != nil {
return err
}

outputID, output, _, err := indexerClt.Account(ctx, account.AccountAddress)
if err != nil {
return err
}

require.EqualValues(d.Testing, account.OutputID, outputID)
require.EqualValues(d.Testing, account.AccountOutput, output)

return nil
})
}

func (d *DockerTestFramework) AssertIndexerFoundryExists(foundryID iotago.FoundryID) {
d.Eventually(func() error {
ctx := context.TODO()
indexerClt, err := d.Node("V1").Client.Indexer(ctx)
if err != nil {
return err
}

_, _, _, err = indexerClt.Foundry(ctx, foundryID)
if err != nil {
return err
}

return nil
})
}

func (d *DockerTestFramework) AssertValidatorExists(accountAddr *iotago.AccountAddress) {
d.Eventually(func() error {
for _, node := range d.nodes {
Expand Down

0 comments on commit 4bae5f2

Please sign in to comment.