示例#1
0
    def test_good_sbc_returns_true(self):
        tx_1 = {
            'something': 'who_cares'
        }

        tx_2 = {
            'something_else': 'who_cares'
        }

        txs = [encode(tx).encode() for tx in [tx_1, tx_2]]
        expected_tree = merklize(txs)

        w = Wallet()

        input_hash = 'something'
        signature = w.sign(expected_tree[0])

        sbc = {
            'subblock': 1,
            'transactions': [tx_1, tx_2],
            'input_hash': input_hash,
            'signer': w.verifying_key,
            'merkle_tree': {
                'signature': signature,
                'leaves': expected_tree
            }
        }

        s = contender.SBCInbox()

        self.assertTrue(s.sbc_is_valid(sbc, 1))
示例#2
0
    def test_merkle_leaf_complex_objects_works(self):
        tx_1_raw = b'{"hash": "503fa157e4d990f78f2b032731dffb398f6ff642b6bbc305817e24dd42b33402", "result": "None", "stamps_used": 198, "state": [{"key": "rewards.S:current_votes:masternodes", "value": 20}, {"key": "rewards.S:current_votes:delegates", "value": 20}, {"key": "rewards.S:current_votes:blackhole", "value": 5}, {"key": "rewards.S:current_votes:foundation", "value": 5}, {"key": "rewards.S:current_votes:developer", "value": 450}, {"key": "rewards.S:has_voted:b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "value": true}, {"key": "rewards.S:vote_count", "value": 5}, {"key": "rewards.S:value", "value": [{"__fixed__": "0.04"}, {"__fixed__": "0.04"}, {"__fixed__": "0.01"}, {"__fixed__": "0.01"}, {"__fixed__": "0.9"}]}, {"key": "rewards.S:election_start", "value": null}, {"key": "currency.balances:b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "value": {"__fixed__": "535.30200000"}}], "status": 0, "transaction": {"metadata": {"signature": "ceb4630c8be71f2c0c1e059790609fafa6ed948b7fceb4bb44c36dca46848fac8d55fe27f539036fee5bda6d772fff852b622393eab593aa6dce67f93f7d8f08", "timestamp": 1601411941}, "payload": {"contract": "election_house", "function": "vote", "kwargs": {"policy": "rewards", "value": [4, 4, 1, 1, 90]}, "nonce": 3, "processor": "5b09493df6c18d17cc883ebce54fcb1f5afbd507533417fe32c006009a9c3c4a", "sender": "b0fc27299da14bc08834df9c70d73074f3e511a5a91321d4fa413f3401144918", "stamps_supplied": 999}}}'

        tx_1 = decode(tx_1_raw)

        txs = [encode(tx).encode() for tx in [tx_1]]
        expected_tree = merklize(txs)

        w = Wallet()

        input_hash = 'something'
        signature = w.sign(expected_tree[0])

        sbc = {
            'subblock': 1,
            'transactions': [tx_1],
            'input_hash': input_hash,
            'signer': w.verifying_key,
            'merkle_tree': {
                'signature': signature,
                'leaves': expected_tree
            }
        }

        s = contender.SBCInbox()

        self.assertTrue(s.sbc_is_valid(sbc, 1))
示例#3
0
    def execute_work(self,
                     driver,
                     work,
                     wallet,
                     previous_block_hash,
                     current_height=0,
                     stamp_cost=20000,
                     parallelism=4):
        # Assume single threaded, single process for now.
        subblocks = []
        i = 0

        for tx_batch in work:
            results = self.execute_tx_batch(driver=driver,
                                            batch=tx_batch,
                                            timestamp=tx_batch['timestamp'],
                                            input_hash=tx_batch['input_hash'],
                                            stamp_cost=stamp_cost,
                                            bhash=previous_block_hash,
                                            num=current_height)

            if len(results) > 0:
                merkle = merklize([encode(r).encode() for r in results])
                proof = wallet.sign(merkle[0])
            else:
                merkle = merklize([bytes.fromhex(tx_batch['input_hash'])])
                proof = wallet.sign(tx_batch['input_hash'])

            merkle_tree = {'leaves': merkle, 'signature': proof}

            sbc = {
                'input_hash': tx_batch['input_hash'],
                'transactions': results,
                'merkle_tree': merkle_tree,
                'signer': wallet.verifying_key,
                'subblock': i % parallelism,
                'previous': previous_block_hash
            }

            sbc = format_dictionary(sbc)

            subblocks.append(sbc)
            i += 1

        return subblocks
示例#4
0
    def sbc_is_valid(self, sbc, sb_idx=0):
        if sbc['subblock'] != sb_idx:
            self.log.error(f'Subblock Contender[{sb_idx}] is out order.')
            return False

        # Make sure signer is in the delegates
        if len(sbc['transactions']) == 0:
            message = sbc['input_hash']
        else:
            message = sbc['merkle_tree']['leaves'][0]

        valid_sig = verify(vk=sbc['signer'],
                           msg=message,
                           signature=sbc['merkle_tree']['signature'])

        if not valid_sig:
            self.log.error(
                f'Subblock Contender[{sb_idx}] from {sbc["signer"][:8]} has an invalid signature.'
            )
            return False

        if len(sbc['merkle_tree']['leaves']) > 0:
            txs = [encode(tx).encode() for tx in sbc['transactions']]
            expected_tree = merklize(txs)

            # Missing leaves, etc
            if len(sbc['merkle_tree']['leaves']) != len(expected_tree) and len(
                    sbc['transactions']) > 0:
                self.log.error('Merkle Tree Len mismatch')
                return False

            for i in range(len(expected_tree)):
                if expected_tree[i] != sbc['merkle_tree']['leaves'][i]:
                    self.log.error(
                        f'Subblock Contender[{sbc["subblock"]}] from {sbc["signer"][:8]} has an Merkle tree proof.'
                    )
                    self.log.error(expected_tree[i])
                    self.log.error(txs[i])
                    return False

        self.log.info(
            f'Subblock[{sbc["subblock"]}] from {sbc["signer"][:8]} is valid.')

        return True
示例#5
0
    def test_process_message_good_and_bad_sbc_doesnt_pass_to_q(self):
        ### GOOD SBC
        tx_1_1 = {
            'something': 'who_cares'
        }

        tx_1_2 = {
            'something_else': 'who_cares'
        }

        txs = [encode(tx).encode() for tx in [tx_1_1, tx_1_2]]
        expected_tree = merklize(txs)

        w = Wallet()

        input_hash = 'something'
        signature = w.sign(expected_tree[0])

        sbc_1 = {
            'subblock': 0,
            'transactions': [tx_1_1, tx_1_2],
            'input_hash': input_hash,
            'signer': w.verifying_key,
            'merkle_tree': {
                'signature': signature,
                'leaves': expected_tree
            }
        }

        ### BAD SBC
        tx_2_1 = {
            'something': 'who_cares2'
        }

        tx_2_2 = {
            'something_else': 'who_cares2'
        }

        txs = [encode(tx).encode() for tx in [tx_2_1, tx_2_2]]
        expected_tree = merklize(txs)

        w = Wallet()

        input_hash = 'something2'
        signature = w.sign(expected_tree[0])

        expected_tree[1] = 'crap'

        sbc_2 = {
            'subblock': 1,
            'transactions': [tx_2_1, tx_2_2],
            'input_hash': input_hash,
            'signer': w.verifying_key,
            'merkle_tree': {
                'signature': signature,
                'leaves': expected_tree
            }
        }

        s = contender.SBCInbox()

        loop = asyncio.get_event_loop()
        if loop.is_closed():
            loop = asyncio.new_event_loop()
        loop.run_until_complete(s.process_message([sbc_1, sbc_2]))

        self.assertEqual(s.q, [])