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

Commit 95e9802

Browse files
committed
Implement Test_AccountTransitions
1 parent a99d53d commit 95e9802

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package tests
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
iotago "github.com/iotaledger/iota.go/v4"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func Test_AccountTransitions(t *testing.T) {
13+
d := NewDockerTestFramework(t,
14+
WithProtocolParametersOptions(
15+
iotago.WithTimeProviderOptions(5, time.Now().Unix(), 10, 4),
16+
iotago.WithLivenessOptions(10, 10, 2, 4, 8),
17+
iotago.WithRewardsOptions(8, 8, 10, 2, 1, 384),
18+
iotago.WithTargetCommitteeSize(4),
19+
))
20+
defer d.Stop()
21+
22+
d.AddValidatorNode("V1", "docker-network-inx-validator-1-1", "http://localhost:8050", "rms1pzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3y5rx2w6")
23+
d.AddValidatorNode("V2", "docker-network-inx-validator-2-1", "http://localhost:8060", "rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl")
24+
d.AddValidatorNode("V3", "docker-network-inx-validator-3-1", "http://localhost:8070", "rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt")
25+
d.AddValidatorNode("V4", "docker-network-inx-validator-4-1", "http://localhost:8040", "rms1pr8cxs3dzu9xh4cduff4dd4cxdthpjkpwmz2244f75m0urslrsvtsshrrjw")
26+
d.AddNode("node5", "docker-network-node-5-1", "http://localhost:8090")
27+
28+
err := d.Run()
29+
require.NoError(t, err)
30+
31+
err = d.WaitUntilSync()
32+
require.NoError(t, err)
33+
34+
// create account1
35+
account1 := d.CreateAccount()
36+
// create account2
37+
account2 := d.CreateAccount()
38+
39+
// request faucet funds
40+
fundsAddr, _ := d.getAddress(iotago.AddressEd25519)
41+
d.RequestFaucetFunds(context.TODO(), fundsAddr)
42+
43+
// allot 1000 mana from account1 to account2
44+
d.AllotManaTo(account1, account2, 1000)
45+
46+
// create native token
47+
account2 = d.CreateNativeToken(account2)
48+
}

tools/docker-network/tests/dockerframework.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"crypto/ed25519"
88
"fmt"
99
"log"
10+
"math/big"
1011
"os/exec"
1112
"sort"
1213
"strings"
@@ -61,6 +62,8 @@ type Account struct {
6162
AccountID iotago.AccountID
6263
AccountAddress *iotago.AccountAddress
6364
BlockIssuerKey ed25519.PrivateKey
65+
AccountOutput *iotago.AccountOutput
66+
OutputID iotago.OutputID
6467
}
6568

6669
type DockerTestFramework struct {
@@ -375,6 +378,8 @@ func (d *DockerTestFramework) CreateAccount(opts ...options.Option[builder.Accou
375378
AccountID: accountID,
376379
AccountAddress: accountAddress,
377380
BlockIssuerKey: accPrivateKey,
381+
AccountOutput: accountOutput,
382+
OutputID: accOutputID,
378383
}
379384
}
380385

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

433+
// AllotManaTo allots amount of mana from one account to another.
434+
func (d *DockerTestFramework) AllotManaTo(from *Account, to *Account, manaToAllot iotago.Mana) {
435+
// requesting faucet funds for allotment
436+
ctx := context.TODO()
437+
fundsAddr, privateKey := d.getAddress(iotago.AddressEd25519)
438+
fundsOutputID, fundsUTXOOutput := d.RequestFaucetFunds(ctx, fundsAddr)
439+
fundsAddrSigner := iotago.NewInMemoryAddressSigner(iotago.NewAddressKeysForEd25519Address(fundsAddr.(*iotago.Ed25519Address), privateKey))
440+
441+
clt := d.Node("V1").Client
442+
currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now())
443+
apiForSlot := clt.APIForSlot(currentSlot)
444+
445+
basicOutput, ok := fundsUTXOOutput.(*iotago.BasicOutput)
446+
require.True(d.Testing, ok)
447+
448+
// Subtract stored mana from source outputs to fund Allotment.
449+
outputBuilder := builder.NewBasicOutputBuilderFromPrevious(basicOutput)
450+
actualAllottedMana := manaToAllot
451+
if manaToAllot >= basicOutput.StoredMana() {
452+
actualAllottedMana = basicOutput.StoredMana()
453+
outputBuilder.Mana(0)
454+
} else {
455+
outputBuilder.Mana(basicOutput.StoredMana() - manaToAllot)
456+
}
457+
458+
issuerResp, err := clt.BlockIssuance(ctx)
459+
require.NoError(d.Testing, err)
460+
461+
congestionResp, err := clt.Congestion(ctx, from.AccountAddress, lo.PanicOnErr(issuerResp.LatestCommitment.ID()))
462+
require.NoError(d.Testing, err)
463+
464+
signedTx, err := builder.NewTransactionBuilder(apiForSlot).
465+
AddInput(&builder.TxInput{
466+
UnlockTarget: fundsAddr,
467+
InputID: fundsOutputID,
468+
Input: fundsUTXOOutput,
469+
}).
470+
IncreaseAllotment(to.AccountID, actualAllottedMana).
471+
AddOutput(basicOutput).
472+
SetCreationSlot(currentSlot).
473+
AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}).
474+
WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything())).
475+
Build(fundsAddrSigner)
476+
require.NoError(d.Testing, err)
477+
478+
blkID := d.SubmitPayload(ctx, signedTx, wallet.NewEd25519Account(from.AccountID, from.BlockIssuerKey), congestionResp, issuerResp)
479+
480+
d.AwaitTransactionPayloadAccepted(ctx, blkID)
481+
}
482+
483+
func (d *DockerTestFramework) CreateNativeToken(from *Account) (updatedAccount *Account) {
484+
// requesting faucet funds for native token creation
485+
ctx := context.TODO()
486+
fundsAddr, privateKey := d.getAddress(iotago.AddressEd25519)
487+
fundsOutputID, fundsUTXOOutput := d.RequestFaucetFunds(ctx, fundsAddr)
488+
489+
mintedAmount := fundsUTXOOutput.BaseTokenAmount()
490+
491+
clt := d.Node("V1").Client
492+
currentSlot := clt.LatestAPI().TimeProvider().SlotFromTime(time.Now())
493+
apiForSlot := clt.APIForSlot(currentSlot)
494+
495+
// increase foundry counter
496+
accTransitionOutput := builder.NewAccountOutputBuilderFromPrevious(from.AccountOutput).
497+
FoundriesToGenerate(1).MustBuild()
498+
499+
// build foundry output, consume all amount from the UTXO output
500+
foundryID, _ := iotago.FoundryIDFromAddressAndSerialNumberAndTokenScheme(from.AccountAddress, accTransitionOutput.FoundryCounter, iotago.TokenSchemeSimple)
501+
tokenScheme := &iotago.SimpleTokenScheme{
502+
MintedTokens: big.NewInt(int64(mintedAmount)),
503+
MaximumSupply: big.NewInt(int64(mintedAmount)),
504+
MeltedTokens: big.NewInt(0),
505+
}
506+
507+
foundryOutput := builder.NewFoundryOutputBuilder(from.AccountAddress, tokenScheme, mintedAmount).
508+
NativeToken(&iotago.NativeTokenFeature{
509+
ID: foundryID,
510+
Amount: big.NewInt(int64(mintedAmount)),
511+
}).
512+
SerialNumber(accTransitionOutput.FoundryCounter).MustBuild()
513+
514+
// prepare transaction
515+
issuerResp, err := clt.BlockIssuance(ctx)
516+
require.NoError(d.Testing, err)
517+
518+
congestionResp, err := clt.Congestion(ctx, from.AccountAddress, lo.PanicOnErr(issuerResp.LatestCommitment.ID()))
519+
require.NoError(d.Testing, err)
520+
521+
signer := iotago.NewInMemoryAddressSigner(iotago.NewAddressKeysForEd25519Address(fundsAddr.(*iotago.Ed25519Address), privateKey),
522+
iotago.NewAddressKeysForEd25519Address(from.AccountOutput.UnlockConditionSet().Address().Address.(*iotago.Ed25519Address), from.BlockIssuerKey))
523+
524+
signedTx, err := builder.NewTransactionBuilder(apiForSlot).
525+
AddInput(&builder.TxInput{
526+
UnlockTarget: fundsAddr,
527+
InputID: fundsOutputID,
528+
Input: fundsUTXOOutput,
529+
}).
530+
AddInput(&builder.TxInput{
531+
UnlockTarget: from.AccountOutput.UnlockConditionSet().Address().Address,
532+
InputID: from.OutputID,
533+
Input: from.AccountOutput,
534+
}).
535+
AddOutput(accTransitionOutput).
536+
AddOutput(foundryOutput).
537+
SetCreationSlot(currentSlot).
538+
AddBlockIssuanceCreditInput(&iotago.BlockIssuanceCreditInput{AccountID: from.AccountID}).
539+
AddCommitmentInput(&iotago.CommitmentInput{CommitmentID: lo.Return1(issuerResp.LatestCommitment.ID())}).
540+
WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything())).
541+
AllotAllMana(currentSlot, from.AccountID).
542+
Build(signer)
543+
require.NoError(d.Testing, err)
544+
545+
blkID := d.SubmitPayload(ctx, signedTx, wallet.NewEd25519Account(from.AccountID, from.BlockIssuerKey), congestionResp, issuerResp)
546+
547+
updatedAccount = &Account{
548+
AccountID: from.AccountID,
549+
AccountAddress: from.AccountAddress,
550+
BlockIssuerKey: from.BlockIssuerKey,
551+
AccountOutput: accTransitionOutput,
552+
OutputID: iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(signedTx.Transaction.ID()), 0),
553+
}
554+
555+
d.AwaitTransactionPayloadAccepted(ctx, blkID)
556+
d.AssertIndexerAccount(updatedAccount)
557+
d.AssertIndexerFoundry(foundryID)
558+
559+
return updatedAccount
560+
}
561+
428562
func (d *DockerTestFramework) CheckAccountStatus(ctx context.Context, blkID iotago.BlockID, txID iotago.TransactionID, creationOutputID iotago.OutputID, accountAddress *iotago.AccountAddress, checkIndexer ...bool) {
429563
// request by blockID if provided, otherwise use txID
430564
// we take the slot from the blockID in case the tx is created earlier than the block.
@@ -469,6 +603,43 @@ func (d *DockerTestFramework) RequestFaucetFunds(ctx context.Context, receiveAdd
469603
return outputID, output
470604
}
471605

606+
func (d *DockerTestFramework) AssertIndexerAccount(account *Account) {
607+
d.Eventually(func() error {
608+
ctx := context.TODO()
609+
indexerClt, err := d.Node("V1").Client.Indexer(ctx)
610+
if err != nil {
611+
return err
612+
}
613+
614+
outputID, output, _, err := indexerClt.Account(ctx, account.AccountAddress)
615+
if err != nil {
616+
return err
617+
}
618+
619+
require.EqualValues(d.Testing, account.OutputID, outputID)
620+
require.EqualValues(d.Testing, account.AccountOutput, output)
621+
622+
return nil
623+
})
624+
}
625+
626+
func (d *DockerTestFramework) AssertIndexerFoundry(foundryID iotago.FoundryID) {
627+
d.Eventually(func() error {
628+
ctx := context.TODO()
629+
indexerClt, err := d.Node("V1").Client.Indexer(ctx)
630+
if err != nil {
631+
return err
632+
}
633+
634+
_, _, _, err = indexerClt.Foundry(ctx, foundryID)
635+
if err != nil {
636+
return err
637+
}
638+
639+
return nil
640+
})
641+
}
642+
472643
func (d *DockerTestFramework) AssertValidatorExists(accountAddr *iotago.AccountAddress) {
473644
d.Eventually(func() error {
474645
for _, node := range d.nodes {

0 commit comments

Comments
 (0)