Beispiel #1
0
    def enter_any(self, prev_state):
        time.sleep(10)

        self.log.notice("Delegate connecting to other nodes ..")
        # Sub to other delegates
        for delegate_vk in VKBook.get_delegates():
            # Do not sub to ourself
            if delegate_vk == self.parent.verifying_key:
                continue

            self.parent.composer.add_sub(vk=delegate_vk, filter=delegate_delegate)

        # Sub to witnesses
        for witness_vk in VKBook.get_witnesses():
            self.parent.composer.add_sub(vk=witness_vk, filter=witness_delegate)

        # Pub on our own url
        self.parent.composer.add_pub(ip=self.parent.ip)

        # Add router socket
        self.parent.composer.add_router(ip=self.parent.ip)

        # Add dealer and sub socket for Masternodes
        for mn_vk in VKBook.get_masternodes():
            self.parent.composer.add_dealer(vk=mn_vk)
            self.parent.composer.add_sub(vk=mn_vk, filter=masternode_delegate)

        # Sleep for a bit while the daemon sets up these sockets TODO find a more reactive solution
        time.sleep(20)

        # Once done with boot state, transition to catchup
        self.parent.transition(DelegateCatchupState)
Beispiel #2
0
    def validate_sig(self, sig: MerkleSignature) -> bool:
        assert self.merkle is not None, "Cannot validate signature without our merkle set"
        self.log.debugv("Validating signature: {}".format(sig))

        # Verify sender's vk exists in the state
        if sig.sender not in VKBook.get_delegates():
            self.log.warning("Received merkle sig from sender {} who was not registered nodes {}"
                             .format(sig.sender, VKBook.get_delegates()))
            return False

        # Verify we haven't received this signature already
        if sig in self.signatures:
            self.log.warning("Already received a signature from sender {}".format(sig.sender))
            return False

        # Below is just for debugging, so we can see if a signature cannot be verified
        if not sig.verify(self.merkle.root):
            self.log.warning("Delegate could not verify signature! Different Merkle trees.\nSig: {}".format(sig))

        return sig.verify(self.merkle.root)
Beispiel #3
0
    def _check_ready(self):
        """
        Checks if the system is 'ready' (as described in the MNStagingState docstring). If all conditions are met,
        this function will transition to MNRunState.
        """
        # TODO for dev we require all delegates online. IRL a 2/3 majority should suffice
        # majority = VKBook.get_delegate_majority()
        majority = len(VKBook.get_delegates())

        num_ready = len(self.ready_delegates)

        if num_ready >= majority:
            self.log.important(
                "{}/{} Delegates are at the latest blockchain state! MN exiting StagingState."
                "\n(Ready Delegates = {})".format(num_ready,
                                                  len(VKBook.get_delegates()),
                                                  self.ready_delegates))
            self.parent.transition(MNRunState)
            return
        else:
            self.log.notice(
                "Only {} of {} required delegate majority ready. MN remaining in StagingState"
                .format(num_ready, majority))
Beispiel #4
0
    def enter_any(self, prev_state):
        # Add publisher socket for sending NewBlockNotifications to delegates
        self.parent.composer.add_pub(ip=self.parent.ip,
                                     port=MN_NEW_BLOCK_PUB_PORT)

        # Add router socket
        self.parent.composer.add_router(ip=self.parent.ip)

        # Add dealer sockets to TESTNET_DELEGATES, for purposes of requesting block data
        for vk in VKBook.get_delegates():
            self.parent.composer.add_dealer(vk=vk)

        # Once done booting, transition to staging
        self.parent.transition(MNStagingState)
Beispiel #5
0
    def enter_any(self, prev_state):
        self.log.debug("MN IP: {}".format(self.parent.ip))

        # Add publisher socket
        self.parent.composer.add_pub(ip=self.parent.ip)

        # Add router socket
        self.parent.composer.add_router(ip=self.parent.ip)

        # Add dealer sockets to delegates, for purposes of requesting block data
        for vk in VKBook.get_delegates():
            self.parent.composer.add_dealer(vk=vk)

        # Once done booting, transition to run
        self.parent.transition(MNRunState)
Beispiel #6
0
    def handle_blockmeta_request(self, request: BlockMetaDataRequest,
                                 envelope: Envelope):
        vk = envelope.seal.verifying_key
        assert vk in VKBook.get_delegates(
        ), "Got BlockMetaDataRequest from VK {} not in delegate VKBook!".format(
            vk)
        self.log.notice(
            "Masternode received BlockMetaDataRequest from delegate {}\n...request={}"
            .format(vk, request))

        # Get a list of block hashes up until this most recent block
        # TODO get_child_block_hashes return an error/assertion/something if block cannot be found
        child_hashes = BlockStorageDriver.get_child_block_hashes(
            request.current_block_hash)
        self.log.debugv(
            "Got descendant block hashes {} for block hash {}".format(
                child_hashes, request.current_block_hash))

        # If this hash could not be found or if it was the latest hash, no need to lookup any blocks
        if not child_hashes:
            self.log.debug(
                "Requested block hash {} is already up to date".format(
                    request.current_block_hash))
            reply = BlockMetaDataReply.create(block_metas=None)
            return reply

        # Build a BlockMetaData object for each descendant block
        block_metas = []
        for block_hash in child_hashes:
            block_data = BlockStorageDriver.get_block(hash=block_hash,
                                                      include_number=False)
            meta = BlockMetaData.create(**block_data)
            block_metas.append(meta)

        reply = BlockMetaDataReply.create(block_metas=block_metas)
        return reply