コード例 #1
0
ファイル: test_block.py プロジェクト: Solomon1732/bami
    def test_create_next_pers(self, monkeypatch):
        """
        Test creating a block that points towards a previous block
        """
        db = MockDBManager()
        prev = FakeBlock()

        monkeypatch.setattr(
            MockDBManager,
            "get_chain",
            lambda _, chain_id: MockChain(),
        )
        monkeypatch.setattr(
            MockChain,
            "consistent_terminal",
            Links((prev.pers_dot, )),
        )

        block = BamiBlock.create(b"test", encode_raw({b"id": 42}), db,
                                 prev.public_key)

        assert block.previous == Links((prev.pers_dot, ))
        assert block.sequence_number == prev.sequence_number + 1
        assert block.public_key == prev.public_key
        assert block.signature == EMPTY_SIG
        assert block.type == b"test"
        assert block.transaction == encode_raw({b"id": 42})
        assert block.com_id == EMPTY_PK
        assert block.com_seq_num == UNKNOWN_SEQ
コード例 #2
0
ファイル: test_block.py プロジェクト: devos50/noodle
    def test_create_link_to_com_chain(self, monkeypatch):
        """
        Test creating a linked half that points back towards a previous block
        """
        key = default_eccrypto.generate_key(u"curve25519")
        com_key = default_eccrypto.generate_key(u"curve25519").pub().key_to_bin()
        db = MockDBManager()
        com_link = Links(((1, ShortKey("30303030")),))
        link = FakeBlock(com_id=com_key, links=com_link)

        monkeypatch.setattr(
            MockDBManager,
            "get_chain",
            lambda _, chain_id: MockChain() if chain_id == com_key else None,
        )
        monkeypatch.setattr(
            MockChain, "consistent_terminal", Links((link.com_dot,)),
        )
        block = BamiBlock.create(
            b"test", encode_raw({"id": 42}), db, key.pub().key_to_bin(), com_id=com_key
        )

        # include the personal community

        # Attach to the
        assert block.links == Links((link.com_dot,))
        assert block.previous == Links((GENESIS_DOT,))
        assert block.sequence_number == GENESIS_SEQ
        assert block.com_seq_num == link.com_seq_num + 1
        assert block.public_key == key.pub().key_to_bin()
        assert block.signature == EMPTY_SIG
        assert block.type == b"test"
        assert block.transaction == encode_raw({"id": 42})
        assert block.com_id == com_key
コード例 #3
0
    def add_block(self, block_blob: bytes, block: "PlexusBlock") -> None:

        block_hash = block.hash
        block_tx = block.transaction

        # 1. Add block blob and transaction blob to the block storage
        self.block_store.add_block(block_hash, block_blob)
        self.block_store.add_tx(block_hash, block_tx)
        self.block_store.add_extra(block_hash,
                                   encode_raw({b"type": block.type}))

        # 2. There are two chains: personal and community chain
        pers = block.public_key
        com = block.com_id

        if pers == com:
            pers = block.com_prefix + pers
            com = block.com_prefix + com
        else:
            com = block.com_prefix + com

        # 2.1: Process the block wrt personal chain
        if pers not in self.chains:
            self.chains[pers] = self.chain_factory.create_chain()

        pers_block_dot = Dot((block.sequence_number, block.short_hash))
        pers_dots_list = self.chains[pers].add_block(block.previous,
                                                     block.sequence_number,
                                                     block_hash)
        full_dot_id = pers + encode_raw(pers_block_dot)
        self.block_store.add_dot(full_dot_id, block_hash)
        # TODO: add more chain topic

        # Notify subs of the personal chain
        self.notify(ChainTopic.ALL, chain_id=pers, dots=pers_dots_list)
        self.notify(ChainTopic.PERSONAL, chain_id=pers, dots=pers_dots_list)
        self.notify(pers, chain_id=pers, dots=pers_dots_list)

        # 2.2: add block to the community chain

        if com != EMPTY_PK:
            if com == pers:
                # Chain was processed already, notify rest
                self.notify(ChainTopic.GROUP,
                            chain_id=com,
                            dots=pers_dots_list)
            else:
                if com not in self.chains:
                    self.chains[com] = self.chain_factory.create_chain()
                com_block_dot = Dot((block.com_seq_num, block.short_hash))
                com_dots_list = self.chains[com].add_block(
                    block.links, block.com_seq_num, block_hash)
                full_dot_id = com + encode_raw(com_block_dot)
                self.block_store.add_dot(full_dot_id, block_hash)

                self.notify(ChainTopic.ALL, chain_id=com, dots=com_dots_list)
                self.notify(ChainTopic.GROUP, chain_id=com, dots=com_dots_list)
                self.notify(com, chain_id=com, dots=com_dots_list)
コード例 #4
0
ファイル: community.py プロジェクト: devos50/noodle
 def spend(
     self,
     chain_id: bytes,
     counter_party: bytes,
     value: Decimal,
     ignore_validation: bool = False,
 ) -> None:
     """
     Spend tokens in the chain to the counter_party.
     Args:
         chain_id: identity of the chain
         counter_party: identity of the counter-party
         value: Decimal value to transfer
         ignore_validation: if True and balance is negative - will raise an Exception
     """
     bal = self.state_db.get_balance(self.my_pub_key_bin)
     if ignore_validation or bal - value >= 0:
         spend_tx = {
             b"value": float(value),
             b"to_peer": counter_party,
             b"prev_pairwise_link": self.state_db.get_last_pairwise_links(
                 self.my_pub_key_bin, counter_party
             ),
         }
         self.verify_spend(self.my_pub_key_bin, spend_tx)
         block = self.create_signed_block(
             block_type=SPEND_TYPE, transaction=encode_raw(spend_tx), com_id=chain_id
         )
         self.logger.info("Created spend block %s", block.com_dot)
         counter_peer = self.get_peer_by_key(counter_party, chain_id)
         if counter_peer:
             self.send_block(block, [counter_peer])
         self.share_in_community(block, chain_id)
     else:
         raise InsufficientBalanceException("Not enough balance for spend")
コード例 #5
0
 def get_block_blob_by_dot(self, chain_id: bytes,
                           block_dot: Dot) -> Optional[bytes]:
     dot_id = chain_id + encode_raw(block_dot)
     blk_hash = self.block_store.get_hash_by_dot(dot_id)
     if blk_hash:
         return self.block_store.get_block_by_hash(blk_hash)
     else:
         return None
コード例 #6
0
 def get_extra_by_dot(self, chain_id: bytes,
                      block_dot: Dot) -> Optional[bytes]:
     dot_id = chain_id + encode_raw(block_dot)
     hash_val = self.block_store.get_hash_by_dot(dot_id)
     if hash_val:
         return self.block_store.get_extra(hash_val)
     else:
         return None
コード例 #7
0
ファイル: test_block.py プロジェクト: Solomon1732/bami
    def test_create_genesis(self):
        """
        Test creating a genesis block
        """
        key = default_eccrypto.generate_key(u"curve25519")
        db = MockDBManager()
        block = BamiBlock.create(b"test", encode_raw({b"id": 42}), db,
                                 key.pub().key_to_bin())

        assert block.previous == Links((GENESIS_DOT, ))
        assert block.sequence_number == GENESIS_SEQ
        assert block.public_key == key.pub().key_to_bin()
        assert block.signature == EMPTY_SIG
        assert block.type == b"test"
        assert block.transaction == encode_raw({b"id": 42})
        assert block.com_id == EMPTY_PK
        assert block.com_seq_num == UNKNOWN_SEQ
コード例 #8
0
def test_decimal():
    new_con = getcontext()
    new_con.prec = 4
    t = Decimal(2.191, new_con)
    t2 = Decimal(2.11, new_con)

    l = encode_raw({b"value": float(t2)})
    p = decode_raw(l)
    assert p.get(b"value") == float(t2)
コード例 #9
0
ファイル: test_backbone.py プロジェクト: Solomon1732/bami
async def test_block_confirm(set_vals):
    """
    Test whether blocks are confirmed correctly.
    """
    block = set_vals.nodes[0].overlay.create_signed_block(
        com_id=set_vals.community_id,
        transaction=encode_raw({b"to_peer": 3}),
        block_type=b"good",
    )
    set_vals.nodes[0].overlay.share_in_community(block, set_vals.community_id)
    await deliver_messages()
コード例 #10
0
ファイル: community.py プロジェクト: devos50/noodle
 def reject(self, block: BamiBlock, extra_data: Dict = None) -> None:
     # change it to confirm
     # create claim block and share in the community
     chain_id = block.com_id if block.com_id != EMPTY_PK else block.public_key
     dot = block.com_dot if block.com_id != EMPTY_PK else block.pers_dot
     reject_tx = {b"initiator": block.public_key, b"dot": dot}
     if extra_data:
         reject_tx.update(extra_data)
     block = self.create_signed_block(
         block_type=REJECT_TYPE, transaction=encode_raw(reject_tx), com_id=chain_id
     )
     self.share_in_community(block, chain_id)
コード例 #11
0
ファイル: community.py プロジェクト: devos50/noodle
 def confirm(self, block: BamiBlock, extra_data: Dict = None) -> None:
     """Create confirm block linked to block. Link will be in the transaction with block dot.
        Add extra data to the transaction with a 'extra_data' dictionary.
     """
     chain_id = block.com_id if block.com_id != EMPTY_PK else block.public_key
     dot = block.com_dot if block.com_id != EMPTY_PK else block.pers_dot
     confirm_tx = {b"initiator": block.public_key, b"dot": dot}
     if extra_data:
         confirm_tx.update(extra_data)
     block = self.create_signed_block(
         block_type=CONFIRM_TYPE, transaction=encode_raw(confirm_tx), com_id=chain_id
     )
     self.share_in_community(block, chain_id)
コード例 #12
0
    def std_vals(self):
        self.chain_id = b"chain_id"
        self.block_dot = Dot((3, ShortKey("808080")))
        self.block_dot_encoded = encode_raw(self.block_dot)
        self.dot_id = self.chain_id + self.block_dot_encoded

        self.test_hash = b"test_hash"
        self.tx_blob = b"tx_blob"
        self.block_blob = b"block_blob"

        self.test_block = FakeBlock()
        self.pers = self.test_block.public_key
        self.com_id = self.test_block.com_id
コード例 #13
0
ファイル: conftest.py プロジェクト: devos50/noodle
    def __init__(
        self,
        transaction: bytes = None,
        previous: Links = None,
        key: LibNaCLSK = None,
        links: Links = None,
        com_prefix: bytes = b"",
        com_id: Any = None,
        block_type: bytes = b"test",
    ):
        crypto = default_eccrypto
        if not links:
            links = GENESIS_LINK
            com_seq_num = 1
        else:
            com_seq_num = max(links)[0] + 1

        if not previous:
            previous = GENESIS_LINK
        pers_seq_num = max(previous)[0] + 1

        if not com_id:
            com_id = crypto.generate_key(u"curve25519").pub().key_to_bin()

        if key:
            self.key = key
        else:
            self.key = crypto.generate_key(u"curve25519")

        if not transaction:
            transaction = encode_raw({"id": 42})

        BamiBlock.__init__(
            self,
            (
                block_type,
                transaction,
                self.key.pub().key_to_bin(),
                pers_seq_num,
                encode_links(previous),
                encode_links(links),
                com_prefix,
                com_id,
                com_seq_num,
                EMPTY_SIG,
                0,
                0,
            ),
        )
        self.sign(self.key)
コード例 #14
0
ファイル: state_sync.py プロジェクト: devos50/noodle
 def request_state(
     self,
     peer: Peer,
     chain_id: bytes,
     state_id: Any = None,
     include_other_witnesses: bool = True,
 ):
     self.logger.debug("Requesting state from a peer (%s) ", peer)
     state_request = {
         "state": state_id,
         "include_others": include_other_witnesses
     }
     self.send_packet(peer,
                      StateRequestPayload(chain_id,
                                          encode_raw(state_request)),
                      sig=True)
コード例 #15
0
ファイル: community.py プロジェクト: devos50/noodle
 def mint(self, value: Decimal = None, chain_id: bytes = None) -> None:
     """
     Create mint for own reputation: Reputation & Liveness  at Stake
     """
     if not value:
         value = self.settings.initial_mint_value
     if not chain_id:
         # Community id is the same as the peer id
         chain_id = self.my_pub_key_bin
     # Mint transaction: value
     mint_tx = {b"value": float(value)}
     self.verify_mint(chain_id, self.my_pub_key_bin, mint_tx)
     block = self.create_signed_block(
         block_type=MINT_TYPE, transaction=encode_raw(mint_tx), com_id=chain_id
     )
     self.share_in_community(block, chain_id)
コード例 #16
0
    def test_val(self):
        val = Decimal(10, self.con)
        l = encode_raw({b"123": float(val)})
        d = decode_raw(l)
        print(d)

        l = cachetools.LRUCache(10)
        l[1] = "v"
        int_max = 9999
        k = 4
        try:
            v = min(l.keys(), key=lambda x: abs(x - k) if x >= k else int_max)
            if v < k:
                # No data yet:
                pass
        except ValueError:
            print("No data for the chain")
コード例 #17
0
ファイル: community.py プロジェクト: devos50/noodle
 def create_introduction_response(
     self,
     lan_socket_address,
     socket_address,
     identifier,
     introduction=None,
     extra_bytes=b"",
     prefix=None,
 ):
     extra_bytes = encode_raw(self.my_subcoms)
     return super().create_introduction_response(
         lan_socket_address,
         socket_address,
         identifier,
         introduction,
         extra_bytes,
         prefix,
     )
コード例 #18
0
ファイル: block_sync.py プロジェクト: Solomon1732/bami
    def create_signed_block(
        self,
        block_type: bytes = b"unknown",
        transaction: Optional[bytes] = None,
        prefix: bytes = b"",
        com_id: bytes = None,
        links: Links = None,
        personal_links: Links = None,
        use_consistent_links: bool = True,
    ) -> BamiBlock:
        """
        This function will create, sign, persist block with given parameters.
        Args:
            block_type: bytes of the block
            transaction: bytes blob of the transaction, or None to indicate an empty transaction payload
            prefix: prefix for the community id. For example b'w' - for witnessing transactions
            com_id: sub-community id if applicable
            links: explicitly link to certain links in the sub-community. Warning - may lead to forks!
            personal_links: explicitly link to certain blocks in the own chain. Warning - may lead to forks!
            use_consistent_links ():
        Returns:
            signed block
        """
        if not transaction:
            transaction = encode_raw(b"")

        block = BamiBlock.create(
            block_type,
            transaction,
            self.persistence,
            self.my_pub_key_bin,
            com_id=com_id,
            com_links=links,
            pers_links=personal_links,
            com_prefix=prefix,
            use_consistent_links=use_consistent_links,
        )
        block.sign(self.my_peer_key)
        self.validate_persist_block(block, self.my_peer)
        return block
コード例 #19
0
ファイル: community.py プロジェクト: devos50/noodle
 def build_witness_blob(self, chain_id: bytes, seq_num: int) -> Optional[bytes]:
     chain_state = self.state_db.get_closest_peers_status(chain_id, seq_num)
     if not chain_state:
         return None
     return encode_raw(chain_state)
コード例 #20
0
ファイル: community.py プロジェクト: devos50/noodle
 def create_introduction_request(
     self, socket_address: Any, extra_bytes: bytes = b""
 ):
     extra_bytes = encode_raw(self.my_subcoms)
     return super().create_introduction_request(socket_address, extra_bytes)
コード例 #21
0
def test_encode_decode_bytelist():
    vals = {b"1", b"2", b"3", b"4", b"100", b"10", b"21", b"5"}
    assert set(decode_raw(encode_raw(list(vals)))) == vals
コード例 #22
0
def test_encode_decode_raw():
    vals = {b"id": 42}
    assert decode_raw(encode_raw(vals))[b"id"] == 42
コード例 #23
0
ファイル: community.py プロジェクト: devos50/noodle
 def notify_peers_on_new_subcoms(self) -> None:
     for peer in self.get_peers():
         self.send_packet(
             peer,
             SubscriptionsPayload(self.my_pub_key_bin, encode_raw(self.my_subcoms)),
         )
コード例 #24
0
 def to_bytes(self) -> bytes:
     return encode_raw({
         b"t": self.terminal,
         b"h": self.holes,
         b"i": self.inconsistencies
     })
コード例 #25
0
 def to_bytes(self) -> bytes:
     return encode_raw({b"m": self.missing, b"c": self.conflicts})