Skip to content

Commit 354046b

Browse files
authored
Add incoming block bill and chain action validation (#461)
* add incoming block bill action validation, add recourse reason to block data, add incoming chain validation * review fixes
1 parent 58d81ba commit 354046b

File tree

12 files changed

+640
-250
lines changed

12 files changed

+640
-250
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# 0.3.3
2+
3+
* Add block data validation
4+
* Add bill action validation for incoming blocks
5+
* Add signer verification for incoming blocks
6+
* Add recourse reason to `RequestRecourse` block data
7+
* (breaks existing persisted bills, if they had a request recourse block)
8+
* Move bill validation logic to `bcr-ebill-core`
9+
110
# 0.3.2
211

312
* Fixed `request_to_accept` calling the correct action

crates/bcr-ebill-api/src/service/bill_service/blocks.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use bcr_ebill_core::{
77
BillBlock, BillBlockchain,
88
block::{
99
BillAcceptBlockData, BillEndorseBlockData, BillMintBlockData,
10-
BillOfferToSellBlockData, BillRecourseBlockData, BillRejectBlockData,
11-
BillRequestRecourseBlockData, BillRequestToAcceptBlockData,
10+
BillOfferToSellBlockData, BillRecourseBlockData, BillRecourseReasonBlockData,
11+
BillRejectBlockData, BillRequestRecourseBlockData, BillRequestToAcceptBlockData,
1212
BillRequestToPayBlockData, BillSellBlockData,
1313
},
1414
},
@@ -98,15 +98,22 @@ impl BillService {
9898
)?
9999
}
100100
BillAction::RequestRecourse(recoursee, recourse_reason) => {
101-
let (sum, currency) = match *recourse_reason {
102-
RecourseReason::Accept => (bill.sum, bill.currency.clone()),
103-
RecourseReason::Pay(sum, ref currency) => (sum, currency.to_owned()),
101+
let (sum, currency, reason) = match *recourse_reason {
102+
RecourseReason::Accept => (
103+
bill.sum,
104+
bill.currency.clone(),
105+
BillRecourseReasonBlockData::Accept,
106+
),
107+
RecourseReason::Pay(sum, ref currency) => {
108+
(sum, currency.to_owned(), BillRecourseReasonBlockData::Pay)
109+
}
104110
};
105111
let block_data = BillRequestRecourseBlockData {
106112
recourser: signer_public_data.clone().into(),
107113
recoursee: recoursee.clone().into(),
108114
sum,
109115
currency: currency.to_owned(),
116+
recourse_reason: reason,
110117
signatory: signing_keys.signatory_identity,
111118
signing_timestamp: timestamp,
112119
signing_address: signer_public_data.postal_address.clone(),

crates/bcr-ebill-api/src/service/bill_service/data_fetching.rs

Lines changed: 6 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ use bcr_ebill_core::{
1616
Blockchain,
1717
bill::{
1818
BillBlockchain, BillOpCode, OfferToSellWaitingForPayment, RecourseWaitingForPayment,
19-
block::{
20-
BillEndorseBlockData, BillMintBlockData, BillSellBlockData, BillSignatoryBlockData,
21-
},
19+
block::BillSignatoryBlockData,
2220
},
2321
},
2422
constants::{ACCEPT_DEADLINE_SECONDS, PAYMENT_DEADLINE_SECONDS},
@@ -45,108 +43,27 @@ impl BillService {
4543
contacts: &HashMap<String, Contact>,
4644
) -> Result<BitcreditBill> {
4745
let bill_first_version = chain.get_first_version_bill(bill_keys)?;
46+
let bill_parties = chain.get_bill_parties(bill_keys, &bill_first_version)?;
4847

49-
// check endorsing blocks
50-
let last_version_block_endorse = if let Some(endorse_block_encrypted) =
51-
chain.get_last_version_block_with_op_code(BillOpCode::Endorse)
52-
{
53-
Some((
54-
endorse_block_encrypted
55-
.get_decrypted_block_bytes::<BillEndorseBlockData>(bill_keys)?,
56-
endorse_block_encrypted.id,
57-
))
58-
} else {
59-
None
60-
};
61-
let last_version_block_mint = if let Some(mint_block_encrypted) =
62-
chain.get_last_version_block_with_op_code(BillOpCode::Mint)
63-
{
64-
Some((
65-
mint_block_encrypted.get_decrypted_block_bytes::<BillMintBlockData>(bill_keys)?,
66-
mint_block_encrypted.id,
67-
))
68-
} else {
69-
None
70-
};
71-
let last_version_block_sell = if let Some(sell_block_encrypted) =
72-
chain.get_last_version_block_with_op_code(BillOpCode::Sell)
73-
{
74-
Some((
75-
sell_block_encrypted.get_decrypted_block_bytes::<BillSellBlockData>(bill_keys)?,
76-
sell_block_encrypted.id,
77-
))
78-
} else {
79-
None
80-
};
81-
82-
// If the last block is endorse, the endorsee is the holder
83-
// If the last block is mint, the mint is the holder
84-
// If the last block is sell, the buyer is the holder
85-
let last_endorsee = match (
86-
last_version_block_endorse,
87-
last_version_block_mint,
88-
last_version_block_sell,
89-
) {
90-
(None, None, None) => None,
91-
(Some((endorse_block, _)), None, None) => Some(endorse_block.endorsee),
92-
(None, Some((mint_block, _)), None) => Some(mint_block.endorsee),
93-
(None, None, Some((sell_block, _))) => Some(sell_block.buyer),
94-
(Some((endorse_block, endorse_block_id)), Some((mint_block, mint_block_id)), None) => {
95-
if endorse_block_id > mint_block_id {
96-
Some(endorse_block.endorsee)
97-
} else {
98-
Some(mint_block.endorsee)
99-
}
100-
}
101-
(Some((endorse_block, endorse_block_id)), None, Some((sell_block, sell_block_id))) => {
102-
if endorse_block_id > sell_block_id {
103-
Some(endorse_block.endorsee)
104-
} else {
105-
Some(sell_block.buyer)
106-
}
107-
}
108-
(None, Some((mint_block, mint_block_id)), Some((sell_block, sell_block_id))) => {
109-
if sell_block_id > mint_block_id {
110-
Some(sell_block.buyer)
111-
} else {
112-
Some(mint_block.endorsee)
113-
}
114-
}
115-
(
116-
Some((endorse_block, endorse_block_id)),
117-
Some((mint_block, mint_block_id)),
118-
Some((sell_block, sell_block_id)),
119-
) => {
120-
if endorse_block_id > mint_block_id && endorse_block_id > sell_block_id {
121-
Some(endorse_block.endorsee)
122-
} else if mint_block_id > sell_block_id {
123-
Some(mint_block.endorsee)
124-
} else {
125-
Some(sell_block.buyer)
126-
}
127-
}
128-
};
129-
130-
let payee = bill_first_version.payee;
131-
48+
let payee = bill_parties.payee;
13249
let drawee_contact = self
13350
.extend_bill_chain_identity_data_from_contacts_or_identity(
134-
bill_first_version.drawee,
51+
bill_parties.drawee,
13552
identity,
13653
contacts,
13754
)
13855
.await;
13956
let drawer_contact = self
14057
.extend_bill_chain_identity_data_from_contacts_or_identity(
141-
bill_first_version.drawer,
58+
bill_parties.drawer,
14259
identity,
14360
contacts,
14461
)
14562
.await;
14663
let payee_contact = self
14764
.extend_bill_chain_identity_data_from_contacts_or_identity(payee, identity, contacts)
14865
.await;
149-
let endorsee_contact = match last_endorsee {
66+
let endorsee_contact = match bill_parties.endorsee {
15067
Some(endorsee) => {
15168
let endorsee_contact = self
15269
.extend_bill_chain_identity_data_from_contacts_or_identity(

crates/bcr-ebill-api/src/service/bill_service/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ pub mod tests {
183183
BillBlock, BillOpCode,
184184
block::{
185185
BillEndorseBlockData, BillMintBlockData, BillOfferToSellBlockData,
186-
BillRejectBlockData, BillRequestRecourseBlockData,
186+
BillRecourseReasonBlockData, BillRejectBlockData, BillRequestRecourseBlockData,
187187
BillRequestToAcceptBlockData, BillRequestToPayBlockData, BillSellBlockData,
188188
BillSignatoryBlockData,
189189
},
@@ -3588,6 +3588,7 @@ pub mod tests {
35883588
.into(),
35893589
currency: "sat".to_string(),
35903590
sum: 15000,
3591+
recourse_reason: BillRecourseReasonBlockData::Pay,
35913592
signatory: None,
35923593
signing_timestamp: now,
35933594
signing_address: empty_address(),
@@ -3653,6 +3654,7 @@ pub mod tests {
36533654
recoursee: identity_public_data_only_node_id(recoursee.clone()).into(),
36543655
currency: "sat".to_string(),
36553656
sum: 15000,
3657+
recourse_reason: BillRecourseReasonBlockData::Pay,
36563658
signatory: None,
36573659
signing_timestamp: now,
36583660
signing_address: empty_address(),
@@ -3717,6 +3719,7 @@ pub mod tests {
37173719
recoursee: identity_public_data_only_node_id(recoursee.clone()).into(),
37183720
currency: "sat".to_string(),
37193721
sum: 15000,
3722+
recourse_reason: BillRecourseReasonBlockData::Pay,
37203723
signatory: Some(BillSignatoryBlockData {
37213724
node_id: get_baseline_identity().identity.node_id.clone(),
37223725
name: get_baseline_identity().identity.name.clone(),
@@ -3952,6 +3955,7 @@ pub mod tests {
39523955
recoursee: recoursee_clone.clone().into(),
39533956
sum: 15000,
39543957
currency: "sat".to_string(),
3958+
recourse_reason: BillRecourseReasonBlockData::Pay,
39553959
signatory: None,
39563960
signing_timestamp: 1731593927,
39573961
signing_address: empty_address(),

crates/bcr-ebill-api/src/service/bill_service/service.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,14 +562,16 @@ impl BillServiceApi for BillService {
562562
// validate
563563
validate_bill_action(
564564
&blockchain,
565-
&bill,
565+
&bill.drawee.node_id,
566+
&bill.payee.node_id,
567+
bill.endorsee.clone().map(|e| e.node_id).as_deref(),
568+
&bill.maturity_date,
566569
&bill_keys,
567570
timestamp,
568571
&signer_public_data.node_id,
569572
&bill_action,
570573
is_paid,
571-
)
572-
.await?;
574+
)?;
573575

574576
// create and sign blocks
575577
self.create_blocks_for_bill_action(

crates/bcr-ebill-api/src/service/bill_service/test_utils.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ use bcr_ebill_core::{
2727
BillBlock,
2828
block::{
2929
BillAcceptBlockData, BillIssueBlockData, BillOfferToSellBlockData,
30-
BillRecourseBlockData, BillRejectBlockData, BillRequestRecourseBlockData,
31-
BillRequestToAcceptBlockData, BillRequestToPayBlockData, BillSellBlockData,
30+
BillRecourseBlockData, BillRecourseReasonBlockData, BillRejectBlockData,
31+
BillRequestRecourseBlockData, BillRequestToAcceptBlockData,
32+
BillRequestToPayBlockData, BillSellBlockData,
3233
},
3334
},
3435
identity::IdentityBlockchain,
@@ -280,6 +281,7 @@ pub fn request_to_recourse_block(
280281
recoursee: recoursee.to_owned().into(),
281282
sum: 15000,
282283
currency: "sat".to_string(),
284+
recourse_reason: BillRecourseReasonBlockData::Pay,
283285
signatory: None,
284286
signing_timestamp: timestamp,
285287
signing_address: empty_address(),

0 commit comments

Comments
 (0)