@@ -761,95 +761,14 @@ function formatTermination(term: TerminationEntry): string {
761761 * @param hostCallIndex The ecalli index being executed
762762 * @param readMemory Function to read memory for comparison
763763 */
764- export function findHostCallEntry (
765- trace : ParsedTrace ,
766- indexInTrace : number ,
767- pc : number ,
768- gas : bigint ,
764+ function collectStateMismatches (
765+ entry : HostCallEntry ,
769766 registers : bigint [ ] ,
770- hostCallIndex : number ,
767+ gas : bigint ,
771768 readMemory ?: ( address : number , length : number ) => Uint8Array | null ,
772- ) : HostCallLookupResult {
773- // Get remaining entries from the current index
774- const remainingEntries = trace . hostCalls . slice ( indexInTrace ) ;
775-
776- // Try to find an exact match by PC and host call index
777- const matchingEntries = remainingEntries . filter ( ( hc ) => hc . pc === pc && hc . gas <= gas ) ;
778-
779- if ( matchingEntries . length === 0 ) {
780- return { entry : null , mismatches : [ ] } ;
781- }
782-
783- // First try to find an entry whose hostCallIndex matches exactly
784- // Prefer exact index match even if gas is slightly higher
785- const exactIndexMatch = remainingEntries . find ( ( hc ) => hc . index === hostCallIndex && hc . pc === pc ) ;
786-
787- // If we have an exact index match with acceptable gas, use it
788- if ( exactIndexMatch && exactIndexMatch . gas <= gas ) {
789- const mismatches : StateMismatch [ ] = [ ] ;
790-
791- // Check gas
792- if ( exactIndexMatch . gas !== gas ) {
793- mismatches . push ( {
794- field : "gas" ,
795- expected : exactIndexMatch . gas . toString ( ) ,
796- actual : gas . toString ( ) ,
797- } ) ;
798- }
799-
800- // Check registers
801- for ( const [ idx , expectedValue ] of exactIndexMatch . registers ) {
802- const actualValue = registers [ idx ] ?? 0n ;
803- if ( expectedValue !== actualValue ) {
804- mismatches . push ( {
805- field : "register" ,
806- expected : `r${ idx } =0x${ expectedValue . toString ( 16 ) } ` ,
807- actual : `r${ idx } =0x${ actualValue . toString ( 16 ) } ` ,
808- details : `Register ${ idx } ` ,
809- } ) ;
810- }
811- }
812-
813- // Check memory reads if readMemory function is provided
814- if ( readMemory ) {
815- for ( const mr of exactIndexMatch . memoryReads ) {
816- const actualData = readMemory ( mr . address , mr . length ) ;
817- if ( actualData ) {
818- const expectedHex = Array . from ( mr . data )
819- . map ( ( b ) => b . toString ( 16 ) . padStart ( 2 , "0" ) )
820- . join ( "" ) ;
821- const actualHex = Array . from ( actualData )
822- . map ( ( b ) => b . toString ( 16 ) . padStart ( 2 , "0" ) )
823- . join ( "" ) ;
824- if ( expectedHex !== actualHex ) {
825- mismatches . push ( {
826- field : "memread" ,
827- expected : `0x${ expectedHex } ` ,
828- actual : `0x${ actualHex } ` ,
829- details : `Memory at 0x${ mr . address . toString ( 16 ) } (${ mr . length } bytes)` ,
830- } ) ;
831- }
832- }
833- }
834- }
835-
836- return { entry : exactIndexMatch , mismatches } ;
837- }
838-
839- // Fall back to first matching entry by PC and gas
840- const entry = matchingEntries [ 0 ] ;
769+ ) : StateMismatch [ ] {
841770 const mismatches : StateMismatch [ ] = [ ] ;
842771
843- // Check PC
844- if ( entry . index !== hostCallIndex ) {
845- mismatches . push ( {
846- field : "index" ,
847- expected : entry . index . toString ( ) ,
848- actual : hostCallIndex . toString ( ) ,
849- } ) ;
850- }
851-
852- // Check gas
853772 if ( entry . gas !== gas ) {
854773 mismatches . push ( {
855774 field : "gas" ,
@@ -858,7 +777,6 @@ export function findHostCallEntry(
858777 } ) ;
859778 }
860779
861- // Check registers
862780 for ( const [ idx , expectedValue ] of entry . registers ) {
863781 const actualValue = registers [ idx ] ?? 0n ;
864782 if ( expectedValue !== actualValue ) {
@@ -871,7 +789,6 @@ export function findHostCallEntry(
871789 }
872790 }
873791
874- // Check memory reads if readMemory function is provided
875792 if ( readMemory ) {
876793 for ( const mr of entry . memoryReads ) {
877794 const actualData = readMemory ( mr . address , mr . length ) ;
@@ -894,6 +811,46 @@ export function findHostCallEntry(
894811 }
895812 }
896813
814+ return mismatches ;
815+ }
816+
817+ export function findHostCallEntry (
818+ trace : ParsedTrace ,
819+ indexInTrace : number ,
820+ pc : number ,
821+ gas : bigint ,
822+ registers : bigint [ ] ,
823+ hostCallIndex : number ,
824+ readMemory ?: ( address : number , length : number ) => Uint8Array | null ,
825+ ) : HostCallLookupResult {
826+ const remainingEntries = trace . hostCalls . slice ( indexInTrace ) ;
827+
828+ const exactIndexMatch = remainingEntries . find ( ( hc ) => hc . index === hostCallIndex && hc . pc === pc ) ;
829+
830+ if ( exactIndexMatch ) {
831+ const mismatches = collectStateMismatches ( exactIndexMatch , registers , gas , readMemory ) ;
832+ return { entry : exactIndexMatch , mismatches } ;
833+ }
834+
835+ const matchingEntries = remainingEntries . filter ( ( hc ) => hc . pc === pc && hc . gas <= gas ) ;
836+
837+ if ( matchingEntries . length === 0 ) {
838+ return { entry : null , mismatches : [ ] } ;
839+ }
840+
841+ const entry = matchingEntries [ 0 ] ;
842+ const mismatches : StateMismatch [ ] = [ ] ;
843+
844+ if ( entry . index !== hostCallIndex ) {
845+ mismatches . push ( {
846+ field : "index" ,
847+ expected : entry . index . toString ( ) ,
848+ actual : hostCallIndex . toString ( ) ,
849+ } ) ;
850+ }
851+
852+ mismatches . push ( ...collectStateMismatches ( entry , registers , gas , readMemory ) ) ;
853+
897854 return { entry, mismatches } ;
898855}
899856
0 commit comments