@@ -822,6 +822,34 @@ func Test_Outcome_Methods(t *testing.T) {
822822 // if cadence is 5s, if time is < 5s, does not report because cadence hasn't elapsed
823823 require .EqualError (t , outcome .IsReportable (cid , 1 , uint64 (5 * time .Second )), "ChannelID: 1; Reason: IsReportable=false; not valid yet (ObservationTimestampNanoseconds=1726670490999999999, validAfterNanoseconds=1726670489999999999, minReportInterval=5000000000); 4.000000 seconds (4000000000ns) until reportable" )
824824 })
825+ t .Run ("IsReportable with ReportFormatEVMABIEncodeUnpackedExpr prevents same-second timestamps" , func (t * testing.T ) {
826+ outcome := Outcome {}
827+ cid := llotypes .ChannelID (1 )
828+
829+ // Test case from production bug: both timestamps truncate to same second
830+ // observationTimestampNanoseconds: 1765173183742021148 → 1765173183 sec
831+ // validAfterNanoseconds: 1765173183282997914 → 1765173183 sec
832+ outcome .LifeCycleStage = LifeCycleStageProduction
833+ outcome .ObservationTimestampNanoseconds = 1765173183742021148
834+ outcome .ChannelDefinitions = map [llotypes.ChannelID ]llotypes.ChannelDefinition {
835+ cid : {ReportFormat : llotypes .ReportFormatEVMABIEncodeUnpackedExpr },
836+ }
837+ outcome .ValidAfterNanoseconds = map [llotypes.ChannelID ]uint64 {
838+ cid : 1765173183282997914 ,
839+ }
840+
841+ // Should be unreportable because timestamps are in same second
842+ require .EqualError (t , outcome .IsReportable (cid , 1 , uint64 (0 )),
843+ "ChannelID: 1; Reason: ChannelID: 1; Reason: IsReportable=false; not valid yet (observationsTimestampSeconds=1765173183, validAfterSeconds=1765173183)" )
844+
845+ // When ValidAfter is at least 1 second before observation, should be reportable
846+ outcome .ValidAfterNanoseconds [cid ] = 1765173182999999999 // 1ns before previous second
847+ assert .Nil (t , outcome .IsReportable (cid , 1 , uint64 (0 )))
848+
849+ // Test IsSecondsResolution returns true for calculated streams
850+ assert .True (t , IsSecondsResolution (llotypes .ReportFormatEVMABIEncodeUnpackedExpr ),
851+ "IsSecondsResolution should return true for ReportFormatEVMABIEncodeUnpackedExpr" )
852+ })
825853 t .Run ("ReportableChannels" , func (t * testing.T ) {
826854 defaultMinReportInterval := uint64 (1 * time .Second )
827855
0 commit comments