diff --git a/pkg/tests/accounts_test.go b/pkg/tests/accounts_test.go index 588f4cd66..fe4e25f9b 100644 --- a/pkg/tests/accounts_test.go +++ b/pkg/tests/accounts_test.go @@ -3,13 +3,9 @@ package tests import ( "testing" - "github.com/stretchr/testify/require" - - "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/iota-core/pkg/model" "github.com/iotaledger/iota-core/pkg/protocol/engine/accounts" "github.com/iotaledger/iota-core/pkg/protocol/engine/blocks" - "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger" "github.com/iotaledger/iota-core/pkg/testsuite" "github.com/iotaledger/iota-core/pkg/testsuite/mock" "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator" @@ -480,33 +476,34 @@ func Test_NegativeBIC(t *testing.T) { node1 := ts.AddValidatorNode("node1") node2 := ts.AddNode("node2") - validatorBIC := iotago.MaxBlockIssuanceCredits / 2 - // Add a default block issuer to the network. This will add another block issuer account to the snapshot. - walletBIC := iotago.BlockIssuanceCredits(499) - wallet := ts.AddGenesisWallet("default", node2, walletBIC) + wallet1BIC := iotago.BlockIssuanceCredits(100000) + wallet2BIC := iotago.BlockIssuanceCredits(0) + + wallet1 := ts.AddGenesisWallet("wallet 1", node2, wallet1BIC) + wallet2 := ts.AddGenesisWallet("wallet 2", node2, wallet2BIC) ts.Run(false) // check that the accounts added in the genesis snapshot were added to the account manager correctly. - // validator node account. - validatorAccountOutput := ts.AccountOutput("Genesis:1") + + // wallet 1 block issuer account. + wallet1OutputID := ts.AccountOutput("Genesis:2").OutputID() ts.AssertAccountData(&accounts.AccountData{ - ID: node1.Validator.AccountID, - Credits: accounts.NewBlockIssuanceCredits(validatorBIC, 0), - OutputID: validatorAccountOutput.OutputID(), + ID: wallet1.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet1BIC, 0), + OutputID: wallet1OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: node1.Validator.BlockIssuerKeys(), - StakeEndEpoch: iotago.MaxEpochIndex, - ValidatorStake: mock.MinValidatorAccountAmount, + BlockIssuerKeys: wallet1.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) - // default wallet block issuer account. - blockIssuerAccountOutput := ts.AccountOutput("Genesis:2") + + // wallet 2 block issuer account. + wallet2OutputID := ts.AccountOutput("Genesis:3").OutputID() ts.AssertAccountData(&accounts.AccountData{ - ID: wallet.BlockIssuer.AccountID, - Credits: accounts.NewBlockIssuanceCredits(walletBIC, 0), - OutputID: blockIssuerAccountOutput.OutputID(), + ID: wallet2.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet2BIC, 0), + OutputID: wallet2OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(), + BlockIssuerKeys: wallet2.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) // MODIFY EXISTING GENESIS ACCOUNT @@ -516,32 +513,30 @@ func Test_NegativeBIC(t *testing.T) { { block1Commitment := iotago.NewEmptyCommitment(ts.API.ProtocolParameters().Version()) block1Commitment.ReferenceManaCost = ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost - block11 := ts.IssueBasicBlockAtSlotWithOptions("block1.1", block1Slot, ts.Wallet("node1"), &iotago.TaggedData{}, mock.WithSlotCommitment(block1Commitment)) - block12 := ts.IssueBasicBlockAtSlotWithOptions("block1.2", block1Slot, wallet, &iotago.TaggedData{}, mock.WithStrongParents(block11.ID()), mock.WithSlotCommitment(block1Commitment)) + block11 := ts.IssueBasicBlockAtSlotWithOptions("block1.1", block1Slot, wallet1, &iotago.TaggedData{}, mock.WithSlotCommitment(block1Commitment)) + block12 := ts.IssueBasicBlockAtSlotWithOptions("block1.2", block1Slot, wallet2, &iotago.TaggedData{}, mock.WithStrongParents(block11.ID()), mock.WithSlotCommitment(block1Commitment)) // Commit BIC burns and check account states. latestParent = ts.CommitUntilSlot(ts.BlockID("block1.2").Slot(), block12) burned := iotago.BlockIssuanceCredits(block11.WorkScore()) * iotago.BlockIssuanceCredits(ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost) - validatorBIC -= burned - walletBIC -= burned + wallet1BIC -= burned + wallet2BIC -= burned ts.AssertAccountData(&accounts.AccountData{ - ID: node1.Validator.AccountID, - Credits: accounts.NewBlockIssuanceCredits(validatorBIC, block1Slot), - OutputID: validatorAccountOutput.OutputID(), + ID: wallet1.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet1BIC, block1Slot), + OutputID: wallet1OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: node1.Validator.BlockIssuerKeys(), - StakeEndEpoch: iotago.MaxEpochIndex, - ValidatorStake: mock.MinValidatorAccountAmount, + BlockIssuerKeys: wallet1.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) ts.AssertAccountData(&accounts.AccountData{ - ID: wallet.BlockIssuer.AccountID, - Credits: accounts.NewBlockIssuanceCredits(walletBIC, block1Slot), + ID: wallet2.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet2BIC, block1Slot), ExpirySlot: iotago.MaxSlotIndex, - OutputID: blockIssuerAccountOutput.OutputID(), - BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(), + OutputID: wallet2OutputID, + BlockIssuerKeys: wallet2.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) } @@ -551,121 +546,98 @@ func Test_NegativeBIC(t *testing.T) { // the other has the block rejected in the CommitmentFilter as his account has negative BIC value. { - block21 := ts.IssueBasicBlockAtSlotWithOptions("block2.1", block2Slot, ts.Wallet("node1"), &iotago.TaggedData{}) + block21 := ts.IssueBasicBlockAtSlotWithOptions("block2.1", block2Slot, wallet1, &iotago.TaggedData{}) - block22 := ts.IssueBasicBlockAtSlotWithOptions("block2.2", block2Slot, wallet, &iotago.TaggedData{}, mock.WithStrongParents(ts.BlockID("block2.1"))) + block22 := ts.IssueBasicBlockAtSlotWithOptions("block2.2", block2Slot, wallet2, &iotago.TaggedData{}, mock.WithStrongParents(ts.BlockID("block2.1"))) - ts.AssertBlockFiltered([]*blocks.Block{block22}, iotago.ErrNegativeBIC, wallet.Node) + ts.AssertBlockFiltered([]*blocks.Block{block22}, iotago.ErrNegativeBIC, wallet2.Node) latestParent = ts.CommitUntilSlot(ts.BlockID("block2.1").Slot(), block21) burned := iotago.BlockIssuanceCredits(block21.WorkScore()) * iotago.BlockIssuanceCredits(ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost) - validatorBIC -= burned + wallet1BIC -= burned ts.AssertAccountData(&accounts.AccountData{ - ID: node1.Validator.AccountID, - Credits: accounts.NewBlockIssuanceCredits(validatorBIC, block2Slot), - OutputID: validatorAccountOutput.OutputID(), + ID: wallet1.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet1BIC, block2Slot), + OutputID: wallet1OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: node1.Validator.BlockIssuerKeys(), - StakeEndEpoch: iotago.MaxEpochIndex, - ValidatorStake: mock.MinValidatorAccountAmount, - LatestSupportedProtocolVersionAndHash: model.VersionAndHash{ - Version: ts.API.ProtocolParameters().Version(), - Hash: lo.PanicOnErr(ts.API.ProtocolParameters().Hash()), - }, + BlockIssuerKeys: wallet1.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) ts.AssertAccountData(&accounts.AccountData{ - ID: wallet.BlockIssuer.AccountID, - Credits: accounts.NewBlockIssuanceCredits(walletBIC, block1Slot), + ID: wallet2.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet2BIC, block1Slot), ExpirySlot: iotago.MaxSlotIndex, - OutputID: blockIssuerAccountOutput.OutputID(), - BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(), + OutputID: wallet2OutputID, + BlockIssuerKeys: wallet2.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) } block3Slot := latestParent.ID().Slot() // Allot some mana to the locked account to unlock it. + // The locked wallet 2 is preparing and signs the transaction, but it's issued by wallet 1 whose account is not locked. { - allottedBIC := iotago.BlockIssuanceCredits(500) - tx1, err := wallet.CreateSignedTransactionWithOptions( - "TX1", - mock.WithInputs(utxoledger.Outputs{wallet.Output("Genesis:0")}), - mock.WithOutputs(iotago.Outputs[iotago.Output]{wallet.Output("Genesis:0").Output()}), - mock.WithSlotCreated(block3Slot), - mock.WithAllotments(iotago.Allotments{&iotago.Allotment{ - AccountID: wallet.BlockIssuer.AccountID, + allottedBIC := iotago.BlockIssuanceCredits(1000) + tx1 := wallet2.AllotManaFromInputs("TX1", + iotago.Allotments{&iotago.Allotment{ + AccountID: wallet2.BlockIssuer.AccountID, Mana: iotago.Mana(allottedBIC), - }}), - ) - require.NoError(t, err) + }}, "Genesis:0") block3Commitment := node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment() - block31 := ts.IssueBasicBlockAtSlotWithOptions("block3.1", block3Slot, ts.Wallet("node1"), tx1, mock.WithStrongParents(latestParent.ID()), mock.WithSlotCommitment(block3Commitment)) + // Wallet 1 whose account is not locked is issuing the block to unlock the account of wallet 2. + block31 := ts.IssueBasicBlockAtSlotWithOptions("block3.1", block3Slot, wallet1, tx1, mock.WithStrongParents(latestParent.ID()), mock.WithSlotCommitment(block3Commitment)) latestParent = ts.CommitUntilSlot(ts.BlockID("block3.1").Slot(), block31) burned := iotago.BlockIssuanceCredits(block31.WorkScore()) * iotago.BlockIssuanceCredits(ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost) - validatorBIC -= burned - walletBIC += allottedBIC + wallet1BIC -= burned + wallet2BIC += allottedBIC ts.AssertAccountData(&accounts.AccountData{ - ID: node1.Validator.AccountID, - Credits: accounts.NewBlockIssuanceCredits(validatorBIC, block3Slot), - OutputID: validatorAccountOutput.OutputID(), + ID: wallet1.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet1BIC, block3Slot), + OutputID: wallet1OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: node1.Validator.BlockIssuerKeys(), - StakeEndEpoch: iotago.MaxEpochIndex, - ValidatorStake: mock.MinValidatorAccountAmount, - LatestSupportedProtocolVersionAndHash: model.VersionAndHash{ - Version: ts.API.ProtocolParameters().Version(), - Hash: lo.PanicOnErr(ts.API.ProtocolParameters().Hash()), - }, + BlockIssuerKeys: wallet1.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) ts.AssertAccountData(&accounts.AccountData{ - ID: wallet.BlockIssuer.AccountID, - Credits: accounts.NewBlockIssuanceCredits(walletBIC, block3Slot), + ID: wallet2.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet2BIC, block3Slot), ExpirySlot: iotago.MaxSlotIndex, - OutputID: blockIssuerAccountOutput.OutputID(), - BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(), + OutputID: wallet2OutputID, + BlockIssuerKeys: wallet2.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) } block4Slot := latestParent.ID().Slot() - // Issue block from the unlocked account to make sure that it's actually unlocked. + // Issue block from the unlocked account of wallet 2 to make sure that it's actually unlocked. { - - block4 := ts.IssueBasicBlockAtSlotWithOptions("block4", block4Slot, wallet, &iotago.TaggedData{}, mock.WithStrongParents(latestParent.ID())) + block4 := ts.IssueBasicBlockAtSlotWithOptions("block4", block4Slot, wallet2, &iotago.TaggedData{}, mock.WithStrongParents(latestParent.ID())) latestParent = ts.CommitUntilSlot(ts.BlockID("block4").Slot(), block4) burned := iotago.BlockIssuanceCredits(block4.WorkScore()) * iotago.BlockIssuanceCredits(ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost) - walletBIC -= burned + wallet2BIC -= burned ts.AssertAccountData(&accounts.AccountData{ - ID: node1.Validator.AccountID, - Credits: accounts.NewBlockIssuanceCredits(validatorBIC, block3Slot), - OutputID: validatorAccountOutput.OutputID(), + ID: wallet1.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet1BIC, block3Slot), + OutputID: wallet1OutputID, ExpirySlot: iotago.MaxSlotIndex, - BlockIssuerKeys: node1.Validator.BlockIssuerKeys(), - StakeEndEpoch: iotago.MaxEpochIndex, - ValidatorStake: mock.MinValidatorAccountAmount, - LatestSupportedProtocolVersionAndHash: model.VersionAndHash{ - Version: ts.API.ProtocolParameters().Version(), - Hash: lo.PanicOnErr(ts.API.ProtocolParameters().Hash()), - }, + BlockIssuerKeys: wallet1.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) ts.AssertAccountData(&accounts.AccountData{ - ID: wallet.BlockIssuer.AccountID, - Credits: accounts.NewBlockIssuanceCredits(walletBIC, block4Slot), + ID: wallet2.BlockIssuer.AccountID, + Credits: accounts.NewBlockIssuanceCredits(wallet2BIC, block4Slot), ExpirySlot: iotago.MaxSlotIndex, - OutputID: blockIssuerAccountOutput.OutputID(), - BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(), + OutputID: wallet2OutputID, + BlockIssuerKeys: wallet2.BlockIssuer.BlockIssuerKeys(), }, ts.Nodes()...) } } diff --git a/pkg/testsuite/mock/blockissuer.go b/pkg/testsuite/mock/blockissuer.go index 509b152f2..a341a39bc 100644 --- a/pkg/testsuite/mock/blockissuer.go +++ b/pkg/testsuite/mock/blockissuer.go @@ -66,7 +66,7 @@ func NewBlockIssuer(t *testing.T, name string, keyManager *KeyManager, accountID priv, pub := keyManager.KeyPair() if accountID == iotago.EmptyAccountID { - accountID = iotago.AccountID(blake2b.Sum256(pub)) + accountID = blake2b.Sum256(pub) } accountID.RegisterAlias(name) diff --git a/pkg/testsuite/mock/node.go b/pkg/testsuite/mock/node.go index 19afa5299..444f49f63 100644 --- a/pkg/testsuite/mock/node.go +++ b/pkg/testsuite/mock/node.go @@ -150,10 +150,6 @@ func (n *Node) hookEvents() { events.CandidateEngineActivated.Hook(func(e *engine.Engine) { n.candidateEngineActivatedCount.Add(1) }) events.MainEngineSwitched.Hook(func(e *engine.Engine) { n.mainEngineSwitchedCount.Add(1) }) - - events.Engine.CommitmentFilter.BlockFiltered.Hook(func(event *commitmentfilter.BlockFilteredEvent) { - n.filteredBlockEvents = append(n.filteredBlockEvents, event) - }) } func (n *Node) hookLogging(failOnBlockFiltered bool) { @@ -319,6 +315,10 @@ func (n *Node) attachEngineLogsWithName(failOnBlockFiltered bool, instance *engi if failOnBlockFiltered { n.Testing.Fatal("no blocks should be filtered") } + + n.mutex.Lock() + defer n.mutex.Unlock() + n.filteredBlockEvents = append(n.filteredBlockEvents, event) }) events.BlockRequester.Tick.Hook(func(blockID iotago.BlockID) { @@ -512,6 +512,9 @@ func (n *Node) CandidateEngineActivatedCount() int { } func (n *Node) FilteredBlocks() []*commitmentfilter.BlockFilteredEvent { + n.mutex.RLock() + defer n.mutex.RUnlock() + return n.filteredBlockEvents } diff --git a/pkg/testsuite/mock/wallet_transactions.go b/pkg/testsuite/mock/wallet_transactions.go index 50c2cc1f1..76c57472a 100644 --- a/pkg/testsuite/mock/wallet_transactions.go +++ b/pkg/testsuite/mock/wallet_transactions.go @@ -37,7 +37,7 @@ func (w *Wallet) CreateAccountFromInput(transactionName string, inputName string outputStates = append(outputStates, remainderOutput) } - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithContextInputs(iotago.TxEssenceContextInputs{ &iotago.CommitmentInput{ @@ -86,7 +86,7 @@ func (w *Wallet) CreateDelegationFromInput(transactionName string, inputName str } // create the signed transaction - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithContextInputs(iotago.TxEssenceContextInputs{ &iotago.CommitmentInput{ @@ -120,7 +120,7 @@ func (w *Wallet) DelayedClaimingTransition(transactionName string, inputName str delegationOutput := delegationBuilder.MustBuild() - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithContextInputs(iotago.TxEssenceContextInputs{ &iotago.CommitmentInput{ @@ -149,7 +149,7 @@ func (w *Wallet) TransitionAccount(transactionName string, inputName string, opt accountBuilder := builder.NewAccountOutputBuilderFromPrevious(accountOutput) accountOutput = options.Apply(accountBuilder, opts).MustBuild() - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithAccountInput(input), WithContextInputs(iotago.TxEssenceContextInputs{ @@ -182,7 +182,7 @@ func (w *Wallet) DestroyAccount(transactionName string, inputName string, creati Features: iotago.BasicOutputFeatures{}, }} - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithContextInputs(iotago.TxEssenceContextInputs{ &iotago.BlockIssuanceCreditInput{ @@ -222,7 +222,7 @@ func (w *Wallet) CreateImplicitAccountFromInput(transactionName string, inputNam Features: iotago.BasicOutputFeatures{}, } - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithInputs(utxoledger.Outputs{input}), WithOutputs(iotago.Outputs[iotago.Output]{implicitAccountOutput, remainderBasicOutput}), @@ -254,7 +254,7 @@ func (w *Wallet) TransitionImplicitAccountToAccountOutput(transactionName string AccountID(iotago.AccountIDFromOutputID(input.OutputID())), opts).MustBuild() - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithContextInputs(iotago.TxEssenceContextInputs{ &iotago.BlockIssuanceCreditInput{ @@ -312,7 +312,7 @@ func (w *Wallet) CreateBasicOutputsEquallyFromInputs(transactionName string, out }) } - signedTransaction := lo.PanicOnErr(w.CreateSignedTransactionWithOptions( + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( transactionName, WithInputs(inputStates), WithOutputs(outputStates), @@ -321,7 +321,47 @@ func (w *Wallet) CreateBasicOutputsEquallyFromInputs(transactionName string, out return signedTransaction } -func (w *Wallet) CreateSignedTransactionWithOptions(transactionName string, opts ...options.Option[builder.TransactionBuilder]) (*iotago.SignedTransaction, error) { +func (w *Wallet) AllotManaFromInputs(transactionName string, allotments iotago.Allotments, inputNames ...string) *iotago.SignedTransaction { + inputStates := make([]*utxoledger.Output, 0, len(inputNames)) + outputStates := make(iotago.Outputs[iotago.Output], 0, len(inputNames)) + manaToAllot := iotago.Mana(0) + for _, allotment := range allotments { + manaToAllot += allotment.Mana + } + + for _, inputName := range inputNames { + output := w.Output(inputName) + inputStates = append(inputStates, output) + basicOutput, ok := output.Output().(*iotago.BasicOutput) + if !ok { + panic("allotting is only supported from BasicOutputs") + } + + // Subtract stored mana from source outputs to fund Allotment. + outputBuilder := builder.NewBasicOutputBuilderFromPrevious(basicOutput) + if manaToAllot > 0 { + if manaToAllot >= basicOutput.StoredMana() { + outputBuilder.Mana(0) + } else { + outputBuilder.Mana(basicOutput.StoredMana() - manaToAllot) + } + manaToAllot -= basicOutput.StoredMana() + } + + outputStates = append(outputStates, outputBuilder.MustBuild()) + } + + signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions( + transactionName, + WithAllotments(allotments), + WithInputs(inputStates), + WithOutputs(outputStates), + )) + + return signedTransaction +} + +func (w *Wallet) createSignedTransactionWithOptions(transactionName string, opts ...options.Option[builder.TransactionBuilder]) (*iotago.SignedTransaction, error) { currentAPI := w.Node.Protocol.CommittedAPI() txBuilder := builder.NewTransactionBuilder(currentAPI) diff --git a/pkg/testsuite/snapshotcreator/snapshotcreator.go b/pkg/testsuite/snapshotcreator/snapshotcreator.go index c09f9d622..6bbc03318 100644 --- a/pkg/testsuite/snapshotcreator/snapshotcreator.go +++ b/pkg/testsuite/snapshotcreator/snapshotcreator.go @@ -81,9 +81,11 @@ func CreateSnapshot(opts ...options.Option[Options]) error { ed25519PubKey := blockIssuerKeyEd25519.ToEd25519PublicKey() accountID := blake2b.Sum256(ed25519PubKey[:]) committeeAccountsData = append(committeeAccountsData, &accounts.AccountData{ - ID: accountID, - Credits: &accounts.BlockIssuanceCredits{Value: snapshotAccountDetails.BlockIssuanceCredits, UpdateTime: 0}, - ExpirySlot: snapshotAccountDetails.ExpirySlot, + ID: accountID, + Credits: &accounts.BlockIssuanceCredits{Value: snapshotAccountDetails.BlockIssuanceCredits, UpdateTime: 0}, + ExpirySlot: snapshotAccountDetails.ExpirySlot, + // OutputID is not used when selecting an initial committee, + // so it's safe to use an empty one that is different from the actual outputID in the UTXO Ledger. OutputID: iotago.OutputID{}, BlockIssuerKeys: iotago.BlockIssuerKeys{snapshotAccountDetails.IssuerKey}, ValidatorStake: snapshotAccountDetails.StakedAmount, diff --git a/pkg/testsuite/testsuite.go b/pkg/testsuite/testsuite.go index 794702d79..bcf027279 100644 --- a/pkg/testsuite/testsuite.go +++ b/pkg/testsuite/testsuite.go @@ -377,7 +377,8 @@ func (t *TestSuite) RemoveNode(name string) { // AddGenesisWallet adds a wallet to the test suite with a block issuer in the genesis snapshot and access to the genesis seed. // If no block issuance credits are provided, the wallet will be assigned half of the maximum block issuance credits. func (t *TestSuite) AddGenesisWallet(name string, node *mock.Node, blockIssuanceCredits ...iotago.BlockIssuanceCredits) *mock.Wallet { - newWallet := t.addWallet(name, node, iotago.EmptyAccountID, t.genesisKeyManager) + accountID := tpkg.RandAccountID() + newWallet := t.addWallet(name, node, accountID, t.genesisKeyManager) var bic iotago.BlockIssuanceCredits if len(blockIssuanceCredits) == 0 { bic = iotago.MaxBlockIssuanceCredits / 2 @@ -386,6 +387,7 @@ func (t *TestSuite) AddGenesisWallet(name string, node *mock.Node, blockIssuance } accountDetails := snapshotcreator.AccountDetails{ + AccountID: accountID, Address: iotago.Ed25519AddressFromPubKey(newWallet.BlockIssuer.PublicKey), Amount: mock.MinIssuerAccountAmount, Mana: iotago.Mana(mock.MinIssuerAccountAmount), @@ -408,7 +410,7 @@ func (t *TestSuite) addWallet(name string, node *mock.Node, accountID iotago.Acc } func (t *TestSuite) DefaultWallet() *mock.Wallet { - defaultWallet, exists := t.wallets.Get("default") + _, defaultWallet, exists := t.wallets.Head() if !exists { return nil } @@ -463,17 +465,21 @@ func (t *TestSuite) Run(failOnBlockFiltered bool, nodesOptions ...map[string][]o node.Initialize(failOnBlockFiltered, baseOpts...) - if defaultWallet := t.DefaultWallet(); defaultWallet != nil { - if err := node.Protocol.MainEngineInstance().Ledger.ForEachUnspentOutput(func(output *utxoledger.Output) bool { - defaultWallet.AddOutput(fmt.Sprintf("Genesis:%d", output.OutputID().Index()), output) + return true + }) + + if _, firstNode, exists := t.nodes.Head(); exists { + t.wallets.ForEach(func(_ string, wallet *mock.Wallet) bool { + if err := firstNode.Protocol.MainEngineInstance().Ledger.ForEachUnspentOutput(func(output *utxoledger.Output) bool { + wallet.AddOutput(fmt.Sprintf("Genesis:%d", output.OutputID().Index()), output) return true }); err != nil { panic(err) } - } - return true - }) + return true + }) + } t.running = true }