11mod schema;
22
33use anyhow:: { Context , Result } ;
4- use replay:: { compare_config_manifests, parse_manifest_json, recommended_manifest_template} ;
5- use serde:: Deserialize ;
4+ use serde:: { Deserialize , Serialize } ;
5+ use serde_json:: json;
6+ use sha2:: { Digest , Sha256 } ;
67use std:: collections:: HashMap ;
78use std:: env;
89use std:: fs:: File ;
910use std:: io:: { BufRead , BufReader } ;
10- use std:: { env as std_env, fs} ;
1111
1212use soroban_sdk:: testutils:: Address as _;
1313use soroban_sdk:: testutils:: Ledger as _;
1414use soroban_sdk:: { Address , Env , Symbol , Vec as SVec } ;
1515
1616use ledgerlens_score:: { LedgerLensScoreContract , LedgerLensScoreContractClient , ScoreSubmission } ;
17- use schema:: { ReplayEntryV1 , ReplayFileHeader , ReplayMetadata } ;
17+ use schema:: ReplayFileHeader ;
1818
1919#[ derive( Debug , Deserialize ) ]
2020struct SnapshotEntry {
@@ -34,6 +34,53 @@ struct FailureEntry {
3434 model_version : Option < u32 > ,
3535}
3636
37+ #[ derive( Debug , Clone , Deserialize , Serialize , PartialEq , Eq ) ]
38+ struct ConfigSnapshot {
39+ admin : String ,
40+ service : String ,
41+ cooldown_secs : u64 ,
42+ default_score : u32 ,
43+ }
44+
45+ #[ derive( Debug , Clone , Deserialize , Serialize , PartialEq , Eq ) ]
46+ struct TransactionEvidence {
47+ sequence : u64 ,
48+ wallet : String ,
49+ asset_pair : String ,
50+ score : u32 ,
51+ timestamp : u64 ,
52+ accepted : bool ,
53+ rejection_code : Option < u32 > ,
54+ }
55+
56+ #[ derive( Debug , Clone , Deserialize , Serialize , PartialEq , Eq ) ]
57+ struct EventEvidence {
58+ sequence : u64 ,
59+ kind : String ,
60+ wallet : String ,
61+ asset_pair : String ,
62+ message : String ,
63+ }
64+
65+ #[ derive( Debug , Clone , Deserialize , Serialize , PartialEq , Eq ) ]
66+ struct BundleHashes {
67+ transactions_hash : String ,
68+ events_hash : String ,
69+ config_hash : String ,
70+ issue_refs_hash : String ,
71+ bundle_hash : String ,
72+ }
73+
74+ #[ derive( Debug , Clone , Deserialize , Serialize , PartialEq , Eq ) ]
75+ struct IncidentEvidenceBundle {
76+ bundle_version : u32 ,
77+ transactions : Vec < TransactionEvidence > ,
78+ events : Vec < EventEvidence > ,
79+ config_snapshot : ConfigSnapshot ,
80+ issue_references : Vec < String > ,
81+ hashes : BundleHashes ,
82+ }
83+
3784fn parse_price_average ( trades : & Option < Vec < serde_json:: Value > > ) -> Option < f64 > {
3885 trades. as_ref ( ) . and_then ( |t| {
3986 let mut sum = 0.0f64 ;
@@ -132,6 +179,8 @@ fn process_snapshot(
132179 let mut count = 0usize ;
133180 let mut addr_map: HashMap < String , Address > = HashMap :: new ( ) ;
134181 let mut schema_version: Option < u32 > = None ;
182+ let mut transactions = Vec :: new ( ) ;
183+ let mut events = Vec :: new ( ) ;
135184
136185 for line in reader. lines ( ) {
137186 let l = line?;
@@ -180,14 +229,15 @@ fn process_snapshot(
180229 } )
181230 . unwrap_or ( config_snapshot. default_score ) ;
182231
232+ let timestamp = env. ledger ( ) . timestamp ( ) . saturating_add ( count as u64 ) ;
183233 let mut batch: SVec < ScoreSubmission > = SVec :: new ( env) ;
184234 batch. push_back ( ScoreSubmission {
185235 wallet : wallet_addr. clone ( ) ,
186236 asset_pair : pair_sym. clone ( ) ,
187237 score,
188238 benford_flag : false ,
189239 ml_flag : false ,
190- timestamp : env . ledger ( ) . timestamp ( ) . saturating_add ( count as u64 ) ,
240+ timestamp,
191241 confidence : 80u32 ,
192242 model_version : 1u32 ,
193243 } ) ;
@@ -202,7 +252,7 @@ fn process_snapshot(
202252 wallet : entry. wallet . clone ( ) ,
203253 asset_pair : entry. asset_pair . clone ( ) ,
204254 score,
205- timestamp : 1u64 ,
255+ timestamp,
206256 accepted,
207257 rejection_code,
208258 } ) ;
@@ -228,7 +278,9 @@ fn process_snapshot(
228278 ) ;
229279 }
230280
231- Ok ( count)
281+ let bundle =
282+ build_evidence_bundle ( transactions, events, config_snapshot. clone ( ) , issue_references) ;
283+ Ok ( ( count, bundle) )
232284}
233285
234286fn process_failure_scenario (
@@ -322,8 +374,19 @@ fn main() -> Result<()> {
322374 let service = Address :: generate ( & env) ;
323375 client. initialize ( & admin, & service) ;
324376
325- match process_snapshot ( path, & env, & client) {
326- Ok ( n) => println ! ( "processed {} entries" , n) ,
377+ let config_snapshot = ConfigSnapshot {
378+ admin : "initialized-admin" . to_string ( ) ,
379+ service : "initialized-service" . to_string ( ) ,
380+ cooldown_secs : 3600 ,
381+ default_score : 50 ,
382+ } ;
383+ let issue_references = parse_issue_references ( args. get ( 3 ..) . unwrap_or_default ( ) ) ;
384+
385+ match process_snapshot ( path, & env, & client, & config_snapshot, & issue_references) {
386+ Ok ( ( n, bundle) ) => {
387+ println ! ( "processed {} entries" , n) ;
388+ println ! ( "evidence_bundle={}" , serde_json:: to_string_pretty( & bundle) ?) ;
389+ }
327390 Err ( e) => println ! ( "error processing snapshot: {:#}" , e) ,
328391 }
329392 }
0 commit comments