def GetAergoValidatorsSignature(self, val_msg, context): """Get a vote(signature) from the validator to update the set of validators in the Ethereum bridge contract bridging to Aergo """ if not (self.auto_update and self.oracle_update): return Approval(error="Validators update not enabled") err_msg = self.data_sources.is_valid_aergo_validators(val_msg) if err_msg is not None: logger.warning(error_log_template, self.validator_index, "false", "\U0001f58b validator set", self.eth_net, err_msg) return Approval(error=err_msg) # sign validators concat_vals = b'' for val in val_msg.validators: concat_vals += pad_bytes(b'\x00', 32, bytes.fromhex(val[2:])) msg_bytes = concat_vals \ + val_msg.destination_nonce.to_bytes(32, byteorder='big') \ + self.eth_oracle_id \ + bytes("V", 'utf-8') h = keccak(msg_bytes) sig = self.eth_signer.sign(h) approval = Approval(address=self.eth_signer.address, sig=bytes(sig.signature)) logger.info(success_log_template, self.validator_index, "true", "\U0001f58b validator set", self.eth_net, val_msg.validators, val_msg.destination_nonce) return approval
def verify_eth_getProof_inclusion(proof, root): trie_root = Binary.fixed_length(32, allow_empty=True) hash32 = Binary.fixed_length(32) class _Account(rlp.Serializable): fields = [('nonce', big_endian_int), ('balance', big_endian_int), ('storage', trie_root), ('code_hash', hash32)] acc = _Account(proof.nonce, proof.balance, proof.storageHash, proof.codeHash) rlp_account = rlp.encode(acc) trie_key = keccak(bytes.fromhex(proof.address[2:])) assert rlp_account == HexaryTrie.get_from_proof( root, trie_key, format_proof_nodes( proof.accountProof)), "Failed to verify account proof {}".format( proof.address) for storage_proof in proof.storageProof: trie_key = keccak(pad_bytes(b'\x00', 32, storage_proof.key)) root = proof.storageHash if storage_proof.value == b'\x00': rlp_value = b'' else: rlp_value = rlp.encode(storage_proof.value) assert rlp_value == HexaryTrie.get_from_proof( root, trie_key, format_proof_nodes(storage_proof.proof) ), "Failed to verify storage proof {}".format(storage_proof.key) return True
def verify_eth_get_proof(self, proof, root): values = [] trie_root = Binary.fixed_length(32, allow_empty=True) hash32 = Binary.fixed_length(32) class _Account(rlp.Serializable): fields = [('nonce', big_endian_int), ('balance', big_endian_int), ('storage', trie_root), ('code_hash', hash32)] acc = _Account(proof.nonce, proof.balance, proof.storageHash, proof.codeHash) rlp_account = rlp.encode(acc) trie_key = keccak(bytes.fromhex(proof.address[2:])) if rlp_account != HexaryTrie.get_from_proof( root, trie_key, self.format_proof_nodes(proof.accountProof)): return False for storage_proof in proof.storageProof: trie_key = keccak(pad_bytes(b'\x00', 32, storage_proof.key)) root = proof.storageHash if storage_proof.value == b'\x00': rlp_value = b'' else: rlp_value = rlp.encode(storage_proof.value) if rlp_value != HexaryTrie.get_from_proof( root, trie_key, self.format_proof_nodes( storage_proof.proof)): return False else: values.append( {storage_proof.key.hex(): storage_proof.value.hex()}) return True, values
def get_new_validators_signatures(self, validators): """Request approvals of validators for the new validator set.""" nonce = self.eth_oracle.functions._nonce().call() new_validators_msg = NewValidators(validators=validators, destination_nonce=nonce) concat_vals = b'' for val in validators: concat_vals += pad_bytes(b'\x00', 32, bytes.fromhex(val[2:])) msg_bytes = concat_vals \ + nonce.to_bytes(32, byteorder='big') \ + self.eth_id \ + bytes("V", 'utf-8') h = keccak(msg_bytes) # get validator signatures and verify sig in worker validator_indexes = [i for i in range(len(self.stubs))] worker = partial(self.get_signature_worker, "GetAergoValidatorsSignature", new_validators_msg, h) approvals = self.pool.map(worker, validator_indexes) sigs, validator_indexes = self.extract_signatures(approvals) return sigs, validator_indexes