"""Reproduce descriptive early-observer results from frozen CSVs; Python stdlib only.""" from pathlib import Path import csv,json,hashlib,collections,datetime,argparse,re STATES=('confirmed','pending','left_mempool','censored_gap','recheck_required','censored_reorg') def analyze(base): base=Path(base);snapshot=json.loads((base/'snapshot.json').read_text()) for name,digest in snapshot['files'].items(): if hashlib.sha256((base/name).read_bytes()).hexdigest()!=digest:raise ValueError('Checksum mismatch: '+name) rows=list(csv.DictReader((base/'cohort.csv').open(newline=''))) polls=list(csv.DictReader((base/'polls.csv').open(newline=''))) txids=[row['txid'] for row in rows] if len(set(txids))!=len(txids):raise ValueError('Duplicate transactions') counts=dict.fromkeys(STATES,0);durations=[];bins=[0]*5;days={};poll_states=collections.Counter() for row in rows: if row['state'] not in counts:raise ValueError('Unknown outcome') if not re.fullmatch(r'[0-9a-f]{64}',row['txid']) or int(row['txid'][:8],16)%snapshot['sample_denominator']:raise ValueError('Sampling rule mismatch') seen=int(row['first_seen']) if not snapshot['window_start']<=seen<=snapshot['last_poll']:raise ValueError('Outside frozen cohort') counts[row['state']]+=1 if row['state']=='confirmed': duration=int(row['confirmed_at'])-seen if duration<0 or int(row['confirmed_at'])>snapshot['last_poll']:raise ValueError('Invalid confirmation time') durations.append(duration) bins[0 if duration<=60 else 1 if duration<=150 else 2 if duration<=300 else 3 if duration<=600 else 4]+=1 for row in polls: at=int(row['at']);covered=int(row['covered_seconds']);excluded=int(row['baseline_excluded']) if not snapshot['window_start']<=at<=snapshot['last_poll'] or excluded<0:raise ValueError('Invalid poll timestamp or exclusion count') if not 0<=covered<=30 or (covered and row['state']!='collecting'):raise ValueError('Invalid covered interval') day=datetime.datetime.fromtimestamp(at,datetime.timezone.utc).date().isoformat() d=days.setdefault(day,{'polls':0,'covered_seconds':0,'baseline_exclusions':0}) d['polls']+=1;d['covered_seconds']+=covered;d['baseline_exclusions']+=excluded;poll_states[row['state']]+=1 durations.sort() if not durations:raise ValueError('No matched confirmations in this snapshot') def quantile(f): import math pos=(len(durations)-1)*f;lo=math.floor(pos);hi=math.ceil(pos) return round(durations[lo]+(durations[hi]-durations[lo])*(pos-lo),1) if durations else None valid_polls=[int(p['at']) for p in polls if int(p['covered_seconds'])>0] first_valid=min(valid_polls);last_valid=max(valid_polls) valid_span=last_valid-first_valid+int(next(p['covered_seconds'] for p in polls if int(p['at'])==first_valid)) covered=sum(d['covered_seconds'] for d in days.values()) assert sum(counts.values())==len(rows) and sum(bins)==counts['confirmed'] return {'schema':1,'snapshot_at':snapshot['snapshot_at'],'last_poll':snapshot['last_poll'],'window_start':snapshot['window_start'],'total':len(rows),'counts':counts,'histogram':bins,'confirmed_median_seconds':quantile(.5),'confirmed_p90_seconds':quantile(.9),'confirmed_within_150':sum(t<=150 for t in durations),'confirmed_within_600':sum(t<=600 for t in durations),'confirmed_max_seconds':max(durations),'matched_block_count':len({r['block_hash'] for r in rows if r['state']=='confirmed'}),'first_seen':min(int(r['first_seen']) for r in rows),'last_first_seen':max(int(r['first_seen']) for r in rows),'first_covered_interval_end':first_valid,'last_covered_interval_end':last_valid,'covered_seconds':covered,'eligible_elapsed_seconds':valid_span,'days':days,'poll_states':dict(poll_states),'note':'Descriptive conditional timings. No population success rate, fee causal effect or sender-to-recipient settlement estimate.'} if __name__=='__main__': parser=argparse.ArgumentParser();parser.add_argument('directory',nargs='?',default='.');args=parser.parse_args() print(json.dumps(analyze(args.directory),indent=2))