def __init__(self, vote_type: int=VoteMessageType.success, block_height: int=-1, block_hash: str=None, signature=b"", leader_id: str=None, peer_id: str=None, channel_name: str= None): """ VoteMessage class to vote block, leader complain and leader ready. :param vote_type: A vote type of VoteType attributes. :param block_hash: The precommit block hash :param block_height: The precommit block height :param signature: RecoverableSign to Base64 :param leader_id: An expected new leader id :param peer_id: The Peer ID of this vote. """ self.__type: int = vote_type self.__block_hash: str = block_hash self.__block_height: int = block_height self.__signature: bytes = signature self.__leader_id: str = leader_id self.__peer_id = peer_id self.__channel_name = channel_name self.__hash = None self.__hash_generator = build_hash_generator(1, None)
def __init__(self, hash_generator_version: int, raise_exceptions=True): self.exceptions = [] self._hash_generator = build_hash_generator(hash_generator_version, self._hash_salt) self._tx_serializer = None self._raise_exceptions = raise_exceptions
def __init__(self, private_key=None): self.__private_key = private_key or PrivateKey() self.__address = self.create_address(self.__private_key.pubkey) self.__last_tx_hash = "" tx_hash_versions = conf.CHANNEL_OPTION[conf.LOOPCHAIN_DEFAULT_CHANNEL]["hash_versions"] self.__hash_generators = { "0x2": build_hash_generator(tx_hash_versions["0x2"], "icx_sendTransaction"), "0x3": build_hash_generator(tx_hash_versions["0x3"], "icx_sendTransaction") } self.to_address = None self.value = None self.message = None self.fee = ICX_FEE self.nid = '0x3' self.is_logging = True
def __init__(self, hash_generator_version: int): self._hash_generator = build_hash_generator(hash_generator_version, self._hash_salt) # Attributes that must be assigned self.signer: 'Signer' = None # Attributes to be generated self.from_address: 'ExternalAddress' = None self.hash: 'Hash32' = None self.signature: 'Signature' = None self.origin_data: dict = None self.raw_data: dict = None
def __init__(self, hash_generator_version: int): self._hash_generator = build_hash_generator(hash_generator_version, self._hash_salt)
# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from abc import ABC, abstractmethod from typing import Generic, TypeVar from dataclasses import dataclass from loopchain.blockchain.types import ExternalAddress, Signature, Hash32 from loopchain.crypto.hashing import build_hash_generator from loopchain.crypto.signature import SignVerifier, Signer TResult = TypeVar("TResult") hash_generator = build_hash_generator(1, "icx_vote") @dataclass(frozen=True) class Vote(ABC, Generic[TResult]): rep: ExternalAddress timestamp: int signature: Signature def origin_args(self): args = dict(self.__dict__) args.pop("signature", None) return args def hash(self): return self.to_hash(**self.origin_args())
def setUp(self): test_util.print_testname(self._testMethodName) self.hash_generator = build_hash_generator(1, "icx_sendTransaction")
def test_genesis_hash_compatibility(self): genesis_init_data = { "transaction_data": { "accounts": [ { "name": "god", "address": "hxebf3a409845cd09dcb5af31ed5be5e34e2af9433", "balance": "0x2961ffa20dd47f5c4700000" }, { "name": "treasury", "address": "hxd5775948cb745525d28ec8c1f0c84d73b38c78d4", "balance": "0x0" }, { "name": "test1", "address": "hx670e692ffd3d5587c36c3a9d8442f6d2a8fcc795", "balance": "0x0" }, { "name": "test2", "address": "hxdc8d79453ba6516bc140b7f53b6b9a012da7ff10", "balance": "0x0" }, { "name": "test3", "address": "hxbedeeadea922dc7f196e22eaa763fb01aab0b64c", "balance": "0x0" }, { "name": "test4", "address": "hxa88d8addc6495e4c21b0dda5b0bf6c9108c98da6", "balance": "0x0" }, { "name": "test5", "address": "hx0260cc5b8777485b04e9dc938b1ee949910f41e1", "balance": "0x0" }, { "name": "test6", "address": "hx09e89b468a1cdfdd24441668204911502fa3add9", "balance": "0x0" }, { "name": "test7", "address": "hxeacd884f0e0b5b2e4a6b4ee87fa5184ab9f25cbe", "balance": "0x0" }, { "name": "test8", "address": "hxa943122f57c7c2af7416c1f2e1af46838ad0958f", "balance": "0x0" }, { "name": "test9", "address": "hxc0519e1c56030be070afc89fbf05783c89b15e2f", "balance": "0x0" }, { "name": "test10", "address": "hxcebc788d5b922b356a1dccadc384d36964e87165", "balance": "0x0" }, { "name": "test11", "address": "hx7f8f432ffdb5fc1d2df6dd452ca52eb719150f3c", "balance": "0x0" }, { "name": "test12", "address": "hxa6c4468032824092ecdb3de2bb66947d69e07b59", "balance": "0x0" }, { "name": "test13", "address": "hxc26d0b28b11732b38c0a2c0634283730258f272a", "balance": "0x0" }, { "name": "test14", "address": "hx695ddb2d1e78f012e3e271e95ffbe4cc8fcd133b", "balance": "0x0" }, { "name": "test15", "address": "hx80ab6b11b5d5c80448d011d10fb1a579c57e0a6c", "balance": "0x0" }, { "name": "test16", "address": "hxa9c7881a53f2245ed12238412940c6f54874c4e3", "balance": "0x0" }, { "name": "test17", "address": "hx4e53cffe116baaff5e1940a6a0c14ad54f7534f2", "balance": "0x0" }, { "name": "test18", "address": "hxbbef9e3942d3d5d83b5293b3cbc20940b459e3eb", "balance": "0x0" } ], "message": "A rHizomE has no beGInning Or enD; it is alWays IN the miDDle, between tHings, interbeing, intermeZzO. ThE tree is fiLiatioN, but the rhizome is alliance, uniquelY alliance. The tree imposes the verb \"to be\" but the fabric of the rhizome is the conJUNction, \"AnD ... and ...and...\"THis conJunction carriEs enouGh force to shaKe and uproot the verb \"to be.\" Where are You goIng? Where are you coMing from? What are you heading for? These are totally useless questions.\n\n- 『Mille Plateaux』, Gilles Deleuze & Felix Guattari\n\n\"Hyperconnect the world\"" } } genesis_hash_generator = build_hash_generator(0, "genesis_tx") genesis_tx_hash = genesis_hash_generator.generate_hash(genesis_init_data["transaction_data"]) self.assertEqual(genesis_tx_hash, Hash32.fromhex("0x6dbc389370253739f28b8c236f4e7acdcfcdb9cfe8386c32d809114d5b00ac65"))
def test_hash_case_v2_v3_compatibility(self): # These methods are obsolete. # But this one and new one must have same results for v2 request. def create_origin_for_hash(json_data: dict): def gen_origin_str(json_data: dict): ordered_keys = list(json_data) ordered_keys.sort() for key in ordered_keys: yield key if isinstance(json_data[key], str): yield json_data[key] elif isinstance(json_data[key], dict): yield from gen_origin_str(json_data[key]) elif isinstance(json_data[key], int): yield str(json_data[key]) else: raise TypeError(f"{key} must be one of them(dict, str, int).") origin = ".".join(gen_origin_str(json_data)) return origin def generate_icx_hash(icx_origin_data, tx_hash_key): copy_tx = copy.deepcopy(icx_origin_data) if 'method' in copy_tx: del copy_tx['method'] if 'signature' in copy_tx: del copy_tx['signature'] if tx_hash_key in copy_tx: del copy_tx[tx_hash_key] origin = create_origin_for_hash(copy_tx) origin = f"icx_sendTransaction.{origin}" # gen hash return hashlib.sha3_256(origin.encode()).digest() request = r'''{ "jsonrpc": "2.0", "method": "icx_sendTransaction", "id": 1234, "params": { "version": "0x3", "from": "hxbe258ceb872e08851f1f59694dac2558708ece11", "to": "hx5bfdb090f43a808005ffc27c25b213145e80b7cd", "value": "0xde0b6b3a7640000", "timestamp": "0x563a6cf330136", "nonce": "0x1", "stepLimit": "0x100000", "nid": "0x2", "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=" } }''' logging.info(f"request : {request}") request = json.loads(request) logging.info(f"request loaded : {request}") question = request["params"] tv = TransactionVersioner() version, type_ = tv.get_version(question) ts = TransactionSerializer.new(version, type_, tv) tx = ts.from_(question) result_new_hash = self.hash_generator.generate_hash(ts.to_origin_data(tx)) result_old_hash = generate_icx_hash(question, "tx_hash") self.assertEqual(result_new_hash, result_old_hash) v0_hash_generator = build_hash_generator(0, "icx_sendTransaction") result_old_hash = v0_hash_generator.generate_hash(ts.to_origin_data(tx)) self.assertEquals(result_new_hash, result_old_hash)
return NextRepsChangeReason.NoChange if self.next_leader == ExternalAddress.empty(): return NextRepsChangeReason.TermEnd return NextRepsChangeReason.Penalty @property def is_unrecorded(self) -> bool: """Return is unrecorded block :return: bool """ return (self.next_leader == ExternalAddress.empty() and self.reps_hash == self.next_reps_hash == Hash32.empty()) @property def revealed_next_reps_hash(self): if self.prep_changed: return self.next_reps_hash return self.reps_hash @dataclass(frozen=True) class BlockBody(BaseBlockBody): leader_votes: List[LeaderVote] prev_votes: List[BlockVote] receipts_hash_generator = build_hash_generator(1, "icx_receipt")