6
6
"encoding/hex"
7
7
"math"
8
8
"math/big"
9
+ "strings"
9
10
"testing"
10
11
"time"
11
12
@@ -20,8 +21,10 @@ import (
20
21
"github.com/iotexproject/iotex-proto/golang/iotextypes"
21
22
22
23
"github.com/iotexproject/iotex-core/v2/action"
24
+ "github.com/iotexproject/iotex-core/v2/action/protocol"
23
25
"github.com/iotexproject/iotex-core/v2/action/protocol/staking"
24
26
"github.com/iotexproject/iotex-core/v2/blockchain/block"
27
+ "github.com/iotexproject/iotex-core/v2/blockchain/genesis"
25
28
"github.com/iotexproject/iotex-core/v2/config"
26
29
"github.com/iotexproject/iotex-core/v2/pkg/unit"
27
30
"github.com/iotexproject/iotex-core/v2/pkg/util/assertions"
@@ -57,7 +60,6 @@ func TestContractStakingV2(t *testing.T) {
57
60
cfg .DardanellesUpgrade .BlockInterval = time .Second * 8640
58
61
cfg .Plugins [config .GatewayPlugin ] = nil
59
62
test := newE2ETest (t , cfg )
60
- defer test .teardown ()
61
63
62
64
var (
63
65
successExpect = & basicActionExpect {nil , uint64 (iotextypes .ReceiptStatus_Success ), "" }
@@ -673,6 +675,8 @@ func TestContractStakingV2(t *testing.T) {
673
675
},
674
676
},
675
677
})
678
+
679
+ checkStakingViewInit (test , require )
676
680
}
677
681
678
682
func TestContractStakingV3 (t * testing.T ) {
@@ -692,7 +696,6 @@ func TestContractStakingV3(t *testing.T) {
692
696
cfg .DardanellesUpgrade .BlockInterval = time .Second * 8640
693
697
cfg .Plugins [config .GatewayPlugin ] = nil
694
698
test := newE2ETest (t , cfg )
695
- defer test .teardown ()
696
699
697
700
var (
698
701
successExpect = & basicActionExpect {nil , uint64 (iotextypes .ReceiptStatus_Success ), "" }
@@ -731,6 +734,13 @@ func TestContractStakingV3(t *testing.T) {
731
734
require .NoError (err )
732
735
return data
733
736
}
737
+ genTransferActionsWithPrice := func (n int , price * big.Int ) []* actionWithTime {
738
+ acts := make ([]* actionWithTime , n )
739
+ for i := 0 ; i < n ; i ++ {
740
+ acts [i ] = & actionWithTime {mustNoErr (action .SignedTransfer (identityset .Address (1 ).String (), identityset .PrivateKey (2 ), test .nonceMgr .pop (identityset .Address (2 ).String ()), unit .ConvertIotxToRau (1 ), nil , gasLimit , price , action .WithChainID (chainID ))), time .Now ()}
741
+ }
742
+ return acts
743
+ }
734
744
test .run ([]* testcase {
735
745
{
736
746
name : "deploy_contract_v2" ,
@@ -947,6 +957,13 @@ func TestContractStakingV3(t *testing.T) {
947
957
},
948
958
},
949
959
})
960
+
961
+ test .run ([]* testcase {
962
+ {
963
+ preActs : genTransferActionsWithPrice (int (cfg .Genesis .WakeBlockHeight ), gasPrice1559 ),
964
+ },
965
+ })
966
+ checkStakingViewInit (test , require )
950
967
}
951
968
952
969
func TestMigrateStake (t * testing.T ) {
@@ -1194,6 +1211,119 @@ func TestMigrateStake(t *testing.T) {
1194
1211
})
1195
1212
}
1196
1213
1214
+ func TestStakingViewInit (t * testing.T ) {
1215
+ require := require .New (t )
1216
+ contractAddress := "io1dkqh5mu9djfas3xyrmzdv9frsmmytel4mp7a64"
1217
+ cfg := initCfg (require )
1218
+ cfg .Genesis .WakeBlockHeight = 10 // mute staking v2 & enable staking v3
1219
+ cfg .Genesis .SystemStakingContractAddress = contractAddress
1220
+ cfg .Genesis .SystemStakingContractHeight = 1
1221
+ cfg .DardanellesUpgrade .BlockInterval = time .Second * 8640
1222
+ cfg .Plugins [config .GatewayPlugin ] = nil
1223
+ test := newE2ETest (t , cfg )
1224
+
1225
+ var (
1226
+ chainID = test .cfg .Chain .ID
1227
+ contractCreator = 1
1228
+ registerAmount = unit .ConvertIotxToRau (1200000 )
1229
+ stakeTime = time .Now ()
1230
+ candOwnerID = 3
1231
+ blocksPerDay = 24 * time .Hour / cfg .DardanellesUpgrade .BlockInterval
1232
+ stakeDurationBlocks = big .NewInt (int64 (blocksPerDay ))
1233
+ )
1234
+ bytecodeV2 , err := hex .DecodeString (_stakingContractByteCode )
1235
+ require .NoError (err )
1236
+ v1ABI , err := abi .JSON (strings .NewReader (_stakingContractABI ))
1237
+ require .NoError (err )
1238
+ mustCallData := func (m string , args ... any ) []byte {
1239
+ data , err := abiCall (v1ABI , m , args ... )
1240
+ require .NoError (err )
1241
+ return data
1242
+ }
1243
+ genTransferActionsWithPrice := func (n int , price * big.Int ) []* actionWithTime {
1244
+ acts := make ([]* actionWithTime , n )
1245
+ for i := 0 ; i < n ; i ++ {
1246
+ acts [i ] = & actionWithTime {mustNoErr (action .SignedTransfer (identityset .Address (1 ).String (), identityset .PrivateKey (2 ), test .nonceMgr .pop (identityset .Address (2 ).String ()), unit .ConvertIotxToRau (1 ), nil , gasLimit , price , action .WithChainID (chainID ))), time .Now ()}
1247
+ }
1248
+ return acts
1249
+ }
1250
+ test .run ([]* testcase {
1251
+ {
1252
+ name : "deploy_contract" ,
1253
+ preActs : []* actionWithTime {
1254
+ {mustNoErr (action .SignedCandidateRegister (test .nonceMgr .pop (identityset .Address (candOwnerID ).String ()), "cand1" , identityset .Address (1 ).String (), identityset .Address (1 ).String (), identityset .Address (candOwnerID ).String (), registerAmount .String (), 1 , true , nil , gasLimit , gasPrice , identityset .PrivateKey (candOwnerID ), action .WithChainID (chainID ))), time .Now ()},
1255
+ },
1256
+ acts : []* actionWithTime {
1257
+ {mustNoErr (action .SignedExecution ("" , identityset .PrivateKey (contractCreator ), test .nonceMgr .pop (identityset .Address (contractCreator ).String ()), big .NewInt (0 ), gasLimit , gasPrice , append (bytecodeV2 , mustCallData ("" )... ), action .WithChainID (chainID ))), time .Now ()},
1258
+ {mustNoErr (action .SignedExecution (contractAddress , identityset .PrivateKey (contractCreator ), test .nonceMgr .pop (identityset .Address (contractCreator ).String ()), big .NewInt (0 ), gasLimit , gasPrice , mustCallData ("addBucketType(uint256,uint256)" , big .NewInt (100 ), stakeDurationBlocks ), action .WithChainID (chainID ))), stakeTime },
1259
+ },
1260
+ blockExpect : func (test * e2etest , blk * block.Block , err error ) {
1261
+ require .NoError (err )
1262
+ require .EqualValues (3 , len (blk .Receipts ))
1263
+ for _ , receipt := range blk .Receipts {
1264
+ require .Equal (uint64 (iotextypes .ReceiptStatus_Success ), receipt .Status )
1265
+ }
1266
+ require .Equal (contractAddress , blk .Receipts [0 ].ContractAddress )
1267
+ },
1268
+ },
1269
+ {
1270
+ name : "stake" ,
1271
+ acts : []* actionWithTime {
1272
+ {mustNoErr (action .SignedExecution (contractAddress , identityset .PrivateKey (contractCreator ), test .nonceMgr .pop (identityset .Address (contractCreator ).String ()), big .NewInt (100 ), gasLimit , gasPrice , mustCallData ("stake(uint256,address)" , stakeDurationBlocks , common .BytesToAddress (identityset .Address (candOwnerID ).Bytes ())), action .WithChainID (chainID ))), stakeTime },
1273
+ },
1274
+ blockExpect : func (test * e2etest , blk * block.Block , err error ) {
1275
+ require .NoError (err )
1276
+ require .EqualValues (2 , len (blk .Receipts ))
1277
+ for _ , receipt := range blk .Receipts {
1278
+ require .Equal (uint64 (iotextypes .ReceiptStatus_Success ), receipt .Status )
1279
+ }
1280
+ },
1281
+ },
1282
+ })
1283
+
1284
+ test .run ([]* testcase {
1285
+ {
1286
+ preActs : genTransferActionsWithPrice (int (cfg .Genesis .WakeBlockHeight ), gasPrice1559 ),
1287
+ },
1288
+ })
1289
+ checkStakingViewInit (test , require )
1290
+ }
1291
+
1292
+ func checkStakingViewInit (test * e2etest , require * require.Assertions ) {
1293
+ tipHeight , err := test .cs .BlockDAO ().Height ()
1294
+ require .NoError (err )
1295
+ test .t .Log ("tip height:" , tipHeight )
1296
+ tipHeader , err := test .cs .BlockDAO ().HeaderByHeight (tipHeight )
1297
+ require .NoError (err )
1298
+
1299
+ stkProtocol , ok := test .cs .Registry ().Find ("staking" )
1300
+ require .True (ok , "staking protocol should be registered" )
1301
+ stk := stkProtocol .(* staking.Protocol )
1302
+ ctx := context .Background ()
1303
+ ctx = genesis .WithGenesisContext (ctx , test .cfg .Genesis )
1304
+ ctx = protocol .WithBlockCtx (ctx , protocol.BlockCtx {
1305
+ BlockHeight : tipHeight ,
1306
+ BlockTimeStamp : tipHeader .Timestamp (),
1307
+ })
1308
+ ctx = protocol .WithFeatureCtx (ctx )
1309
+ cands , err := stk .ActiveCandidates (ctx , test .cs .StateFactory (), 0 )
1310
+ require .NoError (err )
1311
+
1312
+ require .NoError (test .svr .Stop (ctx ))
1313
+ testutil .CleanupPath (test .cfg .Chain .ContractStakingIndexDBPath )
1314
+ test .cfg .Chain .ContractStakingIndexDBPath , err = testutil .PathOfTempFile ("contractindex.db" )
1315
+ require .NoError (err )
1316
+
1317
+ test = newE2ETestWithCtx (ctx , test .t , test .cfg )
1318
+ defer test .teardown ()
1319
+ stkProtocol , ok = test .cs .Registry ().Find ("staking" )
1320
+ require .True (ok , "staking protocol should be registered" )
1321
+ stk = stkProtocol .(* staking.Protocol )
1322
+ newCands , err := stk .ActiveCandidates (ctx , test .cs .StateFactory (), 0 )
1323
+ require .NoError (err )
1324
+ require .ElementsMatch (cands , newCands , "candidates should be the same after restart" )
1325
+ }
1326
+
1197
1327
func methodSignToID (sign string ) []byte {
1198
1328
hash := crypto .Keccak256Hash ([]byte (sign ))
1199
1329
return hash .Bytes ()[:4 ]
0 commit comments