1
- use crate :: jcli_app:: certificate:: { write_cert, Error } ;
1
+ use crate :: jcli_app:: certificate:: { weighted_pool_ids :: WeightedPoolIds , write_cert, Error } ;
2
2
use 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 } ;
6
4
use chain_impl_mockchain:: certificate:: { Certificate , StakeDelegation as Delegation } ;
7
5
use chain_impl_mockchain:: transaction:: UnspecifiedAccountIdentifier ;
8
6
use jormungandr_lib:: interfaces:: Certificate as CertificateType ;
9
- use std:: convert:: TryFrom ;
10
- use std:: error:: Error as StdError ;
7
+ use std:: convert:: TryInto ;
11
8
use std:: ops:: Deref ;
12
9
use std:: path:: PathBuf ;
13
- use std:: str:: FromStr ;
14
10
use structopt:: StructOpt ;
15
11
16
12
#[ derive( StructOpt ) ]
@@ -19,42 +15,19 @@ pub struct StakeDelegation {
19
15
#[ structopt( name = "STAKE_KEY" , parse( try_from_str = "parse_pub_key" ) ) ]
20
16
stake_id : PublicKey < Ed25519 > ,
21
17
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 ,
26
20
27
21
/// write the output to the given file or print it to the standard output if not defined
28
22
#[ structopt( short = "o" , long = "output" ) ]
29
23
output : Option < PathBuf > ,
30
24
}
31
25
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
-
49
26
impl StakeDelegation {
50
27
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
- } ;
55
28
let content = Delegation {
56
29
account_id : UnspecifiedAccountIdentifier :: from_single_account ( self . stake_id . into ( ) ) ,
57
- delegation,
30
+ delegation : ( & self . pool_ids ) . try_into ( ) ? ,
58
31
} ;
59
32
let cert = Certificate :: StakeDelegation ( content) ;
60
33
write_cert (
@@ -63,32 +36,3 @@ impl StakeDelegation {
63
36
)
64
37
}
65
38
}
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