1- use std:: convert:: TryInto ;
2-
31use crate :: {
42 contracts:: ballot:: { BallotContract , BallotContractError } ,
53 oracle_config:: { BallotBoxWrapperParameters , CastBallotBoxVoteParameters } ,
@@ -59,23 +57,14 @@ pub trait BallotBox {
5957 fn get_box ( & self ) -> & ErgoBox ;
6058}
6159
62- #[ derive( Clone ) ]
60+ #[ derive( Clone , Debug ) ]
6361pub struct BallotBoxWrapper {
6462 ergo_box : ErgoBox ,
6563 contract : BallotContract ,
6664}
6765
6866impl BallotBoxWrapper {
6967 pub fn new ( ergo_box : ErgoBox , inputs : BallotBoxWrapperInputs ) -> Result < Self , BallotBoxError > {
70- let CastBallotBoxVoteParameters {
71- reward_token_id,
72- reward_token_quantity,
73- pool_box_address_hash,
74- } = inputs
75- . parameters
76- . vote_parameters
77- . as_ref ( )
78- . ok_or ( BallotBoxError :: ExpectedVoteCast ) ?;
7968 let ballot_token_id = & ergo_box
8069 . tokens
8170 . as_ref ( )
@@ -98,42 +87,54 @@ impl BallotBoxWrapper {
9887 return Err ( BallotBoxError :: UnexpectedGroupElementInR4 ) ;
9988 }
10089
101- if ergo_box
102- . get_register ( NonMandatoryRegisterId :: R5 . into ( ) )
103- . ok_or ( BallotBoxError :: NoUpdateBoxCreationHeightInR5 ) ?
104- . try_extract_into :: < i32 > ( )
105- . is_err ( )
90+ if let Some ( CastBallotBoxVoteParameters {
91+ reward_token_id,
92+ reward_token_quantity,
93+ pool_box_address_hash,
94+ update_box_creation_height,
95+ } ) = inputs. parameters . vote_parameters . as_ref ( )
10696 {
107- return Err ( BallotBoxError :: NoUpdateBoxCreationHeightInR5 ) ;
108- }
97+ let register_update_box_creation_height = ergo_box
98+ . get_register ( NonMandatoryRegisterId :: R5 . into ( ) )
99+ . ok_or ( BallotBoxError :: NoUpdateBoxCreationHeightInR5 ) ?
100+ . try_extract_into :: < i32 > ( ) ?;
109101
110- let register_pool_box_address_hash = ergo_box
111- . get_register ( NonMandatoryRegisterId :: R6 . into ( ) )
112- . ok_or ( BallotBoxError :: NoPoolBoxAddressInR6 ) ?
113- . try_extract_into :: < Digest32 > ( ) ?;
114- let pb: Digest32 = base16:: decode ( pool_box_address_hash)
115- . unwrap ( )
116- . try_into ( )
117- . unwrap ( ) ;
118- if pb != register_pool_box_address_hash {
119- warn ! ( "Pool box address in R6 register differs to config. Could be due to vote." ) ;
120- }
102+ if register_update_box_creation_height != * update_box_creation_height {
103+ warn ! ( "Update box creation height in R5 register differs to config. Could be due to vote." ) ;
104+ }
121105
122- let register_reward_token_id = ergo_box
123- . get_register ( NonMandatoryRegisterId :: R7 . into ( ) )
124- . ok_or ( BallotBoxError :: NoRewardTokenIdInR7 ) ?
125- . try_extract_into :: < TokenId > ( ) ?;
126- if register_reward_token_id != * reward_token_id {
127- warn ! ( "Reward token id in R7 register differs to config. Could be due to vote." ) ;
128- }
106+ let register_pool_box_address_hash = ergo_box
107+ . get_register ( NonMandatoryRegisterId :: R6 . into ( ) )
108+ . ok_or ( BallotBoxError :: NoPoolBoxAddressInR6 ) ?
109+ . try_extract_into :: < Digest32 > ( ) ?;
129110
130- let register_reward_token_quantity = ergo_box
131- . get_register ( NonMandatoryRegisterId :: R8 . into ( ) )
132- . ok_or ( BallotBoxError :: NoRewardTokenQuantityInR8 ) ?
133- . try_extract_into :: < i32 > ( ) ? as u32 ;
111+ if * pool_box_address_hash != register_pool_box_address_hash {
112+ warn ! ( "Pool box address in R6 register differs to config. Could be due to vote." ) ;
113+ }
114+
115+ let register_reward_token_id = ergo_box
116+ . get_register ( NonMandatoryRegisterId :: R7 . into ( ) )
117+ . ok_or ( BallotBoxError :: NoRewardTokenIdInR7 ) ?
118+ . try_extract_into :: < TokenId > ( ) ?;
119+
120+ if register_reward_token_id != * reward_token_id {
121+ warn ! ( "Reward token id in R7 register differs to config. Could be due to vote." ) ;
122+ }
134123
135- if register_reward_token_quantity != * reward_token_quantity {
136- warn ! ( "Reward token quantity in R8 register differs to config. Could be due to vote." ) ;
124+ let register_reward_token_quantity: u64 = ergo_box
125+ . get_register ( NonMandatoryRegisterId :: R8 . into ( ) )
126+ . ok_or ( BallotBoxError :: NoRewardTokenQuantityInR8 ) ?
127+ . try_extract_into :: < i64 > ( ) ?
128+ as u64 ;
129+
130+ if register_reward_token_quantity != * reward_token_quantity {
131+ warn ! (
132+ "Reward token quantity in R8 register differs to config. Could be due to vote."
133+ ) ;
134+ }
135+ } else if ergo_box. additional_registers . len ( ) > 1 {
136+ // If no vote parameter is provided, then the box must only have R4 (owner public key) defined
137+ return Err ( BallotBoxError :: ExpectedVoteCast ) ;
137138 }
138139
139140 let contract = BallotContract :: from_ergo_tree ( ergo_box. ergo_tree . clone ( ) , inputs. into ( ) ) ?;
@@ -150,6 +151,73 @@ pub struct BallotBoxWrapperInputs<'a> {
150151 pub update_nft_token_id : & ' a TokenId ,
151152}
152153
154+ /// A Ballot Box with vote parameters guaranteed to be set
155+ #[ derive( Clone , Debug ) ]
156+ pub struct VoteBallotBoxWrapper {
157+ ergo_box : ErgoBox ,
158+ vote_parameters : CastBallotBoxVoteParameters ,
159+ contract : BallotContract ,
160+ }
161+
162+ impl VoteBallotBoxWrapper {
163+ pub fn new ( ergo_box : ErgoBox , inputs : BallotBoxWrapperInputs ) -> Result < Self , BallotBoxError > {
164+ let ballot_token_id = & ergo_box
165+ . tokens
166+ . as_ref ( )
167+ . ok_or ( BallotBoxError :: NoBallotToken ) ?
168+ . get ( 0 )
169+ . ok_or ( BallotBoxError :: NoBallotToken ) ?
170+ . token_id ;
171+ if * ballot_token_id != * inputs. ballot_token_id {
172+ return Err ( BallotBoxError :: UnknownBallotTokenId ) ;
173+ }
174+
175+ if ergo_box
176+ . get_register ( NonMandatoryRegisterId :: R4 . into ( ) )
177+ . ok_or ( BallotBoxError :: NoGroupElementInR4 ) ?
178+ . try_extract_into :: < EcPoint > ( )
179+ . is_err ( )
180+ {
181+ return Err ( BallotBoxError :: NoGroupElementInR4 ) ;
182+ }
183+ let update_box_creation_height = ergo_box
184+ . get_register ( NonMandatoryRegisterId :: R5 . into ( ) )
185+ . ok_or ( BallotBoxError :: NoUpdateBoxCreationHeightInR5 ) ?
186+ . try_extract_into :: < i32 > ( ) ?;
187+
188+ let pool_box_address_hash = ergo_box
189+ . get_register ( NonMandatoryRegisterId :: R6 . into ( ) )
190+ . ok_or ( BallotBoxError :: NoPoolBoxAddressInR6 ) ?
191+ . try_extract_into :: < Digest32 > ( ) ?;
192+
193+ let reward_token_id = ergo_box
194+ . get_register ( NonMandatoryRegisterId :: R7 . into ( ) )
195+ . ok_or ( BallotBoxError :: NoRewardTokenIdInR7 ) ?
196+ . try_extract_into :: < TokenId > ( ) ?;
197+ let reward_token_quantity = ergo_box
198+ . get_register ( NonMandatoryRegisterId :: R8 . into ( ) )
199+ . ok_or ( BallotBoxError :: NoRewardTokenQuantityInR8 ) ?
200+ . try_extract_into :: < i64 > ( ) ? as u64 ;
201+
202+ let contract = BallotContract :: from_ergo_tree ( ergo_box. ergo_tree . clone ( ) , inputs. into ( ) ) ?;
203+ let vote_parameters = CastBallotBoxVoteParameters {
204+ pool_box_address_hash,
205+ reward_token_id,
206+ reward_token_quantity,
207+ update_box_creation_height,
208+ } ;
209+ Ok ( Self {
210+ ergo_box,
211+ contract,
212+ vote_parameters,
213+ } )
214+ }
215+
216+ pub fn vote_parameters ( & self ) -> & CastBallotBoxVoteParameters {
217+ & self . vote_parameters
218+ }
219+ }
220+
153221impl BallotBox for BallotBoxWrapper {
154222 fn contract ( & self ) -> & BallotContract {
155223 & self . contract
@@ -183,6 +251,39 @@ impl BallotBox for BallotBoxWrapper {
183251 }
184252}
185253
254+ impl BallotBox for VoteBallotBoxWrapper {
255+ fn contract ( & self ) -> & BallotContract {
256+ & self . contract
257+ }
258+
259+ fn ballot_token ( & self ) -> Token {
260+ self . ergo_box
261+ . tokens
262+ . as_ref ( )
263+ . unwrap ( )
264+ . get ( 0 )
265+ . unwrap ( )
266+ . clone ( )
267+ }
268+
269+ fn min_storage_rent ( & self ) -> u64 {
270+ self . contract . min_storage_rent ( )
271+ }
272+
273+ fn ballot_token_owner ( & self ) -> ProveDlog {
274+ self . ergo_box
275+ . get_register ( NonMandatoryRegisterId :: R4 . into ( ) )
276+ . unwrap ( )
277+ . try_extract_into :: < EcPoint > ( )
278+ . unwrap ( )
279+ . into ( )
280+ }
281+
282+ fn get_box ( & self ) -> & ErgoBox {
283+ & self . ergo_box
284+ }
285+ }
286+
186287#[ allow( clippy:: too_many_arguments) ]
187288pub fn make_local_ballot_box_candidate (
188289 contract : & BallotContract ,
@@ -210,7 +311,7 @@ pub fn make_local_ballot_box_candidate(
210311 ) ;
211312 builder. set_register_value (
212313 NonMandatoryRegisterId :: R8 ,
213- ( * reward_tokens. amount . as_u64 ( ) as i32 ) . into ( ) ,
314+ ( * reward_tokens. amount . as_u64 ( ) as i64 ) . into ( ) ,
214315 ) ;
215316 builder. add_token ( ballot_token) ;
216317 builder. build ( )
0 commit comments