@@ -17,6 +17,7 @@ const {
1717 PredefinedDbPaths,
1818 StateVersions,
1919 ValueChangedEventSources,
20+ TransactionStates,
2021} = require ( '../common/constants' ) ;
2122const { ConsensusErrorCode } = require ( '../common/result-code' ) ;
2223const {
@@ -600,7 +601,8 @@ class Consensus {
600601
601602 static validateAndExecuteLastVotes ( lastVotes , lastHash , number , blockTime , db , blockPool , eventSource ) {
602603 if ( number === 0 ) return ;
603- if ( ! db . executeTransactionList ( lastVotes , true , false , number , blockTime , eventSource ) ) {
604+ const txsRes = db . executeTransactionList ( lastVotes , true , false , number , blockTime , eventSource ) ;
605+ if ( ! txsRes ) {
604606 throw new ConsensusError ( {
605607 code : ConsensusErrorCode . EXECUTING_LAST_VOTES_FAILURE ,
606608 message : `Failed to execute last votes` ,
@@ -628,6 +630,7 @@ class Consensus {
628630 level : 'error'
629631 } ) ;
630632 }
633+ return txsRes ;
631634 }
632635
633636 // Cross-check the offenses in proposalTx & the evidence in proposalBlock
@@ -726,6 +729,7 @@ class Consensus {
726729 level : 'error'
727730 } ) ;
728731 }
732+ return txsRes ;
729733 }
730734
731735 static validateStateProofHash ( expectedStateProofHash , block , db , node , takeSnapshot ) {
@@ -774,16 +778,17 @@ class Consensus {
774778 } ) ;
775779 }
776780 // Try executing the proposal tx on the proposal block's db state
777- const proposalTxExecRes = tempDb . executeTransaction ( executableTx , true , false , number , blockTime ) ;
781+ const txRes = tempDb . executeTransaction ( executableTx , true , false , number , blockTime ) ;
778782 tempDb . destroyDb ( ) ;
779- if ( CommonUtil . isFailedTx ( proposalTxExecRes ) ) {
783+ if ( CommonUtil . isFailedTx ( txRes ) ) {
780784 throw new ConsensusError ( {
781785 code : ConsensusErrorCode . EXECUTING_PROPOSAL_FAILURE ,
782- message : `Failed to execute the proposal tx: ${ JSON . stringify ( proposalTxExecRes ) } ` ,
786+ message : `Failed to execute the proposal tx: ${ JSON . stringify ( txRes ) } ` ,
783787 level : 'error'
784788 } ) ;
785789 }
786790 node . tp . addTransaction ( executableTx ) ;
791+ return txRes ;
787792 }
788793
789794 static addBlockToBlockPool ( block , proposalTx , db , blockPool ) {
@@ -797,7 +802,54 @@ class Consensus {
797802 blockPool . addToHashToDbMap ( block . hash , db ) ;
798803 }
799804
800- static validateAndExecuteBlockOnDb ( rawBlock , node , stateVersionPrefix , proposalTx = null , takeSnapshot = false ) {
805+ static updateTransactionInfoForBlock ( node , voteTxs , proposalTx , transactions , voteTxsRes , proposalTxRes , txsRes ) {
806+ const trackedAt = Date . now ( ) ;
807+ for ( let i = 0 ; i < voteTxs . length ; i ++ ) {
808+ const voteTx = voteTxs [ i ] ;
809+ const voteResult = voteTxsRes [ i ] ;
810+ const tracked = node . tp . transactionTracker . get ( voteTx . hash ) || { } ;
811+ const beforeState = _ . get ( tracked , 'state' , null ) ;
812+ node . tp . updateTransactionInfo ( voteTx . hash , {
813+ state : TransactionStates . IN_BLOCK ,
814+ exec_result : voteResult ,
815+ tracked_at : trackedAt ,
816+ } ) ;
817+ if ( node . eh ) {
818+ node . eh . emitTxStateChanged ( voteTx , beforeState , TransactionStates . IN_BLOCK ) ;
819+ }
820+ }
821+ // NOTE(platfowner): Genesis block has no porposal transaction.
822+ if ( proposalTx ) {
823+ const trackedProposalTx = node . tp . transactionTracker . get ( proposalTx . hash ) || { } ;
824+ const beforeState = _ . get ( trackedProposalTx , 'state' , null ) ;
825+ node . tp . updateTransactionInfo ( proposalTx . hash , {
826+ state : TransactionStates . IN_BLOCK ,
827+ exec_result : proposalTxRes ,
828+ tracked_at : trackedAt ,
829+ } ) ;
830+ if ( node . eh ) {
831+ node . eh . emitTxStateChanged ( proposalTx , beforeState , TransactionStates . IN_BLOCK ) ;
832+ }
833+ }
834+ for ( let i = 0 ; i < transactions . length ; i ++ ) {
835+ const tx = transactions [ i ] ;
836+ const txResult = txsRes [ i ] ;
837+ const tracked = node . tp . transactionTracker . get ( tx . hash ) || { } ;
838+ const beforeState = _ . get ( tracked , 'state' , null ) ;
839+ const txState =
840+ CommonUtil . isFailedTx ( txResult ) ? TransactionStates . REVERTED : TransactionStates . IN_BLOCK ;
841+ node . tp . updateTransactionInfo ( tx . hash , {
842+ state : txState ,
843+ exec_result : txResult ,
844+ tracked_at : trackedAt ,
845+ } ) ;
846+ if ( node . eh ) {
847+ node . eh . emitTxStateChanged ( tx , beforeState , txState ) ;
848+ }
849+ }
850+ }
851+
852+ static validateAndExecuteBlockOnDb ( rawBlock , node , stateVersionPrefix , proposalTx , updateTxInfo , takeSnapshot = false ) {
801853 const block = Block . parse ( rawBlock ) ;
802854 if ( ! block ) {
803855 throw new ConsensusError ( {
@@ -822,23 +874,29 @@ class Consensus {
822874 node . bc . lastBlockNumber ( ) , node . stateManager . getFinalVersion ( ) , node . bp ) ;
823875 const db = Consensus . getNewDbForProposal ( number , baseVersion , stateVersionPrefix , node ) ;
824876
877+ let voteTxsRes = null ;
878+ let proposalTxRes = null ;
879+ let txsRes = null ;
825880 try {
826881 Consensus . validateBlockNumberAndHashes ( block , prevBlock , node . bc . genesisBlockHash ) ;
827882 Consensus . validateValidators ( validators , number , baseVersion , node ) ;
828883 Consensus . validateProposer ( number , prevBlockLastVotesHash , epoch , validators , proposer ) ;
829- Consensus . validateAndExecuteLastVotes ( last_votes , last_hash , number , timestamp , db , node . bp , ValueChangedEventSources . BLOCK ) ;
884+ voteTxsRes = Consensus . validateAndExecuteLastVotes ( last_votes , last_hash , number , timestamp , db , node . bp , ValueChangedEventSources . BLOCK ) ;
830885 Consensus . validateAndExecuteOffensesAndEvidence (
831886 evidence , validators , prevBlockMajority , number , timestamp , proposalTx , db , ValueChangedEventSources . BLOCK ) ;
832- Consensus . validateAndExecuteTransactions (
887+ txsRes = Consensus . validateAndExecuteTransactions (
833888 transactions , receipts , number , timestamp , gas_amount_total , gas_cost_total , db , node , ValueChangedEventSources . BLOCK ) ;
834889 db . applyBandagesForBlockNumber ( number ) ;
835890 Consensus . validateStateProofHash ( state_proof_hash , block , db , node , takeSnapshot ) ;
836- Consensus . executeProposalTx ( proposalTx , number , timestamp , db , node ) ;
891+ proposalTxRes = Consensus . executeProposalTx ( proposalTx , number , timestamp , db , node ) ;
837892 Consensus . addBlockToBlockPool ( block , proposalTx , db , node . bp ) ;
838893 } catch ( e ) {
839894 db . destroyDb ( ) ;
840895 throw e ;
841896 }
897+ if ( updateTxInfo ) {
898+ Consensus . updateTransactionInfoForBlock ( node , last_votes , proposalTx , transactions , voteTxsRes , proposalTxRes , txsRes ) ;
899+ }
842900 }
843901
844902 /**
@@ -854,7 +912,7 @@ class Consensus {
854912 `${ proposalBlock . number } / ${ proposalBlock . epoch } / ${ proposalBlock . hash } / ${ proposalBlock . proposer } \n` +
855913 `${ proposalTx . hash } / ${ proposalTx . address } ` ) ;
856914
857- Consensus . validateAndExecuteBlockOnDb ( proposalBlock , this . node , StateVersions . POOL , proposalTx ) ;
915+ Consensus . validateAndExecuteBlockOnDb ( proposalBlock , this . node , StateVersions . POOL , proposalTx , true ) ;
858916
859917 if ( proposalBlock . number > 1 && ! this . node . bp . longestNotarizedChainTips . includes ( proposalBlock . last_hash ) ) {
860918 throw new ConsensusError ( {
@@ -1144,7 +1202,7 @@ class Consensus {
11441202 proposalTx = i < chain . length - 1 ? ConsensusUtil . filterProposalFromVotes ( chain [ i + 1 ] . last_votes ) : null ;
11451203 logger . debug ( `[${ LOG_HEADER } ] applying block ${ JSON . stringify ( block ) } ` ) ;
11461204 try {
1147- Consensus . validateAndExecuteBlockOnDb ( block , this . node , StateVersions . SNAP , proposalTx ) ;
1205+ Consensus . validateAndExecuteBlockOnDb ( block , this . node , StateVersions . SNAP , proposalTx , false ) ;
11481206 } catch ( e ) {
11491207 logger . error ( `[${ LOG_HEADER } ] Failed to validate and execute block ${ block . number } : ${ e } ` ) ;
11501208 return null ;
0 commit comments