@@ -7,38 +7,85 @@ import (
7
7
"github.com/iotaledger/iota-core/pkg/model"
8
8
"github.com/iotaledger/iota-core/pkg/protocol/engine/accounts"
9
9
"github.com/iotaledger/iota-core/pkg/testsuite"
10
- "github.com/iotaledger/iota-core/pkg/testsuite/depositcalculator"
11
10
"github.com/iotaledger/iota-core/pkg/testsuite/mock"
12
11
iotago "github.com/iotaledger/iota.go/v4"
13
12
"github.com/iotaledger/iota.go/v4/tpkg"
14
- "github.com/stretchr/testify/require"
15
13
)
16
14
15
+ // Test_AccountStateTransition follows the account state transition flow described in:
16
+ // https://github.com/iotaledger/iota-core/issues/660#issuecomment-1892596243
17
+ func Test_AccountStateTransition (t * testing.T ) {
18
+ ts := testsuite .NewTestSuite (t ,
19
+ testsuite .WithProtocolParametersOptions (
20
+ iotago .WithTimeProviderOptions (
21
+ 0 ,
22
+ testsuite .GenesisTimeWithOffsetBySlots (200 , testsuite .DefaultSlotDurationInSeconds ),
23
+ testsuite .DefaultSlotDurationInSeconds ,
24
+ testsuite .DefaultSlotsPerEpochExponent ,
25
+ ),
26
+ ),
27
+ )
28
+ defer ts .Shutdown ()
29
+
30
+ node1 := ts .AddValidatorNode ("node1" )
31
+ node2 := ts .AddValidatorNode ("node2" )
32
+ wallet := ts .AddDefaultWallet (node1 )
33
+
34
+ ts .Run (true )
35
+
36
+ node1 .Protocol .SetLogLevel (log .LevelTrace )
37
+
38
+ // split genesis output into 4 outputs for the further usage.
39
+ tx1 := wallet .CreateBasicOutputsEquallyFromInput ("TX1" , 4 , "Genesis:0" )
40
+ ts .IssueBasicBlockWithOptions ("block0" , wallet , tx1 )
41
+
42
+ // Issue some more blocks to make transaction accepted
43
+ {
44
+ ts .IssueValidationBlockWithHeaderOptions ("vblock0" , node2 , mock .WithStrongParents (ts .BlockID ("block0" )))
45
+ ts .IssueValidationBlockWithHeaderOptions ("vblock1" , node1 , mock .WithStrongParents (ts .BlockID ("vblock0" )))
46
+ ts .IssueValidationBlockWithHeaderOptions ("vblock2" , node2 , mock .WithStrongParents (ts .BlockID ("vblock1" )))
47
+
48
+ ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX1" ), true , node1 , node2 )
49
+ }
50
+
51
+ // create the account1 from TX1:0 with wallet "first"
52
+ // generated (block1, TX2)
53
+ ts .AddWallet ("first" , node1 , iotago .EmptyAccountID )
54
+ createFullAccount (ts )
55
+
56
+ // create the account2, from implicit to full account from TX1:1 with wallet "second"
57
+ // generated (block2, TX3), (block3, TX4)
58
+ ts .AddWallet ("second" , node1 , iotago .EmptyAccountID )
59
+ implicitAccID := createImplicitToFullAccount (ts )
60
+
61
+ // send funds to account2, with TX1:2
62
+ // generated (block4, TX5)
63
+ sendfunds (ts )
64
+
65
+ // allot 1000 mana to account2 with TX1:3
66
+ // generated (block5, TX6)
67
+ allotManaTo (ts , implicitAccID )
68
+
69
+ // create native token from "TX5:0" and account2 (TX4:0)
70
+ // generated (block6, TX7)
71
+ createNativetoken (ts )
72
+ }
73
+
17
74
func createFullAccount (ts * testsuite.TestSuite ) iotago.AccountID {
18
75
node1 := ts .Node ("node1" )
76
+ newUserWallet := ts .Wallet ("first" )
19
77
20
- newUserWallet := ts .AddWallet ("first" , node1 , iotago .EmptyAccountID )
21
- // CREATE NEW ACCOUNT WITH BLOCK ISSUER AND STAKING FEATURES FROM BASIC UTXO
78
+ // CREATE NEW ACCOUNT WITH BLOCK ISSUER FROM BASIC UTXO
22
79
newAccountBlockIssuerKey := tpkg .RandBlockIssuerKey ()
23
80
// set the expiry slot of the transitioned genesis account to the latest committed + MaxCommittableAge
24
81
newAccountExpirySlot := node1 .Protocol .Engines .Main .Get ().Storage .Settings ().LatestCommitment ().Slot () + ts .API .ProtocolParameters ().MaxCommittableAge ()
25
82
26
- stakedAmount := iotago .BaseToken (10000 )
27
-
28
- validatorAccountAmount , err := depositcalculator .MinDeposit (ts .API .ProtocolParameters (), iotago .OutputAccount ,
29
- depositcalculator .WithAddress (& iotago.Ed25519Address {}),
30
- depositcalculator .WithBlockIssuerKeys (1 ),
31
- depositcalculator .WithStakedAmount (stakedAmount ),
32
- )
33
- require .NoError (ts .Testing , err )
34
-
35
83
tx1 := ts .DefaultWallet ().CreateAccountFromInput (
36
84
"TX2" ,
37
85
"TX1:0" ,
38
86
newUserWallet ,
39
87
mock .WithBlockIssuerFeature (iotago.BlockIssuerKeys {newAccountBlockIssuerKey }, newAccountExpirySlot ),
40
- mock .WithStakingFeature (stakedAmount , 421 , 0 , 10 ),
41
- mock .WithAccountAmount (validatorAccountAmount ),
88
+ mock .WithAccountAmount (mock .MinIssuerAccountAmount (ts .API .ProtocolParameters ())),
42
89
mock .WithAccountMana (mock .MaxBlockManaCost (ts .DefaultWallet ().Node .Protocol .CommittedAPI ().ProtocolParameters ())),
43
90
)
44
91
@@ -59,9 +106,9 @@ func createFullAccount(ts *testsuite.TestSuite) iotago.AccountID {
59
106
PreviousOutputID : iotago .EmptyOutputID ,
60
107
BlockIssuerKeysAdded : iotago .NewBlockIssuerKeys (newAccountBlockIssuerKey ),
61
108
BlockIssuerKeysRemoved : iotago .NewBlockIssuerKeys (),
62
- ValidatorStakeChange : int64 ( stakedAmount ) ,
63
- StakeEndEpochChange : 10 ,
64
- FixedCostChange : 421 ,
109
+ ValidatorStakeChange : 0 ,
110
+ StakeEndEpochChange : 0 ,
111
+ FixedCostChange : 0 ,
65
112
DelegationStakeChange : 0 ,
66
113
}, false , ts .Nodes ()... )
67
114
@@ -71,21 +118,16 @@ func createFullAccount(ts *testsuite.TestSuite) iotago.AccountID {
71
118
ExpirySlot : newAccountExpirySlot ,
72
119
OutputID : newAccount .OutputID (),
73
120
BlockIssuerKeys : iotago .NewBlockIssuerKeys (newAccountBlockIssuerKey ),
74
- StakeEndEpoch : 10 ,
75
- FixedCost : 421 ,
76
- DelegationStake : 0 ,
77
- ValidatorStake : stakedAmount ,
78
121
}, ts .Nodes ()... )
79
122
80
123
return newAccountOutput .AccountID
81
124
}
82
125
83
126
func createImplicitToFullAccount (ts * testsuite.TestSuite ) iotago.AccountID {
84
127
node1 := ts .Node ("node1" )
128
+ newUserWallet := ts .Wallet ("second" )
85
129
86
130
// CREATE IMPLICIT ACCOUNT FROM GENESIS BASIC UTXO, SENT TO A NEW USER WALLET.
87
- // this wallet is not registered in the ledger yet.
88
- newUserWallet := ts .AddWallet ("second" , node1 , iotago .EmptyAccountID )
89
131
// a default wallet, already registered in the ledger, will issue the transaction and block.
90
132
tx3 := ts .DefaultWallet ().CreateImplicitAccountFromInput (
91
133
"TX3" ,
@@ -158,115 +200,70 @@ func createImplicitToFullAccount(ts *testsuite.TestSuite) iotago.AccountID {
158
200
return implicitAccountID
159
201
}
160
202
161
- func allotManaTo (ts * testsuite.TestSuite , to iotago.AccountID ) {
162
- wallet := ts .DefaultWallet ()
203
+ func sendfunds (ts * testsuite.TestSuite ) {
163
204
node1 := ts .Node ("node1" )
164
205
node2 := ts .Node ("node2" )
206
+ wallet := ts .DefaultWallet ()
207
+ secondWallet := ts .Wallet ("second" )
165
208
166
- tx6 := wallet .AllotManaFromInputs ("TX5" ,
167
- iotago.Allotments {& iotago.Allotment {
168
- AccountID : to ,
169
- Mana : iotago .Mana (1000 ),
170
- }}, "TX1:2" )
171
- commitment := node1 .Protocol .Engines .Main .Get ().Storage .Settings ().LatestCommitment ().Commitment ()
172
- ts .IssueBasicBlockWithOptions ("block4" , wallet , tx6 , mock .WithSlotCommitment (commitment ))
209
+ // send funds from defaultWallet to secondWallet
210
+ tx := wallet .SendFundsToWallet ("TX5" , secondWallet , "TX1:2" )
211
+ ts .IssueBasicBlockWithOptions ("block4" , wallet , tx )
212
+
213
+ ts .AssertTransactionsExist (wallet .Transactions ("TX5" ), true , node1 )
214
+ ts .AssertTransactionsInCacheBooked (wallet .Transactions ("TX5" ), true , node1 )
173
215
174
216
// Issue some more blocks to make transaction accepted
175
217
{
176
- ts .IssueValidationBlockWithHeaderOptions ("vblock6 " , node2 , mock .WithStrongParents (ts .BlockID ("block4" )))
177
- ts .IssueValidationBlockWithHeaderOptions ("vblock7 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock6 " )))
178
- ts .IssueValidationBlockWithHeaderOptions ("vblock8 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock7 " )))
218
+ ts .IssueValidationBlockWithHeaderOptions ("vblock9 " , node2 , mock .WithStrongParents (ts .BlockID ("block4" )))
219
+ ts .IssueValidationBlockWithHeaderOptions ("vblock10 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock9 " )))
220
+ ts .IssueValidationBlockWithHeaderOptions ("vblock11 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock10 " )))
179
221
180
222
ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX5" ), true , node1 , node2 )
181
223
}
182
224
}
183
225
184
- func sendfunds (ts * testsuite.TestSuite ) {
226
+ func allotManaTo (ts * testsuite.TestSuite , to iotago.AccountID ) {
227
+ wallet := ts .DefaultWallet ()
185
228
node1 := ts .Node ("node1" )
186
229
node2 := ts .Node ("node2" )
187
- wallet := ts .DefaultWallet ()
188
- secondWallet := ts .Wallet ("second" )
189
-
190
- tx := wallet .SendFundsToWallet ("TX6" , secondWallet , "TX1:3" )
191
- ts .IssueBasicBlockWithOptions ("block5" , wallet , tx )
192
230
193
- ts .AssertTransactionsExist (wallet .Transactions ("TX6" ), true , node1 )
194
- ts .AssertTransactionsInCacheBooked (wallet .Transactions ("TX6" ), true , node1 )
231
+ tx6 := wallet .AllotManaFromInputs ("TX6" ,
232
+ iotago.Allotments {& iotago.Allotment {
233
+ AccountID : to ,
234
+ Mana : iotago .Mana (1000 ),
235
+ }}, "TX1:3" )
236
+ commitment := node1 .Protocol .Engines .Main .Get ().Storage .Settings ().LatestCommitment ().Commitment ()
237
+ ts .IssueBasicBlockWithOptions ("block5" , wallet , tx6 , mock .WithSlotCommitment (commitment ))
195
238
196
239
// Issue some more blocks to make transaction accepted
197
240
{
198
- ts .IssueValidationBlockWithHeaderOptions ("vblock9 " , node2 , mock .WithStrongParents (ts .BlockID ("block5" )))
199
- ts .IssueValidationBlockWithHeaderOptions ("vblock10 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock9 " )))
200
- ts .IssueValidationBlockWithHeaderOptions ("vblock11 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock10 " )))
241
+ ts .IssueValidationBlockWithHeaderOptions ("vblock6 " , node2 , mock .WithStrongParents (ts .BlockID ("block5" )))
242
+ ts .IssueValidationBlockWithHeaderOptions ("vblock7 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock6 " )))
243
+ ts .IssueValidationBlockWithHeaderOptions ("vblock8 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock7 " )))
201
244
202
- ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX5 " ), true , node1 , node2 )
245
+ ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX6 " ), true , node1 , node2 )
203
246
}
204
-
205
247
}
206
248
207
- func createNativetoken (ts * testsuite.TestSuite , acc iotago.AccountID ) {
249
+ // createNativetoken creates a native token from the given input and account.
250
+ func createNativetoken (ts * testsuite.TestSuite ) {
208
251
wallet := ts .Wallet ("second" )
209
252
node1 := ts .Node ("node1" )
253
+ node2 := ts .Node ("node2" )
210
254
211
- accOutput := ts .Wallet ("second" ).Output ("TX4:0" )
212
- tx := wallet .CreateNativeTokenFromInput ("TX7" , "TX6:0" , accOutput )
213
- ts .IssueBasicBlockWithOptions ("block5" , wallet , tx )
255
+ tx := wallet .CreateNativeTokenFromInput ("TX7" , "TX5:0" , "TX4:0" )
256
+ ts .IssueBasicBlockWithOptions ("block6" , wallet , tx )
214
257
215
258
ts .AssertTransactionsExist (wallet .Transactions ("TX7" ), true , node1 )
216
259
ts .AssertTransactionsInCacheBooked (wallet .Transactions ("TX7" ), true , node1 )
217
- }
218
-
219
- func Test_AccountStateTransition (t * testing.T ) {
220
- ts := testsuite .NewTestSuite (t ,
221
- testsuite .WithProtocolParametersOptions (
222
- iotago .WithTimeProviderOptions (
223
- 0 ,
224
- testsuite .GenesisTimeWithOffsetBySlots (200 , testsuite .DefaultSlotDurationInSeconds ),
225
- testsuite .DefaultSlotDurationInSeconds ,
226
- testsuite .DefaultSlotsPerEpochExponent ,
227
- ),
228
- ),
229
- )
230
- defer ts .Shutdown ()
231
-
232
- // Add a validator node to the network. This will add a validator account to the snapshot.
233
- node1 := ts .AddValidatorNode ("node1" )
234
- node2 := ts .AddValidatorNode ("node2" )
235
- // Add a default block issuer to the network. This will add another block issuer account to the snapshot.
236
- wallet := ts .AddDefaultWallet (node1 )
237
-
238
- ts .Run (true )
239
-
240
- node1 .Protocol .SetLogLevel (log .LevelTrace )
241
-
242
- // split genesis output into two outputs for the 2 accounts creation, 1 as faucet funds
243
- tx1 := wallet .CreateBasicOutputsEquallyFromInput ("TX1" , 4 , "Genesis:0" )
244
- ts .IssueBasicBlockWithOptions ("block0" , wallet , tx1 )
245
260
246
261
// Issue some more blocks to make transaction accepted
247
262
{
248
- ts .IssueValidationBlockWithHeaderOptions ("vblock0 " , node2 , mock .WithStrongParents (ts .BlockID ("block0 " )))
249
- ts .IssueValidationBlockWithHeaderOptions ("vblock1 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock0 " )))
250
- ts .IssueValidationBlockWithHeaderOptions ("vblock2 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock1 " )))
263
+ ts .IssueValidationBlockWithHeaderOptions ("vblock12 " , node2 , mock .WithStrongParents (ts .BlockID ("block6 " )))
264
+ ts .IssueValidationBlockWithHeaderOptions ("vblock13 " , node1 , mock .WithStrongParents (ts .BlockID ("vblock12 " )))
265
+ ts .IssueValidationBlockWithHeaderOptions ("vblock14 " , node2 , mock .WithStrongParents (ts .BlockID ("vblock13 " )))
251
266
252
- ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX1 " ), true , node1 , node2 )
267
+ ts .AssertTransactionsInCacheAccepted (wallet .Transactions ("TX7 " ), true , node1 , node2 )
253
268
}
254
-
255
- // create the first account with TX1:0
256
- // generated (block1, TX2)
257
- createFullAccount (ts )
258
-
259
- // create the second account, from implicit to full account with TX1:1
260
- // generated (block2, TX3), (block3, TX4)
261
- implicitAccID := createImplicitToFullAccount (ts )
262
-
263
- // allot 1000 mana to implicit account with TX1:2
264
- // generated (block4, TX5)
265
- allotManaTo (ts , implicitAccID )
266
-
267
- // send funds to account 2, with TX1:3
268
- sendfunds (ts )
269
-
270
- // create native token
271
- createNativetoken (ts , implicitAccID )
272
269
}
0 commit comments