@@ -10,7 +10,6 @@ use bcr_common::core::NodeId;
1010use bcr_ebill_core:: application:: company:: Company ;
1111use bcr_ebill_core:: application:: contact:: Contact ;
1212use bcr_ebill_core:: application:: { ServiceTraitBounds , ValidationError } ;
13- use bcr_ebill_core:: protocol:: Country ;
1413use bcr_ebill_core:: protocol:: Date ;
1514use bcr_ebill_core:: protocol:: Email ;
1615use bcr_ebill_core:: protocol:: Identification ;
@@ -23,13 +22,14 @@ use bcr_ebill_core::protocol::blockchain::company::{
2322 CompanyAddSignatoryBlockData , CompanyBlock , CompanyBlockPlaintextWrapper , CompanyBlockchain ,
2423 CompanyCreateBlockData , CompanyRemoveSignatoryBlockData , CompanyUpdateBlockData , SignatoryType ,
2524} ;
26- use bcr_ebill_core:: protocol:: blockchain:: identity:: IdentityType ;
2725use bcr_ebill_core:: protocol:: blockchain:: identity:: {
2826 IdentityAddSignatoryBlockData , IdentityBlock , IdentityCreateCompanyBlockData ,
2927 IdentityRemoveSignatoryBlockData ,
3028} ;
29+ use bcr_ebill_core:: protocol:: blockchain:: identity:: { IdentityBlockchain , IdentityType } ;
3130use bcr_ebill_core:: protocol:: crypto:: { self , BcrKeys , DeriveKeypair } ;
3231use bcr_ebill_core:: protocol:: { City , ProtocolValidationError } ;
32+ use bcr_ebill_core:: protocol:: { Country , blockchain} ;
3333use bcr_ebill_core:: protocol:: { File , OptionalPostalAddress , PostalAddress } ;
3434use bcr_ebill_core:: protocol:: {
3535 PublicKey , SecretKey ,
@@ -246,6 +246,37 @@ impl CompanyService {
246246 debug ! ( "Company change" ) ;
247247 self . publish_contact ( company, keys) . await
248248 }
249+
250+ async fn validate_and_add_identity_block (
251+ & self ,
252+ chain : & mut IdentityBlockchain ,
253+ new_block : IdentityBlock ,
254+ ) -> Result < ( ) > {
255+ let try_add_block = chain. try_add_block ( new_block. clone ( ) ) ;
256+ if try_add_block && chain. is_chain_valid ( ) {
257+ self . identity_blockchain_store . add_block ( & new_block) . await ?;
258+ Ok ( ( ) )
259+ } else {
260+ Err ( Error :: Protocol ( blockchain:: Error :: BlockchainInvalid . into ( ) ) )
261+ }
262+ }
263+
264+ async fn validate_and_add_block (
265+ & self ,
266+ company_id : & NodeId ,
267+ chain : & mut CompanyBlockchain ,
268+ new_block : CompanyBlock ,
269+ ) -> Result < ( ) > {
270+ let try_add_block = chain. try_add_block ( new_block. clone ( ) ) ;
271+ if try_add_block && chain. is_chain_valid ( ) {
272+ self . company_blockchain_store
273+ . add_block ( company_id, & new_block)
274+ . await ?;
275+ Ok ( ( ) )
276+ } else {
277+ Err ( Error :: Protocol ( blockchain:: Error :: BlockchainInvalid . into ( ) ) )
278+ }
279+ }
249280}
250281
251282/// Derives a company contact encryption key, encrypts the contact data with it and returns the BCR metadata.
@@ -442,9 +473,10 @@ impl CompanyServiceApi for CompanyService {
442473 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
443474 let create_company_block = company_chain. get_first_block ( ) ;
444475
445- let previous_block = self . identity_blockchain_store . get_latest_block ( ) . await ?;
476+ let mut identity_chain = self . identity_blockchain_store . get_chain ( ) . await ?;
477+ let previous_block = identity_chain. get_latest_block ( ) ;
446478 let new_block = IdentityBlock :: create_block_for_create_company (
447- & previous_block,
479+ previous_block,
448480 & IdentityCreateCompanyBlockData {
449481 company_id : id. clone ( ) ,
450482 company_key : company_keys. get_private_key ( ) ,
@@ -464,11 +496,12 @@ impl CompanyServiceApi for CompanyService {
464496 . add_company_transport ( & company, & company_keys)
465497 . await ?;
466498
467- let company_chain = self . company_blockchain_store . get_chain ( & id) . await ?;
468499 self . populate_block ( & company, & company_chain, & company_keys, None )
469500 . await ?;
470501
471- self . identity_blockchain_store . add_block ( & new_block) . await ?;
502+ self . validate_and_add_identity_block ( & mut identity_chain, new_block. clone ( ) )
503+ . await ?;
504+
472505 self . transport_service
473506 . block_transport ( )
474507 . send_identity_chain_events ( IdentityChainEvent :: new (
@@ -660,10 +693,11 @@ impl CompanyServiceApi for CompanyService {
660693
661694 self . store . update ( id, & company) . await ?;
662695
663- let previous_block = self . company_blockchain_store . get_latest_block ( id) . await ?;
696+ let mut company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
697+ let previous_block = company_chain. get_latest_block ( ) ;
664698 let new_block = CompanyBlock :: create_block_for_update (
665699 id. to_owned ( ) ,
666- & previous_block,
700+ previous_block,
667701 & CompanyUpdateBlockData {
668702 name,
669703 email,
@@ -680,10 +714,8 @@ impl CompanyServiceApi for CompanyService {
680714 timestamp,
681715 )
682716 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
683- self . company_blockchain_store
684- . add_block ( id, & new_block)
717+ self . validate_and_add_block ( id, & mut company_chain, new_block. clone ( ) )
685718 . await ?;
686- let company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
687719 self . populate_block ( & company, & company_chain, & company_keys, None )
688720 . await ?;
689721
@@ -748,10 +780,11 @@ impl CompanyServiceApi for CompanyService {
748780 company. signatories . push ( signatory_node_id. clone ( ) ) ;
749781 self . store . update ( id, & company) . await ?;
750782
751- let previous_block = self . company_blockchain_store . get_latest_block ( id) . await ?;
783+ let mut company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
784+ let previous_block = company_chain. get_latest_block ( ) ;
752785 let new_block = CompanyBlock :: create_block_for_add_signatory (
753786 id. to_owned ( ) ,
754- & previous_block,
787+ previous_block,
755788 & CompanyAddSignatoryBlockData {
756789 signatory : signatory_node_id. clone ( ) ,
757790 t : SignatoryType :: Solo ,
@@ -763,9 +796,10 @@ impl CompanyServiceApi for CompanyService {
763796 )
764797 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
765798
766- let previous_identity_block = self . identity_blockchain_store . get_latest_block ( ) . await ?;
799+ let mut identity_chain = self . identity_blockchain_store . get_chain ( ) . await ?;
800+ let previous_identity_block = identity_chain. get_latest_block ( ) ;
767801 let new_identity_block = IdentityBlock :: create_block_for_add_signatory (
768- & previous_identity_block,
802+ previous_identity_block,
769803 & IdentityAddSignatoryBlockData {
770804 company_id : id. to_owned ( ) ,
771805 block_hash : new_block. hash . clone ( ) ,
@@ -776,10 +810,8 @@ impl CompanyServiceApi for CompanyService {
776810 timestamp,
777811 )
778812 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
779- self . company_blockchain_store
780- . add_block ( id, & new_block)
813+ self . validate_and_add_block ( id, & mut company_chain, new_block. clone ( ) )
781814 . await ?;
782- let company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
783815 self . populate_block (
784816 & company,
785817 & company_chain,
@@ -788,8 +820,7 @@ impl CompanyServiceApi for CompanyService {
788820 )
789821 . await ?;
790822
791- self . identity_blockchain_store
792- . add_block ( & new_identity_block)
823+ self . validate_and_add_identity_block ( & mut identity_chain, new_identity_block. clone ( ) )
793824 . await ?;
794825 self . transport_service
795826 . block_transport ( )
@@ -855,10 +886,11 @@ impl CompanyServiceApi for CompanyService {
855886 self . store . remove ( id) . await ?;
856887 }
857888
858- let previous_block = self . company_blockchain_store . get_latest_block ( id) . await ?;
889+ let mut company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
890+ let previous_block = company_chain. get_latest_block ( ) ;
859891 let new_block = CompanyBlock :: create_block_for_remove_signatory (
860892 id. to_owned ( ) ,
861- & previous_block,
893+ previous_block,
862894 & CompanyRemoveSignatoryBlockData {
863895 signatory : signatory_node_id. clone ( ) ,
864896 } ,
@@ -868,9 +900,10 @@ impl CompanyServiceApi for CompanyService {
868900 )
869901 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
870902
871- let previous_identity_block = self . identity_blockchain_store . get_latest_block ( ) . await ?;
903+ let mut identity_chain = self . identity_blockchain_store . get_chain ( ) . await ?;
904+ let previous_identity_block = identity_chain. get_latest_block ( ) ;
872905 let new_identity_block = IdentityBlock :: create_block_for_remove_signatory (
873- & previous_identity_block,
906+ previous_identity_block,
874907 & IdentityRemoveSignatoryBlockData {
875908 company_id : id. to_owned ( ) ,
876909 block_hash : new_block. hash . clone ( ) ,
@@ -882,15 +915,12 @@ impl CompanyServiceApi for CompanyService {
882915 )
883916 . map_err ( |e| Error :: Protocol ( e. into ( ) ) ) ?;
884917
885- self . company_blockchain_store
886- . add_block ( id, & new_block)
918+ self . validate_and_add_block ( id, & mut company_chain, new_block. clone ( ) )
887919 . await ?;
888- let company_chain = self . company_blockchain_store . get_chain ( id) . await ?;
889920 self . populate_block ( & company, & company_chain, & company_keys, None )
890921 . await ?;
891922
892- self . identity_blockchain_store
893- . add_block ( & new_identity_block)
923+ self . validate_and_add_identity_block ( & mut identity_chain, new_identity_block. clone ( ) )
894924 . await ?;
895925 self . transport_service
896926 . block_transport ( )
@@ -1134,6 +1164,15 @@ pub mod tests {
11341164 . unwrap ( )
11351165 }
11361166
1167+ fn get_valid_identity_chain ( ) -> IdentityBlockchain {
1168+ IdentityBlockchain :: new (
1169+ & empty_identity ( ) . into ( ) ,
1170+ & BcrKeys :: new ( ) ,
1171+ Timestamp :: new ( 1731593928 ) . unwrap ( ) ,
1172+ )
1173+ . unwrap ( )
1174+ }
1175+
11371176 #[ tokio:: test]
11381177 async fn get_list_of_companies_baseline ( ) {
11391178 let (
@@ -1348,18 +1387,8 @@ pub mod tests {
13481387 . expect_remove_temp_upload_folder ( )
13491388 . returning ( |_| Ok ( ( ) ) ) ;
13501389 identity_chain_store
1351- . expect_get_latest_block ( )
1352- . returning ( || {
1353- let identity = empty_identity ( ) ;
1354- Ok ( IdentityBlockchain :: new (
1355- & identity. into ( ) ,
1356- & BcrKeys :: new ( ) ,
1357- Timestamp :: new ( 1731593928 ) . unwrap ( ) ,
1358- )
1359- . unwrap ( )
1360- . get_latest_block ( )
1361- . clone ( ) )
1362- } ) ;
1390+ . expect_get_chain ( )
1391+ . returning ( || Ok ( get_valid_identity_chain ( ) ) ) ;
13631392 identity_chain_store
13641393 . expect_add_block ( )
13651394 . returning ( |_| Ok ( ( ) ) ) ;
@@ -1385,11 +1414,6 @@ pub mod tests {
13851414 t. expect_ensure_nostr_contact ( ) . returning ( |_| ( ) ) . once ( ) ;
13861415 } ) ;
13871416
1388- company_chain_store
1389- . expect_get_chain ( )
1390- . returning ( |_| Ok ( get_valid_company_chain ( ) ) )
1391- . once ( ) ;
1392-
13931417 let service = get_service (
13941418 storage,
13951419 file_upload_store,
@@ -1824,18 +1848,8 @@ pub mod tests {
18241848 } )
18251849 } ) ;
18261850 identity_chain_store
1827- . expect_get_latest_block ( )
1828- . returning ( || {
1829- let identity = empty_identity ( ) ;
1830- Ok ( IdentityBlockchain :: new (
1831- & identity. into ( ) ,
1832- & BcrKeys :: new ( ) ,
1833- Timestamp :: new ( 1731593928 ) . unwrap ( ) ,
1834- )
1835- . unwrap ( )
1836- . get_latest_block ( )
1837- . clone ( ) )
1838- } ) ;
1851+ . expect_get_chain ( )
1852+ . returning ( || Ok ( get_valid_identity_chain ( ) ) ) ;
18391853 identity_chain_store
18401854 . expect_add_block ( )
18411855 . returning ( |_| Ok ( ( ) ) ) ;
@@ -2153,18 +2167,8 @@ pub mod tests {
21532167 } ) ;
21542168 storage. expect_update ( ) . returning ( |_, _| Ok ( ( ) ) ) ;
21552169 identity_chain_store
2156- . expect_get_latest_block ( )
2157- . returning ( || {
2158- let identity = empty_identity ( ) ;
2159- Ok ( IdentityBlockchain :: new (
2160- & identity. into ( ) ,
2161- & BcrKeys :: new ( ) ,
2162- Timestamp :: new ( 1731593928 ) . unwrap ( ) ,
2163- )
2164- . unwrap ( )
2165- . get_latest_block ( )
2166- . clone ( ) )
2167- } ) ;
2170+ . expect_get_chain ( )
2171+ . returning ( || Ok ( get_valid_identity_chain ( ) ) ) ;
21682172 identity_chain_store
21692173 . expect_add_block ( )
21702174 . returning ( |_| Ok ( ( ) ) ) ;
@@ -2311,20 +2315,9 @@ pub mod tests {
23112315 } ) ;
23122316 storage. expect_update ( ) . returning ( |_, _| Ok ( ( ) ) ) ;
23132317 storage. expect_remove ( ) . returning ( |_| Ok ( ( ) ) ) ;
2314- let keys_clone2 = keys. clone ( ) ;
23152318 identity_chain_store
2316- . expect_get_latest_block ( )
2317- . returning ( move || {
2318- let identity = empty_identity ( ) ;
2319- Ok ( IdentityBlockchain :: new (
2320- & identity. into ( ) ,
2321- & keys_clone2,
2322- Timestamp :: new ( 1731593928 ) . unwrap ( ) ,
2323- )
2324- . unwrap ( )
2325- . get_latest_block ( )
2326- . clone ( ) )
2327- } ) ;
2319+ . expect_get_chain ( )
2320+ . returning ( || Ok ( get_valid_identity_chain ( ) ) ) ;
23282321 identity_chain_store
23292322 . expect_add_block ( )
23302323 . returning ( |_| Ok ( ( ) ) ) ;
0 commit comments