@@ -94,8 +94,10 @@ pub enum Error {
94
94
Ledger ( #[ from] nomos_ledger:: LedgerError < HeaderId > ) ,
95
95
#[ error( "Consensus error: {0}" ) ]
96
96
Consensus ( #[ from] cryptarchia_engine:: Error < HeaderId > ) ,
97
- #[ error( "Proposal error: {0}" ) ]
98
- Proposal ( String ) ,
97
+ #[ error( "Serialization error: {0}" ) ]
98
+ Serialisation ( #[ from] nomos_core:: codec:: Error ) ,
99
+ #[ error( "Invalid block: {0}" ) ]
100
+ InvalidBlock ( String ) ,
99
101
#[ error( "Storage error: {0}" ) ]
100
102
Storage ( String ) ,
101
103
}
@@ -781,31 +783,47 @@ where
781
783
}
782
784
}
783
785
784
- // TODO: we maybe can keep existing orphan downloading logic but convert Block to Proposal
785
786
Some ( block) = orphan_downloader. next( ) , if orphan_downloader. should_poll( ) => {
786
- let header_id= block. header( ) . id( ) ;
787
+ let header_id = block. header( ) . id( ) ;
787
788
info!( "Processing block from orphan downloader: {header_id:?}" ) ;
788
789
789
790
if cryptarchia. has_block( & block. header( ) . id( ) ) {
790
791
continue ;
791
792
}
792
793
793
- match Self :: process_block_and_update_state(
794
- cryptarchia. clone( ) ,
795
- & leader,
796
- block. clone( ) ,
797
- & storage_blocks_to_remove,
798
- & relays,
799
- & self . service_resources_handle. state_updater
800
- ) . await {
801
- Ok ( ( new_cryptarchia, new_storage_blocks_to_remove) ) => {
802
- cryptarchia = new_cryptarchia;
803
- storage_blocks_to_remove = new_storage_blocks_to_remove;
794
+ match block. validate( ) {
795
+ Ok ( ( ) ) => {
796
+ Self :: log_received_block( & block) ;
804
797
805
- info!( counter. consensus_processed_blocks = 1 ) ;
798
+ match Self :: process_block_and_update_state(
799
+ cryptarchia. clone( ) ,
800
+ & leader,
801
+ block,
802
+ & storage_blocks_to_remove,
803
+ & relays,
804
+ & self . service_resources_handle. state_updater
805
+ ) . await {
806
+ Ok ( ( new_cryptarchia, new_storage_blocks_to_remove) ) => {
807
+ cryptarchia = new_cryptarchia;
808
+ storage_blocks_to_remove = new_storage_blocks_to_remove;
809
+
810
+ orphan_downloader. remove_orphan( & header_id) ;
811
+ info!( counter. consensus_processed_blocks = 1 ) ;
812
+ }
813
+ Err ( Error :: Ledger ( nomos_ledger:: LedgerError :: ParentNotFound ( parent) )
814
+ | Error :: Consensus ( cryptarchia_engine:: Error :: ParentMissing ( parent) ) ) => {
815
+
816
+ orphan_downloader. enqueue_orphan( header_id, cryptarchia. tip( ) , cryptarchia. lib( ) ) ;
817
+ error!( target: LOG_TARGET , "Orphan block with parent {:?} not in ledger state" , parent) ;
818
+ }
819
+ Err ( e) => {
820
+ error!( target: LOG_TARGET , "Error processing orphan block: {e:?}" ) ;
821
+ orphan_downloader. cancel_active_download( ) ;
822
+ }
823
+ }
806
824
}
807
825
Err ( e) => {
808
- error!( target: LOG_TARGET , "Error processing orphan downloader block: {e:?}" ) ;
826
+ error!( target: LOG_TARGET , "Failed to validate orphan block: {e:?}" ) ;
809
827
orphan_downloader. cancel_active_download( ) ;
810
828
}
811
829
}
@@ -1157,7 +1175,15 @@ where
1157
1175
. collect :: < Vec < _ > > ( ) ;
1158
1176
let content_id = [ 0 ; 32 ] . into ( ) ; // TODO: calculate the actual content id
1159
1177
// TODO: this should probably be a proposal or be transformed into a proposal
1160
- let block = Block :: new ( Header :: new ( parent, content_id, slot, proof) , txs) ;
1178
+ // TODO: Use correct derived one time key
1179
+ let dummy_signing_key = SigningKey :: from_bytes ( & [ 1u8 ; 32 ] ) ;
1180
+ let header = Header :: new ( parent, content_id, slot, proof) ;
1181
+
1182
+ let Ok ( signature) = header. sign ( & dummy_signing_key) else {
1183
+ error ! ( "Failed to sign header during block proposal" ) ;
1184
+ return None ;
1185
+ } ;
1186
+ let block = Block :: new ( header, txs, None , signature) ;
1161
1187
debug ! ( "proposed block with id {:?}" , block. header( ) . id( ) ) ;
1162
1188
output = Some ( block) ;
1163
1189
}
@@ -1599,10 +1625,10 @@ where
1599
1625
BlendService :: BroadcastSettings : Clone + Sync ,
1600
1626
{
1601
1627
// TODO: Use correct derived one time key
1602
- let signing_key = SigningKey :: generate ( & mut rand:: thread_rng ( ) ) ;
1628
+ let signing_key = SigningKey :: from_bytes ( & rand:: random :: < [ u8 ; 32 ] > ( ) ) ;
1603
1629
let proposal = block
1604
1630
. to_proposal ( & signing_key)
1605
- . map_err ( |e| Error :: Proposal ( format ! ( "Failed to create proposal from block: {e}" ) ) ) ?;
1631
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Failed to create proposal from block: {e}" ) ) ) ?;
1606
1632
1607
1633
blend_adapter. publish_proposal ( proposal) . await ;
1608
1634
@@ -1618,22 +1644,6 @@ where
1618
1644
Payload : Send ,
1619
1645
Item : Clone + Transaction < Hash = TxHash > + Send ,
1620
1646
{
1621
- if !proposal. header ( ) . is_valid_bedrock_version ( ) {
1622
- return Err ( Error :: Proposal ( format ! (
1623
- "Invalid header version: expected all fields = 0x01, got {:?}" ,
1624
- proposal. header( ) . version( )
1625
- ) ) ) ;
1626
- }
1627
-
1628
- if proposal. references ( ) . mempool_transactions . len ( ) > 1024 {
1629
- return Err ( Error :: Proposal (
1630
- "Too many transaction references (max 1024)" . into ( ) ,
1631
- ) ) ;
1632
- }
1633
-
1634
- // TODO: the rest of validations should probably go to
1635
- // process_block_and_update_state
1636
-
1637
1647
let needed_hashes: Vec < TxHash > = proposal
1638
1648
. references ( )
1639
1649
. mempool_transactions
@@ -1643,7 +1653,7 @@ where
1643
1653
1644
1654
let reconstructed_transactions = get_transactions_by_hashes ( mempool, needed_hashes. clone ( ) )
1645
1655
. await
1646
- . map_err ( |e| Error :: Proposal ( format ! ( "Failed to get transactions by hashes: {e}" ) ) ) ?;
1656
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Failed to get transactions by hashes: {e}" ) ) ) ?;
1647
1657
1648
1658
if reconstructed_transactions. len ( ) != needed_hashes. len ( ) {
1649
1659
let missing_transactions: Vec < TxHash > = needed_hashes
@@ -1655,18 +1665,26 @@ where
1655
1665
} )
1656
1666
. collect ( ) ;
1657
1667
1658
- return Err ( Error :: Proposal ( format ! (
1668
+ return Err ( Error :: InvalidBlock ( format ! (
1659
1669
"Failed to reconstruct block: {missing_transactions:?} transactions not found in mempool" ,
1660
1670
) ) ) ;
1661
1671
}
1662
1672
1663
1673
let header = proposal. header ( ) . clone ( ) ;
1664
1674
let service_reward = proposal. references ( ) . service_reward ;
1665
-
1666
- Ok ( match service_reward {
1667
- Some ( reward) => Block :: new_with_service_reward ( header, reconstructed_transactions, reward) ,
1668
- None => Block :: new ( header, reconstructed_transactions) ,
1669
- } )
1675
+ let signature = * proposal. signature ( ) ;
1676
+
1677
+ let block = Block :: new (
1678
+ header,
1679
+ reconstructed_transactions,
1680
+ service_reward,
1681
+ signature,
1682
+ ) ;
1683
+ block
1684
+ . validate ( )
1685
+ . map_err ( |e| Error :: InvalidBlock ( format ! ( "Reconstructed block is invalid: {e}" ) ) ) ?;
1686
+
1687
+ Ok ( block)
1670
1688
}
1671
1689
1672
1690
async fn broadcast_finalized_block (
0 commit comments