@@ -92,8 +92,10 @@ pub enum Error {
92
92
Ledger ( #[ from] nomos_ledger:: LedgerError < HeaderId > ) ,
93
93
#[ error( "Consensus error: {0}" ) ]
94
94
Consensus ( #[ from] cryptarchia_engine:: Error < HeaderId > ) ,
95
- #[ error( "Proposal error: {0}" ) ]
96
- Proposal ( String ) ,
95
+ #[ error( "Serialization error: {0}" ) ]
96
+ Serialisation ( #[ from] nomos_core:: wire:: Error ) ,
97
+ #[ error( "Invalid block: {0}" ) ]
98
+ InvalidBlock ( String ) ,
97
99
#[ error( "Storage error: {0}" ) ]
98
100
Storage ( String ) ,
99
101
}
@@ -764,32 +766,48 @@ where
764
766
}
765
767
}
766
768
767
- // TODO: we maybe can keep existing orphan downloading logic but convert Block to Proposal
768
769
Some ( block) = orphan_downloader. next( ) , if orphan_downloader. should_poll( ) => {
769
- let header_id= block. header( ) . id( ) ;
770
+ let header_id = block. header( ) . id( ) ;
770
771
info!( "Processing block from orphan downloader: {header_id:?}" ) ;
771
772
772
773
if cryptarchia. has_block( & block. header( ) . id( ) ) {
773
774
continue ;
774
775
}
775
776
776
- match Self :: process_block_and_update_state(
777
- cryptarchia. clone( ) ,
778
- & leader,
779
- block. clone( ) ,
780
- & storage_blocks_to_remove,
781
- & relays,
782
- & self . block_subscription_sender,
783
- & self . service_resources_handle. state_updater
784
- ) . await {
785
- Ok ( ( new_cryptarchia, new_storage_blocks_to_remove) ) => {
786
- cryptarchia = new_cryptarchia;
787
- storage_blocks_to_remove = new_storage_blocks_to_remove;
777
+ match block. validate( ) {
778
+ Ok ( ( ) ) => {
779
+ Self :: log_received_block( & block) ;
780
+
781
+ match Self :: process_block_and_update_state(
782
+ cryptarchia. clone( ) ,
783
+ & leader,
784
+ block,
785
+ & storage_blocks_to_remove,
786
+ & relays,
787
+ & self . block_subscription_sender,
788
+ & self . service_resources_handle. state_updater
789
+ ) . await {
790
+ Ok ( ( new_cryptarchia, new_storage_blocks_to_remove) ) => {
791
+ cryptarchia = new_cryptarchia;
792
+ storage_blocks_to_remove = new_storage_blocks_to_remove;
793
+
794
+ orphan_downloader. remove_orphan( & header_id) ;
795
+ info!( counter. consensus_processed_blocks = 1 ) ;
796
+ }
797
+ Err ( Error :: Ledger ( nomos_ledger:: LedgerError :: ParentNotFound ( parent) )
798
+ | Error :: Consensus ( cryptarchia_engine:: Error :: ParentMissing ( parent) ) ) => {
788
799
789
- info!( counter. consensus_processed_blocks = 1 ) ;
800
+ orphan_downloader. enqueue_orphan( header_id, cryptarchia. tip( ) , cryptarchia. lib( ) ) ;
801
+ error!( target: LOG_TARGET , "Orphan block with parent {:?} not in ledger state" , parent) ;
802
+ }
803
+ Err ( e) => {
804
+ error!( target: LOG_TARGET , "Error processing orphan block: {e:?}" ) ;
805
+ orphan_downloader. cancel_active_download( ) ;
806
+ }
807
+ }
790
808
}
791
809
Err ( e) => {
792
- error!( target: LOG_TARGET , "Error processing orphan downloader block: {e:?}" ) ;
810
+ error!( target: LOG_TARGET , "Failed to validate orphan block: {e:?}" ) ;
793
811
orphan_downloader. cancel_active_download( ) ;
794
812
}
795
813
}
@@ -1139,7 +1157,15 @@ where
1139
1157
. collect :: < Vec < _ > > ( ) ;
1140
1158
let content_id = [ 0 ; 32 ] . into ( ) ; // TODO: calculate the actual content id
1141
1159
// TODO: this should probably be a proposal or be transformed into a proposal
1142
- let block = Block :: new ( Header :: new ( parent, content_id, slot, proof) , txs) ;
1160
+ // TODO: Use correct derived one time key
1161
+ let dummy_signing_key = SigningKey :: from_bytes ( & [ 1u8 ; 32 ] ) ;
1162
+ let header = Header :: new ( parent, content_id, slot, proof) ;
1163
+
1164
+ let Ok ( signature) = header. sign ( & dummy_signing_key) else {
1165
+ error ! ( "Failed to sign header during block proposal" ) ;
1166
+ return None ;
1167
+ } ;
1168
+ let block = Block :: new ( header, txs, None , signature) ;
1143
1169
debug ! ( "proposed block with id {:?}" , block. header( ) . id( ) ) ;
1144
1170
output = Some ( block) ;
1145
1171
}
@@ -1615,10 +1641,10 @@ where
1615
1641
BlendService :: BroadcastSettings : Clone + Sync ,
1616
1642
{
1617
1643
// TODO: Use correct derived one time key
1618
- let signing_key = SigningKey :: generate ( & mut rand:: thread_rng ( ) ) ;
1644
+ let signing_key = SigningKey :: from_bytes ( & rand:: random :: < [ u8 ; 32 ] > ( ) ) ;
1619
1645
let proposal = block
1620
1646
. to_proposal ( & signing_key)
1621
- . map_err ( |e| Error :: Proposal ( format ! ( "Failed to create proposal from block: {e}" ) ) ) ?;
1647
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Failed to create proposal from block: {e}" ) ) ) ?;
1622
1648
1623
1649
blend_adapter. publish_proposal ( proposal) . await ;
1624
1650
@@ -1634,22 +1660,6 @@ where
1634
1660
Payload : Send ,
1635
1661
Item : Clone + Transaction < Hash = TxHash > + Send ,
1636
1662
{
1637
- if !proposal. header ( ) . is_valid_bedrock_version ( ) {
1638
- return Err ( Error :: Proposal ( format ! (
1639
- "Invalid header version: expected all fields = 0x01, got {:?}" ,
1640
- proposal. header( ) . version( )
1641
- ) ) ) ;
1642
- }
1643
-
1644
- if proposal. references ( ) . mempool_transactions . len ( ) > 1024 {
1645
- return Err ( Error :: Proposal (
1646
- "Too many transaction references (max 1024)" . into ( ) ,
1647
- ) ) ;
1648
- }
1649
-
1650
- // TODO: the rest of validations should probably go to
1651
- // process_block_and_update_state
1652
-
1653
1663
let needed_hashes: Vec < TxHash > = proposal
1654
1664
. references ( )
1655
1665
. mempool_transactions
@@ -1659,7 +1669,7 @@ where
1659
1669
1660
1670
let reconstructed_transactions = get_transactions_by_hashes ( mempool, needed_hashes. clone ( ) )
1661
1671
. await
1662
- . map_err ( |e| Error :: Proposal ( format ! ( "Failed to get transactions by hashes: {e}" ) ) ) ?;
1672
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Failed to get transactions by hashes: {e}" ) ) ) ?;
1663
1673
1664
1674
if reconstructed_transactions. len ( ) != needed_hashes. len ( ) {
1665
1675
let missing_transactions: Vec < TxHash > = needed_hashes
@@ -1671,18 +1681,26 @@ where
1671
1681
} )
1672
1682
. collect ( ) ;
1673
1683
1674
- return Err ( Error :: Proposal ( format ! (
1684
+ return Err ( Error :: InvalidBlock ( format ! (
1675
1685
"Failed to reconstruct block: {missing_transactions:?} transactions not found in mempool" ,
1676
1686
) ) ) ;
1677
1687
}
1678
1688
1679
1689
let header = proposal. header ( ) . clone ( ) ;
1680
1690
let service_reward = proposal. references ( ) . service_reward ;
1681
-
1682
- Ok ( match service_reward {
1683
- Some ( reward) => Block :: new_with_service_reward ( header, reconstructed_transactions, reward) ,
1684
- None => Block :: new ( header, reconstructed_transactions) ,
1685
- } )
1691
+ let signature = * proposal. signature ( ) ;
1692
+
1693
+ let block = Block :: new (
1694
+ header,
1695
+ reconstructed_transactions,
1696
+ service_reward,
1697
+ signature,
1698
+ ) ;
1699
+ block
1700
+ . validate ( )
1701
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Reconstructed block is invalid: {e}" ) ) ) ?;
1702
+
1703
+ Ok ( block)
1686
1704
}
1687
1705
1688
1706
#[ cfg( test) ]
0 commit comments