1- use crate :: jcli_app:: certificate:: { write_cert, Error } ;
1+ use crate :: jcli_app:: certificate:: { weighted_pool_ids :: WeightedPoolIds , write_cert, Error } ;
22use crate :: jcli_app:: utils:: key_parser:: parse_pub_key;
3- use chain_crypto:: { Blake2b256 , Ed25519 , PublicKey } ;
4- use chain_impl_mockchain:: account:: { DelegationRatio , DelegationType } ;
5- use chain_impl_mockchain:: accounting:: account:: DELEGATION_RATIO_MAX_DECLS ;
3+ use chain_crypto:: { Ed25519 , PublicKey } ;
64use chain_impl_mockchain:: certificate:: { Certificate , StakeDelegation as Delegation } ;
75use chain_impl_mockchain:: transaction:: UnspecifiedAccountIdentifier ;
86use jormungandr_lib:: interfaces:: Certificate as CertificateType ;
9- use std:: convert:: TryFrom ;
10- use std:: error:: Error as StdError ;
7+ use std:: convert:: TryInto ;
118use std:: ops:: Deref ;
129use std:: path:: PathBuf ;
13- use std:: str:: FromStr ;
1410use structopt:: StructOpt ;
1511
1612#[ derive( StructOpt ) ]
@@ -19,42 +15,19 @@ pub struct StakeDelegation {
1915 #[ structopt( name = "STAKE_KEY" , parse( try_from_str = "parse_pub_key" ) ) ]
2016 stake_id : PublicKey < Ed25519 > ,
2117
22- /// hex-encoded stake pool IDs and their numeric weights in format "pool_id:weight".
23- /// If weight is not provided, it defaults to 1.
24- #[ structopt( name = "STAKE_POOL_IDS" , raw( required = "true" ) ) ]
25- pool_ids : Vec < WeightedPoolId > ,
18+ #[ structopt( flatten) ]
19+ pool_ids : WeightedPoolIds ,
2620
2721 /// write the output to the given file or print it to the standard output if not defined
2822 #[ structopt( short = "o" , long = "output" ) ]
2923 output : Option < PathBuf > ,
3024}
3125
32- struct WeightedPoolId {
33- pool_id : Blake2b256 ,
34- weight : u8 ,
35- }
36-
37- impl FromStr for WeightedPoolId {
38- type Err = Box < dyn StdError > ;
39-
40- fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
41- let mut split = s. splitn ( 2 , ':' ) ;
42- Ok ( WeightedPoolId {
43- pool_id : split. next ( ) . unwrap ( ) . parse ( ) ?,
44- weight : split. next ( ) . map_or ( Ok ( 1 ) , str:: parse) ?,
45- } )
46- }
47- }
48-
4926impl StakeDelegation {
5027 pub fn exec ( self ) -> Result < ( ) , Error > {
51- let delegation = match self . pool_ids . len ( ) {
52- 1 => DelegationType :: Full ( self . pool_ids [ 0 ] . pool_id . into ( ) ) ,
53- _ => DelegationType :: Ratio ( delegation_ratio ( & self . pool_ids ) ?) ,
54- } ;
5528 let content = Delegation {
5629 account_id : UnspecifiedAccountIdentifier :: from_single_account ( self . stake_id . into ( ) ) ,
57- delegation,
30+ delegation : ( & self . pool_ids ) . try_into ( ) ? ,
5831 } ;
5932 let cert = Certificate :: StakeDelegation ( content) ;
6033 write_cert (
@@ -63,32 +36,3 @@ impl StakeDelegation {
6336 )
6437 }
6538}
66-
67- fn delegation_ratio ( pool_ids : & [ WeightedPoolId ] ) -> Result < DelegationRatio , Error > {
68- if pool_ids. len ( ) > DELEGATION_RATIO_MAX_DECLS {
69- return Err ( Error :: TooManyPoolDelegations {
70- actual : pool_ids. len ( ) ,
71- max : DELEGATION_RATIO_MAX_DECLS ,
72- } ) ;
73- }
74- let parts = delegation_ratio_sum ( pool_ids) ?;
75- let pools = pool_ids
76- . iter ( )
77- . map ( |pool_id| ( pool_id. pool_id . into ( ) , pool_id. weight ) )
78- . collect ( ) ;
79- DelegationRatio :: new ( parts, pools) . ok_or_else ( || Error :: InvalidPoolDelegation )
80- }
81-
82- fn delegation_ratio_sum ( pool_ids : & [ WeightedPoolId ] ) -> Result < u8 , Error > {
83- let parts = pool_ids
84- . iter ( )
85- . map ( |pool_id| match pool_id. weight {
86- 0 => Err ( Error :: PoolDelegationWithZeroWeight ) ,
87- weight => Ok ( weight as u64 ) ,
88- } )
89- . sum :: < Result < _ , _ > > ( ) ?;
90- u8:: try_from ( parts) . map_err ( |_| Error :: InvalidPoolDelegationWeights {
91- actual : parts,
92- max : u8:: max_value ( ) as u64 ,
93- } )
94- }
0 commit comments