def sampling(smc_handler, shard_id): """The sampling process is the same as the one in SMC(inside the `get_member_of_committee` function). It is used to avoid the overhead of making contrac call to SMC. The overhead could be quite significant if you want to get the complete sampling result since you have to make a total of `SHARD_COUNT`*`COMMITTEE_SIZE` times of contract calls. """ w3 = smc_handler.web3 current_period = w3.eth.blockNumber // smc_handler.config['PERIOD_LENGTH'] # Determine sample size if smc_handler.notary_sample_size_updated_period() < current_period: sample_size = smc_handler.next_period_notary_sample_size() elif smc_handler.notary_sample_size_updated_period() == current_period: sample_size = smc_handler.current_period_notary_sample_size() else: raise Exception("notary_sample_size_updated_period is larger than current period") # Get source for pseudo random number generation bytes32_shard_id = int_to_bytes32(shard_id) entropy_block_number = current_period * smc_handler.config['PERIOD_LENGTH'] - 1 entropy_block_hash = w3.eth.getBlock(entropy_block_number)['hash'] for i in range(smc_handler.config['COMMITTEE_SIZE']): yield big_endian_to_int( keccak( entropy_block_hash + bytes32_shard_id + int_to_bytes32(i) ) ) % sample_size
def encode_for_smc(self) -> bytes: encoded = b"".join([ int_to_bytes32(self.shard_id), self.chunk_root, int_to_bytes32(self.period), pad32(self.proposer_address), ]) if len(encoded) != self.smc_encoded_size: raise ValueError("Encoded header size is {} instead of {} bytes".format( len(encoded), self.smc_encoded_size, )) return encoded
def hash(self) -> bytes: header_hash = keccak( b''.join(( int_to_bytes32(self.shard_id), int_to_bytes32(self.expected_period_number), self.period_start_prevhash, self.parent_hash, self.transaction_root, pad32(self.coinbase), self.state_root, self.receipt_root, int_to_bytes32(self.number), )) ) return header_hash
def hash(self) -> bytes: header_hash = keccak( b''.join(( int_to_bytes32(self.shard_id), int_to_bytes32(self.expected_period_number), self.period_start_prevhash, self.parent_hash, self.transaction_root, pad32(self.coinbase), self.state_root, self.receipt_root, int_to_bytes32(self.number), )) ) # Hash of Collation header is the right most 26 bytes of `sha3(header)` # It's padded to 32 bytes because `bytes32` is easier to handle in Vyper return pad32(header_hash[6:])
def test_int_to_bytes32_invalid(value): with pytest.raises(ValueError): int_to_bytes32(value)
def test_int_to_bytes32_valid(value, expected): assert int_to_bytes32(value) == expected