def test_check_cipher_batch_hash( executor_contract: Any, config_contract: Any, mock_batcher_contract: Any, chain: Chain, config_change_heads_up_blocks: int, owner: Account, keypers: List[Account], ) -> None: config = make_batch_config( start_batch_index=0, start_block_number=chain.height + config_change_heads_up_blocks + 20, batch_span=10, keypers=keypers, threshold=0, ) schedule_config(config_contract, config, owner=owner) mine_until(config.start_block_number, chain) batch_hash = make_bytes(32) mock_batcher_contract.setBatchHash(0, 0, batch_hash) mine_until(config.start_block_number + config.batch_span - 1, chain) with brownie.reverts("ExecutorContract: incorrect cipher batch hash"): executor_contract.executeCipherBatch(0, ZERO_HASH32, [], 0, {"from": keypers[0]}) with brownie.reverts("ExecutorContract: incorrect cipher batch hash"): executor_contract.executeCipherBatch(0, make_bytes(32), [b""], 0, {"from": keypers[0]}) executor_contract.executeCipherBatch(0, batch_hash, [b""], 0, {"from": keypers[0]})
def execute_cipher_batch( *, config_contract: Any, batcher_contract: Any, executor_contract: Any, chain: Chain, owner: Account, keypers: Accounts, config_change_heads_up_blocks: int, threshold: int, batch_size: int, tx_size: int, ) -> TransactionReceipt: config = make_batch_config( start_batch_index=0, start_block_number=chain.height + config_change_heads_up_blocks + 20, batch_span=100, keypers=keypers, threshold=1, ) schedule_config(config_contract, config, owner=owner) mine_until(config.start_block_number - 1, chain) batch = [make_bytes(tx_size) for _ in range(batch_size)] for tx in batch: batcher_contract.addTransaction(0, 0, tx) cipher_batch_hash = compute_batch_hash(batch) mine_until(config.start_block_number + config.batch_span, chain) decrypted_transactions = [make_bytes(tx_size) for _ in range(batch_size)] return executor_contract.executeCipherBatch(0, cipher_batch_hash, decrypted_transactions, 0, {"from": keypers[0]})
def test_broadcasting_checks_sender(key_broadcast_contract: Any, config_contract: Any, owner: Account, accounts: Sequence[Account]) -> None: keypers = accounts[1:4] keyper_addresses = [to_canonical_address(k.address) for k in keypers] config = make_batch_config(start_batch_index=0, keypers=keyper_addresses, batch_span=1) schedule_config(config_contract, config, owner=owner) start_batch_index = 10 key = make_bytes(32) for keyper_index, sender in [ (1, accounts[5]), (1, keypers[2]), ]: with brownie.reverts("KeyBroadcastContract: sender is not keyper"): key_broadcast_contract.vote( keyper_index, start_batch_index, key, {"from": sender}, ) with brownie.reverts("KeyBroadcastContract: keyper index out of range"): key_broadcast_contract.vote( 3, start_batch_index, key, {"from": keypers[0]}, )
def test_check_plain_batch_hash( executor_contract: Any, config_contract: Any, mock_batcher_contract: Any, chain: Chain, config_change_heads_up_blocks: int, owner: Account, keypers: List[Account], ) -> None: config = make_batch_config( start_batch_index=0, start_block_number=chain.height + config_change_heads_up_blocks + 20, batch_span=10, keypers=keypers, threshold=0, ) schedule_config(config_contract, config, owner=owner) mine_until(config.start_block_number, chain) batch = make_batch(3) mock_batcher_contract.setBatchHash(0, 1, compute_batch_hash(batch)) mine_until(config.start_block_number + config.batch_span - 1, chain) executor_contract.executeCipherBatch(0, ZERO_HASH32, [], 0, {"from": keypers[0]}) with brownie.reverts("ExecutorContract: batch hash does not match"): executor_contract.executePlainBatch(0, []) with brownie.reverts("ExecutorContract: batch hash does not match"): executor_contract.executePlainBatch(0, batch[:-1]) with brownie.reverts("ExecutorContract: batch hash does not match"): executor_contract.executePlainBatch(0, batch + [make_bytes()]) executor_contract.executePlainBatch(0, batch)
def benchmark_add_plain_txs_by_size(batcher_contract: Any) -> None: # first tx takes more gas, so add one in advance to not skew results batcher_contract.addTransaction(0, 1, b"\x00") txs = [] sizes = list(range(1, 201, 10)) for size in sizes: tx = batcher_contract.addTransaction(0, 1, make_bytes(size)) txs.append(tx) print_gas_summary(txs)
def test_vote(key_broadcast_contract: Any, config_contract: Any, owner: Account, accounts: Sequence[Account]) -> None: keypers = accounts[1:4] keyper_addresses = [to_canonical_address(k.address) for k in keypers] config = make_batch_config(start_batch_index=0, keypers=keyper_addresses, batch_span=1) schedule_config(config_contract, config, owner=owner) index1 = 1 index2 = 2 sender1 = keypers[index1] sender2 = keypers[index2] start_batch_index = 10 key = make_bytes(32) tx1 = key_broadcast_contract.vote(index1, start_batch_index, key, {"from": sender1}) assert len(tx1.events) == 1 assert tx1.events["Voted"][0] == { "keyper": sender1, "startBatchIndex": start_batch_index, "key": encode_hex(key), "numVotes": 1, } tx2 = key_broadcast_contract.vote(index2, start_batch_index, key, {"from": sender2}) assert len(tx2.events) == 1 assert tx2.events["Voted"][0] == { "keyper": sender2, "startBatchIndex": start_batch_index, "key": encode_hex(key), "numVotes": 2, } with brownie.reverts("KeyBroadcastContract: keyper has already voted"): key_broadcast_contract.vote(index1, start_batch_index, make_bytes(32), {"from": sender1})
def benchmark_add_plain_txs(batcher_contract: Any) -> None: txs = [] for _ in range(10): tx = batcher_contract.addTransaction(0, 1, make_bytes(100)) txs.append(tx) print_gas_summary(txs)