@@ -16,7 +16,10 @@ use actix::{
16
16
use ansi_term:: Color :: { White , Yellow } ;
17
17
use futures:: future:: { try_join_all, FutureExt } ;
18
18
19
- use witnet_config:: defaults:: PSEUDO_CONSENSUS_CONSTANTS_WIP0027_COLLATERAL_AGE ;
19
+ use witnet_config:: defaults:: {
20
+ PSEUDO_CONSENSUS_CONSTANTS_POS_MAX_STAKE_BLOCK_WEIGHT ,
21
+ PSEUDO_CONSENSUS_CONSTANTS_WIP0027_COLLATERAL_AGE ,
22
+ } ;
20
23
use witnet_data_structures:: {
21
24
chain:: {
22
25
tapi:: { after_second_hard_fork, ActiveWips } ,
@@ -115,6 +118,7 @@ impl ChainManager {
115
118
let chain_info = self . chain_state . chain_info . as_mut ( ) . unwrap ( ) ;
116
119
let max_vt_weight = chain_info. consensus_constants . max_vt_weight ;
117
120
let max_dr_weight = chain_info. consensus_constants . max_dr_weight ;
121
+ let max_st_weight = PSEUDO_CONSENSUS_CONSTANTS_POS_MAX_STAKE_BLOCK_WEIGHT ;
118
122
let mining_bf = chain_info. consensus_constants . mining_backup_factor ;
119
123
let mining_rf = chain_info. consensus_constants . mining_replication_factor ;
120
124
let collateral_minimum = chain_info. consensus_constants . collateral_minimum ;
@@ -232,6 +236,7 @@ impl ChainManager {
232
236
) ,
233
237
max_vt_weight,
234
238
max_dr_weight,
239
+ max_st_weight,
235
240
beacon,
236
241
eligibility_claim,
237
242
& tally_transactions,
@@ -814,11 +819,13 @@ impl ChainManager {
814
819
/// Build a new Block using the supplied leadership proof and by filling transactions from the
815
820
/// `transaction_pool`
816
821
/// Returns an unsigned block!
822
+ /// TODO: simplify function signature, e.g. through merging multiple related fields into new data structures.
817
823
#[ allow( clippy:: too_many_arguments) ]
818
824
pub fn build_block (
819
825
pools_ref : ( & mut TransactionsPool , & UnspentOutputsPool , & DataRequestPool ) ,
820
826
max_vt_weight : u32 ,
821
827
max_dr_weight : u32 ,
828
+ max_st_weight : u32 ,
822
829
beacon : CheckpointBeacon ,
823
830
proof : BlockEligibilityClaim ,
824
831
tally_transactions : & [ TallyTransaction ] ,
@@ -842,18 +849,21 @@ pub fn build_block(
842
849
let mut transaction_fees: u64 = 0 ;
843
850
let mut vt_weight: u32 = 0 ;
844
851
let mut dr_weight: u32 = 0 ;
852
+ let mut st_weight: u32 = 0 ;
845
853
let mut value_transfer_txns = Vec :: new ( ) ;
846
854
let mut data_request_txns = Vec :: new ( ) ;
847
855
let mut tally_txns = Vec :: new ( ) ;
848
- // TODO: handle stake tx
849
- let stake_txns = Vec :: new ( ) ;
856
+ let mut stake_txns = Vec :: new ( ) ;
850
857
// TODO: handle unstake tx
851
858
let unstake_txns = Vec :: new ( ) ;
852
859
860
+ // Calculate the base weight for different types of transactions, to know when to give up trying to fit more
861
+ // transactions into a block
853
862
let min_vt_weight =
854
863
VTTransactionBody :: new ( vec ! [ Input :: default ( ) ] , vec ! [ ValueTransferOutput :: default ( ) ] )
855
864
. weight ( ) ;
856
- // Currently only value transfer transactions weight is taking into account
865
+ let min_st_weight =
866
+ StakeTransactionBody :: new ( vec ! [ Input :: default ( ) ] , Default :: default ( ) , None ) . weight ( ) ;
857
867
858
868
for vt_tx in transactions_pool. vt_iter ( ) {
859
869
let transaction_weight = vt_tx. weight ( ) ;
@@ -868,7 +878,7 @@ pub fn build_block(
868
878
}
869
879
} ;
870
880
871
- let new_vt_weight = vt_weight . saturating_add ( transaction_weight) ;
881
+ let new_vt_weight = st_weight . saturating_add ( transaction_weight) ;
872
882
if new_vt_weight <= max_vt_weight {
873
883
update_utxo_diff (
874
884
& mut utxo_diff,
@@ -994,6 +1004,39 @@ pub fn build_block(
994
1004
}
995
1005
}
996
1006
1007
+ for st_tx in transactions_pool. st_iter ( ) {
1008
+ let transaction_weight = st_tx. weight ( ) ;
1009
+ let transaction_fee = match st_transaction_fee ( st_tx, & utxo_diff, epoch, epoch_constants) {
1010
+ Ok ( x) => x,
1011
+ Err ( e) => {
1012
+ log:: warn!(
1013
+ "Error when calculating transaction fee for transaction: {}" ,
1014
+ e
1015
+ ) ;
1016
+ continue ;
1017
+ }
1018
+ } ;
1019
+
1020
+ let new_st_weight = st_weight. saturating_add ( transaction_weight) ;
1021
+ if new_st_weight <= max_st_weight {
1022
+ update_utxo_diff (
1023
+ & mut utxo_diff,
1024
+ st_tx. body . inputs . iter ( ) ,
1025
+ st_tx. body . change . iter ( ) ,
1026
+ st_tx. hash ( ) ,
1027
+ ) ;
1028
+ stake_txns. push ( st_tx. clone ( ) ) ;
1029
+ transaction_fees = transaction_fees. saturating_add ( transaction_fee) ;
1030
+ st_weight = new_st_weight;
1031
+ }
1032
+
1033
+ // The condition to stop is if the free space in the block for VTTransactions
1034
+ // is less than the minimum stake transaction weight
1035
+ if st_weight > max_st_weight. saturating_sub ( min_st_weight) {
1036
+ break ;
1037
+ }
1038
+ }
1039
+
997
1040
// Include Mint Transaction by miner
998
1041
let reward = block_reward ( epoch, initial_block_reward, halving_period) + transaction_fees;
999
1042
let mint = MintTransaction :: with_external_address (
@@ -1096,6 +1139,7 @@ mod tests {
1096
1139
// Set `max_vt_weight` and `max_dr_weight` to zero (no transaction should be included)
1097
1140
let max_vt_weight = 0 ;
1098
1141
let max_dr_weight = 0 ;
1142
+ let max_st_weight = 0 ;
1099
1143
1100
1144
// Fields required to mine a block
1101
1145
let block_beacon = CheckpointBeacon :: default ( ) ;
@@ -1109,6 +1153,7 @@ mod tests {
1109
1153
( & mut transaction_pool, & unspent_outputs_pool, & dr_pool) ,
1110
1154
max_vt_weight,
1111
1155
max_dr_weight,
1156
+ max_st_weight,
1112
1157
block_beacon,
1113
1158
block_proof,
1114
1159
& [ ] ,
@@ -1277,6 +1322,7 @@ mod tests {
1277
1322
// Set `max_vt_weight` to fit only `transaction_1` weight
1278
1323
let max_vt_weight = vt_tx1. weight ( ) ;
1279
1324
let max_dr_weight = 0 ;
1325
+ let max_st_weight = 0 ;
1280
1326
1281
1327
// Insert transactions into `transactions_pool`
1282
1328
let mut transaction_pool = TransactionsPool :: default ( ) ;
@@ -1313,6 +1359,7 @@ mod tests {
1313
1359
( & mut transaction_pool, & unspent_outputs_pool, & dr_pool) ,
1314
1360
max_vt_weight,
1315
1361
max_dr_weight,
1362
+ max_st_weight,
1316
1363
block_beacon,
1317
1364
block_proof,
1318
1365
& [ ] ,
@@ -1378,6 +1425,7 @@ mod tests {
1378
1425
// Set `max_vt_weight` to fit only 1 transaction weight
1379
1426
let max_vt_weight = vt_tx2. weight ( ) ;
1380
1427
let max_dr_weight = 0 ;
1428
+ let max_st_weight = 0 ;
1381
1429
1382
1430
// Insert transactions into `transactions_pool`
1383
1431
let mut transaction_pool = TransactionsPool :: default ( ) ;
@@ -1414,6 +1462,7 @@ mod tests {
1414
1462
( & mut transaction_pool, & unspent_outputs_pool, & dr_pool) ,
1415
1463
max_vt_weight,
1416
1464
max_dr_weight,
1465
+ max_st_weight,
1417
1466
block_beacon,
1418
1467
block_proof,
1419
1468
& [ ] ,
@@ -1493,6 +1542,7 @@ mod tests {
1493
1542
// Set `max_vt_weight` to fit only `transaction_1` weight
1494
1543
let max_vt_weight = 0 ;
1495
1544
let max_dr_weight = dr_tx1. weight ( ) ;
1545
+ let max_st_weight = 0 ;
1496
1546
1497
1547
// Insert transactions into `transactions_pool`
1498
1548
let mut transaction_pool = TransactionsPool :: default ( ) ;
@@ -1529,6 +1579,7 @@ mod tests {
1529
1579
( & mut transaction_pool, & unspent_outputs_pool, & dr_pool) ,
1530
1580
max_vt_weight,
1531
1581
max_dr_weight,
1582
+ max_st_weight,
1532
1583
block_beacon,
1533
1584
block_proof,
1534
1585
& [ ] ,
@@ -1591,6 +1642,7 @@ mod tests {
1591
1642
// Set `max_vt_weight` to fit only `transaction_1` weight
1592
1643
let max_vt_weight = 0 ;
1593
1644
let max_dr_weight = dr_tx2. weight ( ) ;
1645
+ let max_st_weight = 0 ;
1594
1646
1595
1647
// Insert transactions into `transactions_pool`
1596
1648
let mut transaction_pool = TransactionsPool :: default ( ) ;
@@ -1627,6 +1679,7 @@ mod tests {
1627
1679
( & mut transaction_pool, & unspent_outputs_pool, & dr_pool) ,
1628
1680
max_vt_weight,
1629
1681
max_dr_weight,
1682
+ max_st_weight,
1630
1683
block_beacon,
1631
1684
block_proof,
1632
1685
& [ ] ,
0 commit comments