def get_example_genesis_block():
    return Block.deserialize(computer(
        """000000000000000000000000000000000000000000000000000000000000000000008278968af4bd613aa24a5ccd5280211b3101e3"""
        """ff62621bb11500509d1bbe2a956046240b0100000000000000000000000000000000000000000000000000000000000000000000d7"""
        """38f2c472180cb401f650b12be96ec25bfd9b4e9908c6c9089d9bf26401646f87000000000000000000000000000000000000000000"""
        """0000000000000000000000077a14cfbe21d47f367f23f9a464c765541b1b07bef9f5a95901e0bffe3a1a2f01000100000000000000"""
        """000000000000000000000000000000000000000000000000000000000001000000000001000000012a05f200027878787878787878"""
        """7878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878"""
        """787878"""))
예제 #2
0
    def handle_mined_block(self, block: Block) -> None:
        self.coinstate = self.coinstate.add_block(block, int(time()))
        with open(Path('chain') / block_filename(block), 'wb') as f:
            f.write(block.serialize())

        self.send_message("found_block", block_filename(block))
        self.send_message("balance", self.get_balance())

        self.thread.local_peer.chain_manager.set_coinstate(self.coinstate)
        self.thread.local_peer.network_manager.broadcast_block(block)
예제 #3
0
def _read_chain_from_disk(max_height):
    coinstate = CoinState.zero()

    for file_path in sorted(CHAIN_TESTDATA_PATH.iterdir()):
        height = int(file_path.name.split("-")[0])
        if height > max_height:
            return coinstate

        block = Block.stream_deserialize(open(file_path, 'rb'))
        coinstate = coinstate.add_block_no_validation(block)

    return coinstate
예제 #4
0
def read_chain_from_disk():
    print("Reading chain from disk")
    coinstate = CoinState.zero()
    for filename in sorted(os.listdir('chain')):
        height = int(filename.split("-")[0])
        if height % 1000 == 0:
            print(filename)

        block = Block.stream_deserialize(open(Path('chain') / filename, 'rb'))
        coinstate = coinstate.add_block_no_validation(block)

    return coinstate
예제 #5
0
    def handle_scrypt_output_message(self, miner_id: int, data: bytes) -> None:
        summary_hash: bytes = data

        self.increment_hash_counter()

        summary, current_height, transactions = self.mining_args[miner_id]

        evidence = construct_pow_evidence_after_scrypt(summary_hash,
                                                       self.coinstate, summary,
                                                       current_height,
                                                       transactions)

        block = Block(BlockHeader(summary, evidence), transactions)

        if block.hash() >= block.target:
            # we didn't mine the block
            return

        self.network_thread.local_peer.chain_manager.set_coinstate(
            self.coinstate)
        self.network_thread.local_peer.network_manager.broadcast_block(block)

        self.coinstate = self.coinstate.add_block(block, int(time()))

        # Originally there was a disk write in this spot. During testing of the chain.cache changes,
        # it was found there is a race condition between the mining thread and the networking thread.
        # Better to skip the write here and just let the networking thread do it.

        print(f"miner {miner_id} found block: {block_filename(block)}")

        # get new public key for miner
        self.public_key = self.wallet.get_annotated_public_key(
            "reserved for potentially mined block")
        save_wallet(self.wallet)

        self.balance = self.wallet.get_balance(
            self.coinstate) / Decimal(SASHIMI_PER_COIN)
예제 #6
0
def _read_chain_from_disk(max_height):
    # the requirement to run these tests from an environment that has access to the real blockchain is hard-coded (for
    # now)

    coinstate = CoinState.zero()

    for filename in sorted(os.listdir('chain')):
        height = int(filename.split("-")[0])
        if height > max_height:
            return coinstate

        block = Block.stream_deserialize(open(Path('chain') / filename, 'rb'))
        coinstate = coinstate.add_block_no_validation(block)

    return coinstate
예제 #7
0
def read_chain_from_disk():
    print("Reading chain from disk")
    coinstate = CoinState.zero()
    for filename in sorted(os.listdir('chain')):
        height = int(filename.split("-")[0])
        if height % 1000 == 0:
            print(filename)

        try:
            block = Block.stream_deserialize(open(Path('chain') / filename, 'rb'))
        except Exception as e:
            raise Exception("Corrupted block on disk: %s" % filename) from e

        coinstate = coinstate.add_block_no_validation(block)

    return coinstate
예제 #8
0
def read_chain_from_disk() -> CoinState:
    if os.path.isfile('chain.cache'):
        print("Reading cached chain")
        with open('chain.cache', 'rb') as file:
            coinstate = CoinState.load(lambda: pickle.load(file))
    else:
        coinstate = CoinState.zero()

    rewrite = False

    if os.path.isdir('chain'):
        # the code below is no longer needed by normal users, but some old testcases still rely on it:
        for filename in sorted(os.listdir('chain')):
            (height_str, hash_str) = filename.split("-")
            (height, hash) = (int(height_str), computer(hash_str))

            if hash not in coinstate.block_by_hash:

                if height % 1000 == 0:
                    print(filename)

                if os.path.getsize(f"chain/{filename}") == 0:
                    print("Stopping at empty block file: %s" % filename)
                    break

                with open(Path("chain") / filename, 'rb') as f:
                    try:
                        block = Block.stream_deserialize(f)
                    except Exception as e:
                        raise Exception("Corrupted block on disk: %s" % filename) from e
                    try:
                        coinstate = coinstate.add_block_no_validation(block)
                    except Exception:
                        print("Failed to add block at height=%d, previous_hash=%s"
                              % (block.height, human(block.header.summary.previous_block_hash)))
                        break

                rewrite = True

    if rewrite:
        DiskInterface().write_chain_cache_to_disk(coinstate)

    return coinstate
예제 #9
0
def test_validate_block_by_itself_invalid_coinbase_transaction():
    coinstate = CoinState.empty()

    transactions = [
        Transaction(inputs=[
            Input(
                OutputReference(b'x' * 32, 1),
                SECP256k1Signature(b'y' * 64),
            )
        ],
                    outputs=[Output(1, example_public_key)])
    ]

    summary = construct_minable_summary(coinstate, transactions, 1615209942,
                                        39)
    evidence = construct_pow_evidence(coinstate, summary, 0, transactions)
    block = Block(BlockHeader(summary, evidence), transactions)

    with pytest.raises(ValidateTransactionError, match=".*thin air.*"):
        validate_block_by_itself(block, 1615209942)
예제 #10
0
def test_block_serialization():
    block = Block(
        header=BlockHeader(
            summary=example_block_summary,
            pow_evidence=example_pow_evidence,
        ),
        transactions=[
            Transaction(
                inputs=[
                    Input(output_reference=OutputReference(b"b" * 32, 1234),
                          signature=SECP256k1Signature(b"b" * 64))
                ],
                outputs=[
                    Output(value=1582,
                           public_key=SECP256k1PublicKey(b"g" * 64))
                ],
            )
        ] * 2,
    )

    serialize_and_deserialize(block)
예제 #11
0
파일: manager.py 프로젝트: lk16/skepticoin
 def broadcast_block(self, block: Block) -> None:
     self.local_peer.logger.info("%15s ChainManager.broadcast_block(%s)" %
                                 ("", human(block.hash())))
     self.broadcast_message(DataMessage(DATA_BLOCK, block))
예제 #12
0
def read_chain_from_disk() -> CoinState:
    if os.path.isfile('chain.cache'):
        print("Reading cached chain")
        with open('chain.cache', 'rb') as file:
            coinstate = CoinState.load(lambda: pickle.load(file))
    else:
        try:
            print("Pre-download blockchain from trusted source to 'chain.zip'")
            with urllib.request.urlopen(TRUSTED_BLOCKCHAIN_ZIP) as resp:
                with open('chain.zip', 'wb') as outfile:
                    outfile.write(resp.read())
            print("Reading initial chain from zipfile")
            coinstate = CoinState.zero()
            with zipfile.ZipFile('chain.zip') as zip:
                for entry in zip.infolist():
                    if not entry.is_dir():
                        filename = entry.filename.split('/')[1]
                        height = int(filename.split("-")[0])
                        if height % 1000 == 0:
                            print(filename)

                        data = zip.read(entry)
                        block = Block.stream_deserialize(BytesIO(data))
                        coinstate = coinstate.add_block_no_validation(block)
        except Exception:
            print(
                "Error reading zip file. We'll start with an empty blockchain instead."
                + traceback.format_exc())
            coinstate = CoinState.zero()

    rewrite = False

    if os.path.isdir('chain'):
        # the code below is no longer needed by normal users, but some old testcases still rely on it:
        for filename in sorted(os.listdir('chain')):
            (height_str, hash_str) = filename.split("-")
            (height, hash) = (int(height_str), computer(hash_str))

            if hash not in coinstate.block_by_hash:

                if height % 1000 == 0:
                    print(filename)

                if os.path.getsize(f"chain/{filename}") == 0:
                    print("Stopping at empty block file: %s" % filename)
                    break

                with open(Path("chain") / filename, 'rb') as f:
                    try:
                        block = Block.stream_deserialize(f)
                    except Exception as e:
                        raise Exception("Corrupted block on disk: %s" %
                                        filename) from e
                    try:
                        coinstate = coinstate.add_block_no_validation(block)
                    except Exception:
                        print(
                            "Failed to add block at height=%d, previous_hash=%s"
                            %
                            (block.height,
                             human(block.header.summary.previous_block_hash)))
                        break

                rewrite = True

    if rewrite:
        DiskInterface().write_chain_cache_to_disk(coinstate)

    return coinstate
예제 #13
0
def block_filename(block: Block) -> str:
    return "%08d-%s" % (block.height, human(block.hash()))