@@ -16,11 +16,13 @@ use witnet_config::defaults::{
1616use witnet_data_structures:: {
1717 chain:: {
1818 tapi:: ActiveWips , Block , ChainState , CheckpointBeacon , DataRequestInfo , Epoch , Hash ,
19- Hashable , NodeStats , PublicKeyHash , SuperBlockVote , SupplyInfo ,
19+ Hashable , NodeStats , PublicKeyHash , SuperBlockVote , SupplyInfo , ValueTransferOutput ,
2020 } ,
2121 error:: { ChainInfoError , TransactionError :: DataRequestNotFound } ,
2222 staking:: errors:: StakesError ,
23- transaction:: { DRTransaction , StakeTransaction , Transaction , VTTransaction } ,
23+ transaction:: {
24+ DRTransaction , StakeTransaction , Transaction , UnstakeTransaction , VTTransaction ,
25+ } ,
2426 transaction_factory:: { self , NodeBalance } ,
2527 types:: LastBeacon ,
2628 utxo_pool:: { get_utxo_info, UtxoInfo } ,
@@ -33,8 +35,8 @@ use crate::{
3335 chain_manager:: { handlers:: BlockBatches :: * , BlockCandidate } ,
3436 messages:: {
3537 AddBlocks , AddCandidates , AddCommitReveal , AddSuperBlock , AddSuperBlockVote ,
36- AddTransaction , Broadcast , BuildDrt , BuildStake , BuildVtt , EpochNotification ,
37- EstimatePriority , GetBalance , GetBalanceTarget , GetBlocksEpochRange ,
38+ AddTransaction , Broadcast , BuildDrt , BuildStake , BuildUnstake , BuildVtt ,
39+ EpochNotification , EstimatePriority , GetBalance , GetBalanceTarget , GetBlocksEpochRange ,
3840 GetDataRequestInfo , GetHighestCheckpointBeacon , GetMemoryTransaction , GetMempool ,
3941 GetMempoolResult , GetNodeStats , GetReputation , GetReputationResult , GetSignalingInfo ,
4042 GetState , GetSuperBlockVotes , GetSupplyInfo , GetUtxoInfo , IsConfirmedBlock ,
@@ -1357,6 +1359,65 @@ impl Handler<BuildStake> for ChainManager {
13571359 }
13581360}
13591361
1362+ impl Handler < BuildUnstake > for ChainManager {
1363+ type Result = ResponseActFuture < Self , <BuildUnstake as Message >:: Result > ;
1364+
1365+ fn handle ( & mut self , msg : BuildUnstake , _ctx : & mut Self :: Context ) -> Self :: Result {
1366+ if !msg. dry_run && self . sm_state != StateMachine :: Synced {
1367+ return Box :: pin ( actix:: fut:: err (
1368+ ChainManagerError :: NotSynced {
1369+ current_state : self . sm_state ,
1370+ }
1371+ . into ( ) ,
1372+ ) ) ;
1373+ }
1374+
1375+ let withdrawal = ValueTransferOutput {
1376+ time_lock : 0 ,
1377+ pkh : self . own_pkh . unwrap ( ) ,
1378+ value : msg. value ,
1379+ } ;
1380+ match transaction_factory:: build_ut ( withdrawal, msg. operator ) {
1381+ Err ( e) => {
1382+ log:: error!( "Error when building stake transaction: {}" , e) ;
1383+ Box :: pin ( actix:: fut:: err ( e. into ( ) ) )
1384+ }
1385+ Ok ( ut) => {
1386+ let fut = signature_mngr:: sign_transaction ( & ut, 1 )
1387+ . into_actor ( self )
1388+ . then ( move |s, act, _ctx| match s {
1389+ Ok ( signature) => {
1390+ let ut =
1391+ UnstakeTransaction :: new ( ut, signature. first ( ) . unwrap ( ) . clone ( ) ) ;
1392+
1393+ if msg. dry_run {
1394+ Either :: Right ( actix:: fut:: result ( Ok ( ut) ) )
1395+ } else {
1396+ let transaction = Transaction :: Unstake ( ut. clone ( ) ) ;
1397+ Either :: Left (
1398+ act. add_transaction (
1399+ AddTransaction {
1400+ transaction,
1401+ broadcast_flag : true ,
1402+ } ,
1403+ get_timestamp ( ) ,
1404+ )
1405+ . map_ok ( move |_, _, _| ut) ,
1406+ )
1407+ }
1408+ }
1409+ Err ( e) => {
1410+ log:: error!( "Failed to sign stake transaction: {}" , e) ;
1411+ Either :: Right ( actix:: fut:: result ( Err ( e) ) )
1412+ }
1413+ } ) ;
1414+
1415+ Box :: pin ( fut)
1416+ }
1417+ }
1418+ }
1419+ }
1420+
13601421impl Handler < QueryStake > for ChainManager {
13611422 type Result = <QueryStake as Message >:: Result ;
13621423
0 commit comments