Skip to content

Commit 9cac6cc

Browse files
committed
Initial rebase work
1 parent 148f021 commit 9cac6cc

File tree

10 files changed

+205
-70
lines changed

10 files changed

+205
-70
lines changed

core/src/box_kind/ballot_box.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl BallotBoxWrapper {
130130
let register_reward_token_quantity = ergo_box
131131
.get_register(NonMandatoryRegisterId::R8.into())
132132
.ok_or(BallotBoxError::NoRewardTokenQuantityInR8)?
133-
.try_extract_into::<i32>()? as u32;
133+
.try_extract_into::<i64>()? as u32;
134134

135135
if register_reward_token_quantity != *reward_token_quantity {
136136
warn!("Reward token quantity in R8 register differs to config. Could be due to vote.");

core/src/box_kind/update_box.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,35 @@ use thiserror::Error;
1616

1717
use crate::contracts::update::UpdateContract;
1818
use crate::contracts::update::UpdateContractError;
19+
use crate::contracts::update::UpdateContractParameters;
1920

2021
#[derive(Debug, Error)]
2122
pub enum UpdateBoxError {
2223
#[error("oracle box: no tokens found")]
2324
NoTokens,
2425
#[error("update contract: {0:?}")]
2526
UpdateContractError(#[from] UpdateContractError),
27+
#[error("update contract: {0:?}")]
28+
IncorrectUpdateTokenId(TokenId),
2629
}
2730

2831
#[derive(Clone)]
2932
pub struct UpdateBoxWrapper(ErgoBox, UpdateContract);
3033

3134
impl UpdateBoxWrapper {
32-
pub fn new(b: ErgoBox) -> Result<Self, UpdateBoxError> {
33-
let _update_token_id = b
35+
pub fn new(b: ErgoBox, inputs: UpdateBoxWrapperInputs) -> Result<Self, UpdateBoxError> {
36+
let update_token_id = b
3437
.tokens
3538
.as_ref()
3639
.ok_or(UpdateBoxError::NoTokens)?
3740
.get(0)
3841
.ok_or(UpdateBoxError::NoTokens)?
3942
.token_id
4043
.clone();
41-
let contract = UpdateContract::from_ergo_tree(b.ergo_tree.clone())?;
44+
if update_token_id != *inputs.update_nft_token_id {
45+
return Err(UpdateBoxError::IncorrectUpdateTokenId(update_token_id));
46+
}
47+
let contract = UpdateContract::from_ergo_tree(b.ergo_tree.clone(), inputs.into())?;
4248

4349
Ok(Self(b, contract))
4450
}
@@ -59,12 +65,12 @@ impl UpdateBoxWrapper {
5965
}
6066
}
6167

62-
impl TryFrom<ErgoBox> for UpdateBoxWrapper {
63-
type Error = UpdateBoxError;
64-
65-
fn try_from(value: ErgoBox) -> Result<Self, Self::Error> {
66-
UpdateBoxWrapper::new(value)
67-
}
68+
#[derive(Debug, Copy, Clone)]
69+
pub struct UpdateBoxWrapperInputs<'a> {
70+
pub contract_parameters: &'a UpdateContractParameters,
71+
pub update_nft_token_id: &'a TokenId,
72+
pub ballot_token_id: &'a TokenId,
73+
pub pool_nft_token_id: &'a TokenId,
6874
}
6975

7076
impl From<UpdateBoxWrapper> for ErgoBox {

core/src/cli_commands/update_pool.rs

Lines changed: 109 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ use crate::{
2929
PoolBox, PoolBoxWrapper,
3030
},
3131
cli_commands::ergo_explorer_transaction_link,
32-
contracts::ballot::BallotContract,
3332
contracts::pool::PoolContract,
33+
contracts::{ballot::BallotContract, pool::PoolContractInputs},
3434
node_interface::{current_block_height, get_wallet_status, sign_and_submit_transaction},
3535
oracle_config::ORACLE_CONFIG,
3636
oracle_state::{
@@ -62,8 +62,10 @@ pub enum UpdatePoolError {
6262
Node(NodeError),
6363
#[error("No change address in node")]
6464
NoChangeAddressSetInNode,
65-
#[error("Update pool: address encoder error: {0}")]
65+
#[error("Update pool: address encoder error {0}")]
6666
AddressEncoderError(AddressEncoderError),
67+
#[error("Update pool: pool contract error {0}")]
68+
PoolContractError(crate::contracts::pool::PoolContractError),
6769
}
6870

6971
pub fn update_pool(
@@ -86,9 +88,12 @@ pub fn update_pool(
8688
let change_address =
8789
AddressEncoder::new(network_prefix).parse_address_from_str(&change_address_str)?;
8890

89-
let new_pool_contract = PoolContract::new()
90-
.with_update_nft_token_id(ORACLE_CONFIG.update_nft.clone())
91-
.with_refresh_nft_token_id(ORACLE_CONFIG.refresh_nft.clone());
91+
let pool_contract_inputs = PoolContractInputs::from((
92+
&ORACLE_CONFIG.pool_contract_parameters,
93+
&ORACLE_CONFIG.token_ids,
94+
));
95+
96+
let new_pool_contract = PoolContract::new(pool_contract_inputs)?;
9297
let new_pool_box_hash = blake2b256_hash(
9398
&new_pool_contract
9499
.ergo_tree()
@@ -206,7 +211,7 @@ fn build_update_pool_box_tx(
206211
let reward_tokens = new_reward_tokens.unwrap_or(old_pool_box.reward_token());
207212
// Find ballot boxes that are voting for the new pool hash
208213
let mut sorted_ballot_boxes = ballot_boxes.get_ballot_boxes()?;
209-
sorted_ballot_boxes.sort_by_key(|ballot_box| ballot_box.ballot_token().amount);
214+
sorted_ballot_boxes.sort_by_key(|ballot_box| ballot_box.ballot_token().amount); // TODO: sort by box value as well, incase some ballot boxes were incorrectly created below storage rent levels
210215

211216
let mut votes_cast = 0;
212217
let vote_ballot_boxes: Vec<BallotBoxWrapper> = ballot_boxes
@@ -308,7 +313,8 @@ fn build_update_pool_box_tx(
308313
NonMandatoryRegisterId::R4,
309314
(*ballot_box.ballot_token_owner().h).clone().into(),
310315
);
311-
outputs.push(ballot_box_candidate.build()?);
316+
let built = ballot_box_candidate.clone().build()?;
317+
outputs.push(ballot_box_candidate.build()?)
312318
}
313319

314320
let mut tx_builder = TxBuilder::new(
@@ -361,9 +367,15 @@ mod tests {
361367
use crate::{
362368
box_kind::{
363369
make_local_ballot_box_candidate, make_pool_box_candidate, BallotBox, BallotBoxWrapper,
364-
PoolBox, PoolBoxWrapper, UpdateBoxWrapper,
370+
PoolBox, PoolBoxWrapper, PoolBoxWrapperInputs, UpdateBoxWrapper,
371+
UpdateBoxWrapperInputs,
372+
},
373+
contracts::{
374+
ballot::{BallotContract, BallotContractInputs},
375+
pool::{PoolContract, PoolContractInputs},
376+
update::{UpdateContract, UpdateContractInputs, UpdateContractParameters},
365377
},
366-
contracts::{ballot::BallotContract, pool::PoolContract, update::UpdateContract},
378+
oracle_config::{BallotBoxWrapperParameters, TokenIds},
367379
pool_commands::test_utils::{
368380
find_input_boxes, make_wallet_unspent_box, BallotBoxMock, BallotBoxesMock, PoolBoxMock,
369381
UpdateBoxMock, WalletDataMock,
@@ -387,29 +399,40 @@ mod tests {
387399
let ctx = force_any_val::<ErgoStateContext>();
388400
let height = ctx.pre_header.height;
389401

390-
let ballot_token_id = force_any_tokenid();
391-
let pool_nft_token_id = force_any_tokenid();
392-
let update_nft_token_id = force_any_tokenid();
393-
let reward_token_id = force_any_tokenid();
402+
let token_ids = TokenIds {
403+
pool_nft_token_id: force_any_tokenid(),
404+
update_nft_token_id: force_any_tokenid(),
405+
refresh_nft_token_id: force_any_tokenid(),
406+
reward_token_id: force_any_tokenid(),
407+
oracle_token_id: force_any_tokenid(),
408+
ballot_token_id: force_any_tokenid(),
409+
};
394410
let reward_tokens = Token {
395-
token_id: reward_token_id,
411+
token_id: token_ids.reward_token_id.clone(),
396412
amount: 1500.try_into().unwrap(),
397413
};
398414
let new_reward_tokens = Token {
399415
token_id: force_any_tokenid(),
400-
amount: force_any_val(),
416+
amount: force_any_val()
401417
};
402-
let update_contract = UpdateContract::new()
403-
.with_min_votes(4)
404-
.with_pool_nft_token_id(pool_nft_token_id.clone())
405-
.with_ballot_token_id(ballot_token_id.clone());
418+
419+
let update_contract_parameters = UpdateContractParameters {
420+
min_votes: 6,
421+
..Default::default()
422+
};
423+
let update_contract_inputs = UpdateContractInputs {
424+
contract_parameters: &update_contract_parameters,
425+
pool_nft_token_id: &token_ids.pool_nft_token_id,
426+
ballot_token_id: &token_ids.ballot_token_id,
427+
};
428+
let update_contract = UpdateContract::new(update_contract_inputs).unwrap();
406429
let mut update_box_candidate = ErgoBoxCandidateBuilder::new(
407430
BoxValue::SAFE_USER_MIN,
408431
update_contract.ergo_tree(),
409432
height,
410433
);
411434
update_box_candidate.add_token(Token {
412-
token_id: update_nft_token_id.clone(),
435+
token_id: token_ids.update_nft_token_id.clone(),
413436
amount: 1.try_into().unwrap(),
414437
});
415438
let update_box = ErgoBox::from_box_candidate(
@@ -419,15 +442,17 @@ mod tests {
419442
)
420443
.unwrap();
421444

422-
let pool_contract = PoolContract::new()
423-
.with_refresh_nft_token_id(force_any_tokenid())
424-
.with_update_nft_token_id(update_nft_token_id.clone());
445+
let pool_contract_parameters = Default::default();
446+
let pool_contract_inputs =
447+
PoolContractInputs::from((&pool_contract_parameters, &token_ids));
448+
449+
let pool_contract = PoolContract::new(pool_contract_inputs).unwrap();
425450
let pool_box_candidate = make_pool_box_candidate(
426451
&pool_contract,
427452
0,
428453
0,
429454
Token {
430-
token_id: pool_nft_token_id.clone(),
455+
token_id: token_ids.pool_nft_token_id.clone(),
431456
amount: 1.try_into().unwrap(),
432457
},
433458
reward_tokens.clone(),
@@ -439,41 +464,69 @@ mod tests {
439464
ErgoBox::from_box_candidate(&pool_box_candidate, force_any_val::<TxId>(), 0).unwrap();
440465

441466
let new_refresh_token_id = force_any_tokenid();
442-
let new_pool_contract = PoolContract::new()
443-
.with_refresh_nft_token_id(new_refresh_token_id)
444-
.with_update_nft_token_id(update_nft_token_id.clone());
467+
let mut new_pool_contract_inputs = pool_contract_inputs.clone();
468+
new_pool_contract_inputs.refresh_nft_token_id = &new_refresh_token_id;
469+
let new_pool_contract = PoolContract::new(new_pool_contract_inputs).unwrap();
445470

446471
let pool_box_bytes = new_pool_contract
447472
.ergo_tree()
448473
.sigma_serialize_bytes()
449474
.unwrap();
450475
let pool_box_hash = blake2b256_hash(&pool_box_bytes);
451476

452-
let ballot_contract = BallotContract::new()
453-
.with_min_storage_rent(*BoxValue::SAFE_USER_MIN.as_u64())
454-
.with_update_nft_token_id(update_nft_token_id);
477+
let ballot_contract_parameters = Default::default();
478+
let ballot_contract_inputs = BallotContractInputs {
479+
contract_parameters: &ballot_contract_parameters,
480+
update_nft_token_id: &token_ids.update_nft_token_id,
481+
};
482+
let ballot_contract = BallotContract::new(ballot_contract_inputs).unwrap();
483+
455484
let mut ballot_boxes = vec![];
456485

457-
for _ in 0..5 {
486+
for _ in 0..6 {
458487
let secret = DlogProverInput::random();
488+
let ballot_box_parameters = BallotBoxWrapperParameters {
489+
contract_parameters: ballot_contract_parameters.clone(),
490+
vote_parameters: Some(crate::oracle_config::CastBallotBoxVoteParameters {
491+
pool_box_address_hash: base16::encode_lower(&pool_box_hash),
492+
reward_token_id: new_reward_tokens.token_id.clone(),
493+
reward_token_quantity: *new_reward_tokens.amount.as_u64() as u32,
494+
}),
495+
ballot_token_owner_address: AddressEncoder::new(
496+
ballot_contract_parameters.p2s.network(),
497+
)
498+
.address_to_str(
499+
&ergo_lib::ergotree_ir::chain::address::Address::P2Pk(secret.public_image()),
500+
),
501+
};
459502
let ballot_box_candidate = make_local_ballot_box_candidate(
460503
&ballot_contract,
461504
secret.public_image(),
462505
update_box.creation_height,
463506
Token {
464-
token_id: ballot_token_id.clone(),
507+
token_id: token_ids.ballot_token_id.clone(),
465508
amount: 1.try_into().unwrap(),
466509
},
467510
pool_box_hash.clone(),
468511
new_reward_tokens.clone(),
469-
BoxValue::SAFE_USER_MIN,
512+
ballot_contract.min_storage_rent().try_into().unwrap(),
470513
height,
471514
)
472515
.unwrap();
473516
let ballot_box =
474517
ErgoBox::from_box_candidate(&ballot_box_candidate, force_any_val::<TxId>(), 0)
475518
.unwrap();
476-
ballot_boxes.push(ballot_box.try_into().unwrap());
519+
ballot_boxes.push(
520+
BallotBoxWrapper::new(
521+
ballot_box,
522+
crate::box_kind::BallotBoxWrapperInputs {
523+
parameters: &ballot_box_parameters,
524+
ballot_token_id: &token_ids.ballot_token_id,
525+
update_nft_token_id: &token_ids.update_nft_token_id,
526+
},
527+
)
528+
.unwrap(),
529+
);
477530
}
478531
let ballot_boxes_mock = BallotBoxesMock { ballot_boxes };
479532

@@ -491,10 +544,29 @@ mod tests {
491544
};
492545
let wallet = Wallet::from_secrets(vec![secret.clone().into()]);
493546
let update_mock = UpdateBoxMock {
494-
update_box: UpdateBoxWrapper::try_from(update_box).unwrap(),
547+
update_box: UpdateBoxWrapper::new(
548+
update_box,
549+
UpdateBoxWrapperInputs {
550+
contract_parameters: &update_contract_parameters,
551+
update_nft_token_id: &token_ids.update_nft_token_id,
552+
ballot_token_id: &token_ids.ballot_token_id,
553+
pool_nft_token_id: &token_ids.pool_nft_token_id,
554+
},
555+
)
556+
.unwrap(),
495557
};
496558
let pool_mock = PoolBoxMock {
497-
pool_box: PoolBoxWrapper::try_from(pool_box).unwrap(),
559+
pool_box: PoolBoxWrapper::new(
560+
pool_box,
561+
PoolBoxWrapperInputs {
562+
contract_parameters: &pool_contract_parameters,
563+
pool_nft_token_id: &token_ids.pool_nft_token_id,
564+
reward_token_id: &token_ids.reward_token_id,
565+
refresh_nft_token_id: &token_ids.refresh_nft_token_id,
566+
update_nft_token_id: &token_ids.update_nft_token_id,
567+
},
568+
)
569+
.unwrap(),
498570
};
499571

500572
let change_address =
@@ -513,6 +585,7 @@ mod tests {
513585
change_address,
514586
)
515587
.unwrap();
588+
println!("{}", serde_json::to_string(&update_tx.spending_tx).unwrap());
516589

517590
wallet.sign_transaction(update_tx, &ctx, None).unwrap();
518591
}

core/src/contracts/pool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub enum PoolContractError {
3737
TryExtractFrom(TryExtractFromError),
3838
}
3939

40+
#[derive(Copy, Clone)]
4041
pub struct PoolContractInputs<'a> {
4142
pub contract_parameters: &'a PoolContractParameters,
4243
pub refresh_nft_token_id: &'a TokenId,

core/src/contracts/update.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use ergo_lib::ergotree_ir::serialization::SigmaParsingError;
99

1010
use thiserror::Error;
1111

12+
use crate::box_kind::UpdateBoxWrapperInputs;
13+
1214
#[derive(Clone)]
1315
pub struct UpdateContract {
1416
ergo_tree: ErgoTree,
@@ -47,6 +49,16 @@ pub struct UpdateContractInputs<'a> {
4749
pub ballot_token_id: &'a TokenId,
4850
}
4951

52+
impl<'a> From<UpdateBoxWrapperInputs<'a>> for UpdateContractInputs<'a> {
53+
fn from(wrapper_inputs: UpdateBoxWrapperInputs) -> UpdateContractInputs {
54+
UpdateContractInputs {
55+
contract_parameters: wrapper_inputs.contract_parameters,
56+
pool_nft_token_id: wrapper_inputs.pool_nft_token_id,
57+
ballot_token_id: wrapper_inputs.ballot_token_id,
58+
}
59+
}
60+
}
61+
5062
impl UpdateContract {
5163
pub fn new(inputs: UpdateContractInputs) -> Result<Self, UpdateContractError> {
5264
let ergo_tree = inputs
@@ -61,6 +73,10 @@ impl UpdateContract {
6173
.with_constant(
6274
inputs.contract_parameters.ballot_token_index,
6375
inputs.ballot_token_id.clone().into(),
76+
)?
77+
.with_constant(
78+
inputs.contract_parameters.min_votes_index,
79+
(inputs.contract_parameters.min_votes as i32).into(),
6480
)?;
6581
let contract = Self::from_ergo_tree(ergo_tree, inputs)?;
6682
Ok(contract)

core/src/oracle_config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
contracts::{
44
ballot::BallotContractParameters, oracle::OracleContractParameters,
55
pool::PoolContractParameters, refresh::RefreshContractParameters,
6+
update::UpdateContractParameters,
67
},
78
datapoint_source::{DataPointSource, ExternalScript, PredefinedDataPointSource},
89
};
@@ -32,8 +33,8 @@ pub struct OracleConfig {
3233
pub oracle_contract_parameters: OracleContractParameters,
3334
pub pool_contract_parameters: PoolContractParameters,
3435
pub refresh_contract_parameters: RefreshContractParameters,
36+
pub update_contract_parameters: UpdateContractParameters,
3537
pub ballot_parameters: BallotBoxWrapperParameters,
36-
// TODO: update_parameters (https://github.com/ergoplatform/oracle-core/issues/49)
3738
pub token_ids: TokenIds,
3839
pub addresses: Addresses,
3940
}

0 commit comments

Comments
 (0)