"""Recalculate this frozen regtest export; no Core or network connection required.
Run: python analyze-results.py /path/to/results.json
Transparent SegWit serialization reader, scoped to this package's transactions.
It does not validate signatures, ownership, consensus or live UTXO status.
"""
import hashlib,json,sys
from pathlib import Path
def decode(hex_tx):
    raw=bytes.fromhex(hex_tx);pos=4;stripped=raw[:4]
    assert raw[4:6]==b'\x00\x01','Expected ordinary SegWit serialization'
    pos+=2
    def read(length):
        nonlocal pos
        data=raw[pos:pos+length];pos+=length
        assert len(data)==length,'Truncated data';return data
    def compact():
        prefix=read(1)[0]
        if prefix<253:return prefix
        return int.from_bytes(read({253:2,254:4,255:8}[prefix]),'little')
    begin=pos;count=compact();inputs=[]
    for _ in range(count):
        txid=read(32)[::-1].hex();index=int.from_bytes(read(4),'little')
        read(compact());read(4);inputs.append({'txid':txid,'vout':index})
    out_count=compact();outputs=[]
    for index in range(out_count):
        value=int.from_bytes(read(8),'little');script=read(compact()).hex()
        outputs.append({'vout':index,'value_litoshi':value,'script_hex':script})
    stripped+=raw[begin:pos]
    for _ in range(count):
        items=compact()
        for _ in range(items):read(compact())
    stripped+=read(4);assert pos==len(raw),'Unexpected trailing bytes'
    weight=3*len(stripped)+len(raw)
    return {'inputs':inputs,'outputs':outputs,'weight':weight,'vsize':(weight+3)//4,
            'txid':hashlib.sha256(hashlib.sha256(stripped).digest()).digest()[::-1].hex()}
def main():
    data=json.loads(Path(sys.argv[1]).read_text(encoding='utf-8'));signed=failed=0
    assert data['network']=='regtest' and data['peer_count']==0
    assert len(data['states'])==11 and len(data['payments'])==24
    for row in data['payments']:
        if not row['constructed']:
            assert row['case']=='exact_full_balance' and 'Insufficient funds' in row['error'];failed+=1;continue
        signed+=1;tx=decode(row['signed_hex'])
        assert tx['outputs']==row['decoded_outputs']
        assert tx['txid']==row['txid'] and tx['weight']==row['weight'] and tx['vsize']==row['vsize']
        assert tx['inputs']==[{'txid':x['txid'],'vout':x['vout']} for x in row['selected_inputs']]
        input_total=sum(x['value_litoshi'] for x in row['selected_inputs'])
        outputs=sum(x['value_litoshi'] for x in tx['outputs'])
        assert input_total==row['input_litoshi']==100000000
        assert input_total-outputs==row['fee_litoshi']
        assert tx['outputs'][0]['value_litoshi']==row['recipient_litoshi']
        assert outputs-row['recipient_litoshi']==row['change_litoshi']
        assert row['wallet_reduction_litoshi']==input_total-row['change_litoshi']
        assert row['complete_signature'] and row['local_policy']['allowed']
        if row['case']=='exact_0.4':assert row['recipient_litoshi']==40000000
        if row['case']=='subtract_from_0.4':assert row['recipient_litoshi']==40000000-row['fee_litoshi'] and row['change_litoshi']==60000000
        if row['case']=='send_max':assert row['recipient_litoshi']==input_total-row['fee_litoshi'] and row['change_litoshi']==0
    assert signed==18 and failed==6
    assert all(x['passed'] for x in data['checks']) and len(data['checks'])==103
    assert data['mined_sweep']['senderBalanceLitoshi']==0
    print(json.dumps({'signed_transactions_redecoded':signed,'rejected_constructions':failed,'wallet_states':len(data['states']),
                      'collector_assertions':len(data['checks']),'frozen_export_recalculated':True}))
if __name__=='__main__':main()
