def __fill_ledger_root_hash(self, txn, lid, ledger, last_audit_txn, three_pc_batch): last_audit_txn_data = get_payload_data( last_audit_txn) if last_audit_txn is not None else None if lid == three_pc_batch.ledger_id: txn[AUDIT_TXN_LEDGER_ROOT][lid] = Ledger.hashToStr( ledger.uncommitted_root_hash) txn[AUDIT_TXN_STATE_ROOT][lid] = Ledger.hashToStr( self.database_manager.get_state(lid).headHash) # 1. it is the first batch and we have something elif last_audit_txn_data is None and ledger.uncommitted_size: txn[AUDIT_TXN_LEDGER_ROOT][lid] = Ledger.hashToStr( ledger.uncommitted_root_hash) txn[AUDIT_TXN_STATE_ROOT][lid] = Ledger.hashToStr( self.database_manager.get_state(lid).headHash) # 1.1. Rare case -- we have previous audit txns but don't have this ledger i.e. new plugins elif last_audit_txn_data is not None and last_audit_txn_data[AUDIT_TXN_LEDGERS_SIZE].get(lid, None) is None and \ len(ledger.uncommittedTxns): txn[AUDIT_TXN_LEDGER_ROOT][lid] = Ledger.hashToStr( ledger.uncommitted_root_hash) txn[AUDIT_TXN_STATE_ROOT][lid] = Ledger.hashToStr( self.database_manager.get_state(lid).headHash) # 2. Usual case -- this ledger was updated since the last audit txn elif last_audit_txn_data is not None and last_audit_txn_data[AUDIT_TXN_LEDGERS_SIZE].get(lid, None) is not None and \ ledger.uncommitted_size > last_audit_txn_data[AUDIT_TXN_LEDGERS_SIZE][lid]: txn[AUDIT_TXN_LEDGER_ROOT][lid] = Ledger.hashToStr( ledger.uncommitted_root_hash) txn[AUDIT_TXN_STATE_ROOT][lid] = Ledger.hashToStr( self.database_manager.get_state(lid).headHash) # 3. This ledger is never audited, so do not add the key elif last_audit_txn_data is None or lid not in last_audit_txn_data[ AUDIT_TXN_LEDGER_ROOT]: return # 4. ledger is not changed in last batch => delta = delta + 1 elif isinstance(last_audit_txn_data[AUDIT_TXN_LEDGER_ROOT][lid], int): txn[AUDIT_TXN_LEDGER_ROOT][ lid] = last_audit_txn_data[AUDIT_TXN_LEDGER_ROOT][lid] + 1 # 5. ledger is changed in last batch but not changed now => delta = 1 elif last_audit_txn_data: txn[AUDIT_TXN_LEDGER_ROOT][lid] = 1
def __fill_ledger_root_hash(self, txn, three_pc_batch, lid, last_audit_txn): target_ledger_id = three_pc_batch.ledger_id last_audit_txn_data = get_payload_data(last_audit_txn) if last_audit_txn is not None else None # 1. ledger is changed in this batch => root_hash if lid == target_ledger_id: txn[AUDIT_TXN_LEDGER_ROOT][lid] = Ledger.hashToStr(three_pc_batch.txn_root) # 2. This ledger is never audited, so do not add the key elif last_audit_txn_data is None or lid not in last_audit_txn_data[AUDIT_TXN_LEDGER_ROOT]: return # 3. ledger is not changed in last batch => delta = delta + 1 elif isinstance(last_audit_txn_data[AUDIT_TXN_LEDGER_ROOT][lid], int): txn[AUDIT_TXN_LEDGER_ROOT][lid] = last_audit_txn_data[AUDIT_TXN_LEDGER_ROOT][lid] + 1 # 4. ledger is changed in last batch but not changed now => delta = 1 elif last_audit_txn_data: txn[AUDIT_TXN_LEDGER_ROOT][lid] = 1
def check_audit_txn(txn, view_no, pp_seq_no, seq_no, txn_time, txn_roots, state_roots, pool_size, domain_size, config_size, last_domain_seqno, last_pool_seqno, last_config_seqno, primaries, node_reg, digest='', other_sizes={}): expectedLedgerRoots = {} txn_roots = {k: Ledger.hashToStr(v) for k, v in txn_roots.items()} state_roots = {k: Ledger.hashToStr(v) for k, v in state_roots.items()} # we expect deltas here, that is a difference from the current audit ledger txn to # the audit txn where the corresponding ledger was updated if last_domain_seqno: expectedLedgerRoots[1] = seq_no - last_domain_seqno if last_pool_seqno: expectedLedgerRoots[0] = seq_no - last_pool_seqno if last_config_seqno: expectedLedgerRoots[2] = seq_no - last_config_seqno expectedLedgerRoots.update(txn_roots) ledger_size = {0: pool_size, 1: domain_size, 2: config_size} ledger_size.update(other_sizes) expected = { "reqSignature": {}, "txn": { "data": { "ledgerRoot": expectedLedgerRoots, "ver": "1", "viewNo": view_no, "ppSeqNo": pp_seq_no, "ledgerSize": ledger_size, "stateRoot": state_roots, "primaries": primaries, "digest": digest, "nodeReg": node_reg }, "metadata": {}, "protocolVersion": CURRENT_PROTOCOL_VERSION, "type": "2", # AUDIT }, "txnMetadata": { "seqNo": seq_no, "txnTime": txn_time }, "ver": "1" } txn = JsonSerializer().serialize(txn) expected = JsonSerializer().serialize(expected) print(txn) print(expected) assert expected == txn