def processor_trans_make(self, content):
        i_ = 0
        add_from = 0
        add_to = 1
        add_to_two = 0
        _address = [add_from, add_to, add_to_two]
        result = dict()
        # print(_address)
        fd = open('ad1.txt', 'r')
        line = fd.readlines()
        for i in _address:
            line_ = line[i].rstrip()
            pr, pu = line_.split('ENDDING')
            temp = bytes(pu[2:-1], encoding='utf-8')
            temp = temp.replace(b'\r\n', b'\n')
            public_key = temp.replace(b'\\n', b'\n')
            temp = bytes(pr[2:-1], encoding='utf-8')
            temp = temp.replace(b'\r\n', b'\n')
            private_key = temp.replace(b'\\n', b'\n')
            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash = sha.digest()
            result[i] = [public_key, private_key, public_key_hash]
        fd.close()

        for utxo in self.server.blockchain.utxo.utxo.items():
            if utxo[1]['to'] == result[
                    _address[0]][2] and utxo[0] not in self.server.Used:
                self.server.Used.append(utxo[0])
                # print('1')
                i_ = 1
                private_key = serialization.load_pem_private_key(
                    result[_address[0]][1], None, backend=default_backend())
                ipt = TransInput([utxo[0]], result[_address[0]][2])
                opt = TransOutput([
                    (utxo[1]['amount'] / 2, result[_address[1]][2]),
                    (utxo[1]['amount'] / 2, result[_address[2]][2])
                ])
                tran = Transaction(ipt, opt)
                tran.ready(private_key)
                content = trans_to_json(tran)
                requests.post('http://127.0.0.1:23390/transaction_post',
                              data=content)
                requests.post('http://127.0.0.1:23391/transaction_post',
                              data=content)

                _ = send_handler(MsgType.TYPE_RESPONSE_OK, tran.b)

                self.request.sendall(_)

                break
        if i_ == 0:
            _ = send_handler(MsgType.TYPE_RESPONSE_ERROR, b'')
            self.request.sendall(_)
        else:
            pass
    def test_002_trans_read(self):

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            header, length, msgtype, content = recv_parser(s)
            content = batch_parser(content)

            for i in content:
                Transaction.unpack(i)
            self.assertEqual(msgtype, MsgType.TYPE_RESPONSE_OK)
            self.assertEqual(len(content), 2)
    def processor_trans_write(self, content):
        result = self.server.transpool.add(content)
        tran = Transaction.unpack(content)
        # print(tran.show_trans())
        # print('ok3')
        if result:
            a = Transaction.unpack(content)
            _ = send_handler(MsgType.TYPE_RESPONSE_OK, b'')
            # print('trans_received')
            # print(a.timestamp)
            # print(time.time())
            # print(len(self.server.transpool.trans.queue))
        else:
            _ = send_handler(MsgType.TYPE_RESPONSE_ERROR, b'')

        self.request.sendall(_)
    def __get_trans(self) -> List[Transaction]:
        # self.chainbase_address
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            *_, msgtype, content = recv_parser(s)

            trans = []

            if msgtype == MsgType.TYPE_RESPONSE_OK:
                trans += batch_parser(content)

            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash = sha.digest()
            ipt = TransInput([(public_key_hash, 0)], public_key_hash)
            fd_ = open('ad1.txt', 'r')
            for index, line in enumerate(fd_.readlines()):
                if index == 0:
                    line = line.rstrip()
                    pr, pu = line.split('ENDDING')
                    temp = bytes(pu[2:-1], encoding='utf-8')
                    temp = temp.replace(b'\r\n', b'\n')
                    public_key = temp.replace(b'\\n', b'\n')
                    sha = hashlib.sha256()
                    sha.update(public_key)
                    public_key_hash = sha.digest()
                    break
            fd_.close()
            opt = TransOutput([(20, public_key_hash)])
            tran = Transaction(ipt, opt, 0)
            tran.ready(private_key)
            trans.append(tran.b)
            # result = self.get_miner_credit(public_key_hash, 5)
            # print(result)
            print('len = ', len(trans))
            return [Transaction.unpack(t) for t in trans]
Exemplo n.º 5
0
    def __get_trans(self) -> List[Transaction]:
        # self.chainbase_address
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            s.connect(self.chainbase_address)
            s.sendall(send_handler(MsgType.TYPE_TRANS_READ, b''))
            *_, msgtype, content = recv_parser(s)

            trans = []  # todo: the first transaction should reward the miner,
            # todo: the server may have a property named owner_address
            if msgtype == MsgType.TYPE_RESPONSE_OK:
                trans += batch_parser(content)

            return [Transaction.unpack(t) for t in trans]
Exemplo n.º 6
0
    def handle(self):
        flag = 0
        # print(BlockchainMixin.state)
        while True:
            header = self.request.recv(LENGTH_HEADER)

            if len(header) == 0:
                # self.handler_log.debug('pid {0} Round end: {1}'.format(os.getpid(), time.time()))
                # print('pid {0} Round end: {1}'.format(os.getpid(), time.time()))
                break

            if flag == 0:
                # self.handler_log.debug('pid {0} Round start: {1}'.format(os.getpid(), time.time()))
                # print('pid {0} Round start: {1}'.format(os.getpid(), time.time()))
                flag = 1

            typ = header[4:8]
            len_h = struct.unpack('=i', header[:4])[0]
            content = bytes()
            '''Just receive all the content'''
            l = 0
            while l < len_h:
                piece = self.request.recv(min(PIECE, len_h - l))
                content += piece
                l += len(piece)
            '''Check whether the block content has been received (hash or keyword IN)
            if so, continue the loop'''
            # print('received from: ', self.request.getpeername())
            '''PBFT state machine'''
            if BlockchainMixin.state is StatePBFT.IDLE:
                if typ == TYPE_TRANS:  # keep receiving trans until reach the limitation
                    BlockchainMixin.lock.acquire()
                    BlockchainMixin.trans.append(Transaction.unpack(content))
                    BlockchainMixin.lock.release()
                    if len(BlockchainMixin.trans
                           ) == BlockchainMixin.trans_limit:  # prepare a block
                        at = Attachment()
                        at.add_data(b'')
                        at.ready()

                        bd = BlockData(BlockchainMixin.trans, at)
                        block = Block(
                            BlockchainMixin.chain.chain[-1].index + 1,
                            time.time(), bd,
                            BlockchainMixin.chain.chain[-1].hash)
                        msg = BlockchainMixin.pre_prepare_msg(
                            BlockchainMixin.view, BlockchainMixin.n_request,
                            block.b)

                        BlockchainMixin.n_request += 1
                        BlockchainMixin.state = StatePBFT.PREPARE
                        BlockchainMixin.temp_block.append(block.b)
                        for ip, port in BlockchainMixin.connection:
                            if (ip, port) == self.request.getpeername():
                                continue
                            BlockchainMixin.pool.apply_async(
                                self.sends, ((ip, port), msg))

                        BlockchainMixin.trans.clear()

                elif typ == TYPE_PRE_PREPARE:  # cache the block and response with PREPARE message
                    BlockchainMixin.lock.acquire()
                    # print('content', content)
                    BlockchainMixin.temp_block.append(content)
                    BlockchainMixin.state = StatePBFT.PREPARE
                    BlockchainMixin.lock.release()
                    msg = BlockchainMixin.prepare_msg(
                        BlockchainMixin.view, BlockchainMixin.num_nodes,
                        BlockchainMixin.index, content)
                    for ip, port in BlockchainMixin.connection:
                        BlockchainMixin.pool.apply_async(
                            self.sends, ((ip, port), msg))

            elif BlockchainMixin.state is StatePBFT.PREPARE:
                if typ == TYPE_PREPARE or typ == TYPE_COMMIT:
                    BlockchainMixin.lock.acquire()
                    BlockchainMixin.state = StatePBFT.COMMIT
                    BlockchainMixin.lock.release()
                    msg = BlockchainMixin.commit_msg(BlockchainMixin.view,
                                                     BlockchainMixin.num_nodes,
                                                     BlockchainMixin.index,
                                                     content)
                    for ip, port in BlockchainMixin.connection:
                        BlockchainMixin.pool.apply_async(
                            self.sends, ((ip, port), msg))

            elif BlockchainMixin.state is StatePBFT.COMMIT:
                if typ == TYPE_COMMIT:
                    BlockchainMixin.lock.acquire()
                    BlockchainMixin.state = StatePBFT.REPLY
                    BlockchainMixin.chain.add_block(
                        Block.unpack(BlockchainMixin.temp_block[0]))
                    BlockchainMixin.temp_block.clear()
                    BlockchainMixin.lock.release()
                    msg = BlockchainMixin.commit_msg(BlockchainMixin.view,
                                                     BlockchainMixin.num_nodes,
                                                     BlockchainMixin.index,
                                                     content)
                    for ip, port in BlockchainMixin.connection:
                        BlockchainMixin.pool.apply_async(
                            self.sends, ((ip, port), msg))

                    mm = '%f' % time.time()
                    print(mm)
                    with open('logs/srv' + str(BlockchainMixin.index) + '.txt',
                              'w') as logfile:
                        logfile.writelines([mm])

            elif BlockchainMixin.state is StatePBFT.REPLY:
                pass
    def test_000_trans_write(self):
        """
        The first (genesis) block contains a transaction that pays 42 to the address that corresponds to the
        following private key. This test case first use this private key to issue and submit a transaction
        which pays 7 for 6 random addresses. This transaction is valid and stays in the pool of transactions.
        Then the test try to issue a new transaction. Because the 42 assets of the following private key were
        used up, the new transaction is invalid. Finally, the test pays 7 from random address 1 to address 2.
        """

        tinput = [(
            b'O\x1e,-\xe1\xa0!\x16D\x87\xcc\x923\xf7\xf6\xca\xad\xd1\t\x8eV\xdc\xe8t}N\xfa\x8af\xbe\xe7\xef',
            0)]

        private_key1 = load_pem_private_key(
            b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0w'
            b'awIBAQQg64DiDBUkuGC5rrTfH6uy\nHt6vhvHrMHj3Gm64SZtdqtKhRANCAATMIea'
            b'IK4vT0ni00F6GGW40qioinPFgXjsj\n6sZGivW9Ipj+zcDfPc7RxZuFeKFmbtVaUX'
            b'Z877DM4C8ELZs2DPVQ\n-----END PRIVATE KEY-----\n', None,
            default_backend())
        public_key = b'-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzCHmiCuL09J4tNBehhluNKoqIpzx' \
                     b'YF47\nI+rGRor1vSKY/s3A3z3O0cWbhXihZm7VWlF2fO+wzOAvBC2bNgz1UA==\n-----END PUBLIC KEY-----\n'
        sha = hashlib.sha256()
        sha.update(public_key)
        public_key_hash = sha.digest()

        T1 = TransInput(tinput, public_key_hash)

        public_key_hash = []
        private_keys = []
        public_keys = []

        for i in range(6):
            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            private_keys.append(private_key)

            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
            public_keys.append(public_key)

            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash.append(sha.digest())

        toutput = [(7, public_key_hash[i]) for i in range(6)]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key1)

        with socket.socket(
                socket.AF_UNIX,
                socket.SOCK_STREAM) as s:  # submit the valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
            # submit the same transaction, but it is invalid this time

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype,
                MsgType.TYPE_RESPONSE_ERROR)  # the chainbase returns ERROR
        """
        construct a second valid transaction, which pay 7 from random address 1 to random address 2
        """
        private_key = private_keys[0]
        public_key = public_keys[0]
        public_key_hash1 = public_key_hash[0]

        T1 = TransInput([(T.txid, 0)], public_key_hash1)

        toutput = [(7, public_key_hash[1])]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key)
        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM
                           ) as s:  # submit the second valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_TRANS_WRITE, T.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK
    def test_001_block_write(self):
        """
        use the same case as the test_000_trans_write, but transactions are seperated into different blocks
        :return:
        """
        # replace the following connection address with the address in the chainbase

        tinput = [(
            b'O\x1e,-\xe1\xa0!\x16D\x87\xcc\x923\xf7\xf6\xca\xad\xd1\t\x8eV\xdc\xe8t}N\xfa\x8af\xbe\xe7\xef',
            0)]

        private_key1 = load_pem_private_key(
            b'-----BEGIN PRIVATE KEY-----\nMIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0w'
            b'awIBAQQg64DiDBUkuGC5rrTfH6uy\nHt6vhvHrMHj3Gm64SZtdqtKhRANCAATMIea'
            b'IK4vT0ni00F6GGW40qioinPFgXjsj\n6sZGivW9Ipj+zcDfPc7RxZuFeKFmbtVaUX'
            b'Z877DM4C8ELZs2DPVQ\n-----END PRIVATE KEY-----\n', None,
            default_backend())
        public_key = b'-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzCHmiCuL09J4tNBehhluNKoqIpzx' \
                     b'YF47\nI+rGRor1vSKY/s3A3z3O0cWbhXihZm7VWlF2fO+wzOAvBC2bNgz1UA==\n-----END PUBLIC KEY-----\n'
        sha = hashlib.sha256()
        sha.update(public_key)
        public_key_hash = sha.digest()

        T1 = TransInput(tinput, public_key_hash)

        public_key_hash = []
        private_keys = []
        public_keys = []

        for i in range(6):
            private_key = ec.generate_private_key(ec.SECP256K1,
                                                  default_backend())
            private_keys.append(private_key)

            public_key = private_key.public_key()
            public_key = public_key.public_bytes(
                Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
            public_keys.append(public_key)

            sha = hashlib.sha256()
            sha.update(public_key)
            public_key_hash.append(sha.digest())

        toutput = [(7, public_key_hash[i]) for i in range(6)]
        T2 = TransOutput(toutput)

        T = Transaction(T1, T2)
        T.ready(private_key1)

        pri_key = private_keys[0]
        public_key_hash1 = public_key_hash[0]

        T8 = TransInput([(T.txid, 0)], public_key_hash1)

        toutput = [(7, public_key_hash[1])]
        T9 = TransOutput(toutput)

        T4 = Transaction(T8, T9)
        T4.ready(pri_key)

        at = Attachment()
        at.add_data(b'')
        at.ready()

        bd = BlockData([T, T4], at)
        t = time.time()
        block = Block(
            1, t, bd,
            b'G\xfdk\x88\xda5\xff\x8c\x97t\x9f\xcb\xe0\xa8\x07S\x8b9t:.9\x1d\xee\xf4\xb1\xda\xd1r\xaf\xfcu',
            33)
        """
        construct a second valid transaction, which pay 7 from random address 1 to random address 2 
        """

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM
                           ) as s:  # submit the second valid transaction

            s.connect(self.address)
            payload = send_handler(MsgType.TYPE_BLOCK_WRITE, block.b)
            s.sendall(payload)
            header, length, msgtype, content = recv_parser(s)

            self.assertEqual(content, b'')
            self.assertEqual(length, 0)
            self.assertEqual(
                msgtype, MsgType.TYPE_RESPONSE_OK)  # the chainbase returns OK