def test_mtree_proof(): leaves = [str(i).encode() * 32 for i in range(10)] layers = compute_layers(leaves) tree = MerkleTreeState(layers) root = merkleroot(tree) proofs = [compute_merkleproof_for(tree, _hash) for _hash in leaves] for i, leaf in enumerate(leaves): assert validate_proof(proofs[i], root, leaf)
def test_merkle_proof_contract(): hash0 = b'a' * 32 hash1 = b'b' * 32 leaves = [hash0, hash1] layers = compute_layers(leaves) tree = MerkleTreeState(layers) root = merkleroot(tree) proofs0 = compute_merkleproof_for(tree, hash0) proofs1 = compute_merkleproof_for(tree, hash1) s = tester.Chain() contract_code = open('MerkleProof.sol').read() contract = s.contract(contract_code, language='solidity') assert contract.verifyProof(b''.join(proofs0), root, hash0) assert contract.verifyProof(b''.join(proofs1), root, hash1) assert contract.verifyProof(b''.join(proofs1), root, hash0) is False
def generate_mt_worker(checkpoint_path, checkpoints, checkpoint_timediff): CheckPointInfo = collections.namedtuple('CheckPointInfo', 'path history_pos hash') while True: time.sleep(3) with checkpoint_lock: now = datetime.datetime.now() path_hashes = [] for path, details in checkpoints.items(): if path != 'roots': for i, checkpoint in enumerate(details['history']): # Merkle proofs have not yet been produced # and to_date is one checkpoint time frame ago. if not checkpoint.get('root_hash') and \ now - gt(checkpoint['to_date']) > checkpoint_timediff: path_hashes.append( CheckPointInfo(path, i, checkpoint['hash']) ) if not path_hashes: # Nothing to calculate. continue leaves = [ binascii.unhexlify(ci.hash) for ci in path_hashes ] layers = compute_layers(leaves) tree = MerkleTreeState(layers) root_hash_str = binascii.hexlify(merkleroot(tree)).decode() # Calculate proofs for leaves. proofs = [compute_merkleproof_for(tree, _hash) for _hash in leaves] # Set the necessary proofs on the checkpoints. for i, ci in enumerate(path_hashes): checkpoints[ci.path]['history'][ci.history_pos]['root_hash'] = \ root_hash_str checkpoints[ci.path]['history'][ci.history_pos]['proofs'] = \ [binascii.hexlify(k).decode() for k in proofs[i]] # Maintain the set of root hashes. if 'roots' not in checkpoints: checkpoints['roots'] = set() checkpoints['roots'].add(root_hash_str) save_checkpoints(checkpoint_path, checkpoints)
def root_with(self, lock=None, exclude=None): assert not lock or isinstance(lock, Lock) assert not exclude or isinstance(exclude, Lock) lock_hash = exclude_hash = None # temporarily add / remove if lock: lock_hash = sha3(lock.asstring) self._cached_lock_hashes.append(lock_hash) if exclude: exclude_hash = sha3(exclude.asstring) self._cached_lock_hashes.remove(exclude_hash) # calc r = merkleroot(self._cached_lock_hashes) # restore if lock_hash: assert lock_hash in self._cached_lock_hashes self._cached_lock_hashes.remove(lock_hash) if exclude: self._cached_lock_hashes.append(exclude_hash) return r
def root(self): if not self._cached_root: self._cached_root = merkleroot(self._cached_lock_hashes) return self._cached_root