Ejemplo n.º 1
0
    def test_validate_custom(self):
        """
        MultiSigCreate _validate_custom() only checks if fee == 0
        """
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.alice.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=0,
                                  xmss_pk=self.random_signer.pk)
        del tx._data.multi_sig_spend.addrs_to[-1]
        result = tx._validate_custom()
        self.assertFalse(result)

        tx._data.multi_sig_spend.addrs_to.extend([self.alice.address])
        result = tx._validate_custom()
        self.assertTrue(result)

        del tx._data.multi_sig_spend.amounts[-1]
        result = tx._validate_custom()
        self.assertFalse(result)

        tx._data.multi_sig_spend.amounts.extend([100])
        result = tx._validate_custom()
        self.assertTrue(result)

        tx._data.multi_sig_spend.multi_sig_address = self.bob.address
        result = tx._validate_custom()
        self.assertFalse(result)
Ejemplo n.º 2
0
    def test_apply(self):
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        alice_address_state = OptimizedAddressState.get_default(
            self.alice.address)
        alice_address_state.pbdata.balance = 5
        bob_address_state = OptimizedAddressState.get_default(self.bob.address)
        addresses_state = {
            self.alice.address: alice_address_state,
            self.bob.address: bob_address_state,
            multi_sig_address: multi_sig_address_state,
        }

        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.alice.pk)
        tx.sign(self.alice)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, tx.ots_key))

        tx.apply(self.state, state_container)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, tx.ots_key))
        self.assertIn(tx.txhash, state_container.votes_stats)
        vote_stats = state_container.votes_stats[tx.txhash]
        self.assertEqual(vote_stats.shared_key, tx.txhash)
        self.assertEqual(vote_stats.total_weight, 0)
        self.assertEqual(vote_stats.signatories,
                         multi_sig_address_state.signatories)
Ejemplo n.º 3
0
    def test_validate_all(self):
        """
        TODO: Check by signing txn from a non signatory address
        """
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.random.pk,
                                  master_addr=self.alice.address)
        tx.sign(self.random)
        tx._data.nonce = 1
        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        random_address_state = OptimizedAddressState.get_default(
            address=self.random.address)
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        addresses_state = {
            self.alice.address: alice_address_state,
            self.random.address: random_address_state,
            multi_sig_address: multi_sig_address_state,
        }
        slaves = Indexer(b'slave', None)
        slaves.data[(self.alice.address,
                     self.random.pk)] = SlaveMetadata(access_type=0)

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=slaves,
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=10,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=False,
                                         my_db=self.state._db,
                                         batch=None)

        result = tx.validate_all(state_container)
        self.assertTrue(result)

        tx._data.nonce = 2
        result = tx.validate_all(state_container)
        self.assertFalse(result)  # False as nonce is invalid
Ejemplo n.º 4
0
 def test_create(self):
     multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
         b'')
     tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                               addrs_to=[self.bob.address],
                               amounts=[100],
                               expiry_block_number=15000,
                               fee=0,
                               xmss_pk=self.alice.pk)
     self.assertIsInstance(tx, MultiSigSpend)
Ejemplo n.º 5
0
 def create_multi_sig_spend_txn(multi_sig_address: bytes, addrs_to: list,
                                amounts: list, expiry_block_number: int,
                                fee: int, xmss_pk: bytes,
                                master_addr: bytes):
     return MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                 addrs_to=addrs_to,
                                 amounts=amounts,
                                 expiry_block_number=expiry_block_number,
                                 fee=fee,
                                 xmss_pk=xmss_pk,
                                 master_addr=master_addr)
Ejemplo n.º 6
0
 def test_to_json(self):
     multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
         b'')
     tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                               addrs_to=[self.bob.address],
                               amounts=[100],
                               expiry_block_number=15000,
                               fee=0,
                               xmss_pk=self.alice.pk)
     txjson = tx.to_json()
     self.assertEqual(json.loads(test_json_MultiSigSpend),
                      json.loads(txjson))
Ejemplo n.º 7
0
    def test_affected_address(self):
        # This transaction can only involve 2 addresses.
        affected_addresses = set()
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.alice.pk)
        tx.set_affected_address(affected_addresses)

        self.assertEqual(3, len(affected_addresses))
        self.assertIn(self.alice.address, affected_addresses)
        self.assertIn(multi_sig_address, affected_addresses)
Ejemplo n.º 8
0
 def test_create(self):
     multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
         b'')
     spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                     addrs_to=[self.alice.address],
                                     amounts=[100],
                                     expiry_block_number=15000,
                                     fee=0,
                                     xmss_pk=self.alice.pk)
     spend_tx.sign(self.alice)
     tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                              unvote=False,
                              fee=0,
                              xmss_pk=self.alice.pk)
     tx.sign(self.alice)
     self.assertIsInstance(tx, MultiSigVote)
Ejemplo n.º 9
0
 def test_to_json(self):
     multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
         b'')
     spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                     addrs_to=[self.alice.address],
                                     amounts=[100],
                                     expiry_block_number=15000,
                                     fee=0,
                                     xmss_pk=self.alice.pk)
     spend_tx.sign(self.alice)
     tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                              unvote=False,
                              fee=0,
                              xmss_pk=self.alice.pk)
     txjson = tx.to_json()
     self.assertEqual(json.loads(test_json_MultiSigVote),
                      json.loads(txjson))
Ejemplo n.º 10
0
 def test_validate_custom(self):
     """
     MultiSigCreate _validate_custom() only checks if fee == 0
     """
     multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
         b'')
     spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                     addrs_to=[self.alice.address],
                                     amounts=[100],
                                     expiry_block_number=15000,
                                     fee=0,
                                     xmss_pk=self.alice.pk)
     spend_tx.sign(self.alice)
     tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                              unvote=False,
                              fee=0,
                              xmss_pk=self.alice.pk)
     tx.sign(self.alice)
     result = tx._validate_custom()
     self.assertTrue(result)
Ejemplo n.º 11
0
    def test_affected_address(self):
        # This transaction can only involve 2 addresses.
        affected_addresses = set()
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                        addrs_to=[self.alice.address],
                                        amounts=[100],
                                        expiry_block_number=15000,
                                        fee=0,
                                        xmss_pk=self.alice.pk)
        spend_tx.sign(self.alice)
        tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                                 unvote=False,
                                 fee=5,
                                 xmss_pk=self.alice.pk)
        tx.sign(self.alice)
        tx.set_affected_address(affected_addresses)

        self.assertEqual(1, len(affected_addresses))
        self.assertIn(self.alice.address, affected_addresses)
Ejemplo n.º 12
0
    def test_validate_extended(self):
        """
        TODO: Check by signing txn from a non signatory address
        """
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=[self.bob.address],
                                  amounts=[100],
                                  expiry_block_number=15000,
                                  fee=5,
                                  xmss_pk=self.alice.pk)
        tx.sign(self.alice)

        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        addresses_state = {
            self.alice.address: alice_address_state,
            multi_sig_address: multi_sig_address_state,
        }
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=10,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=None,
                                         batch=None)

        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        alice_address_state.pbdata.balance = 0
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        alice_address_state.pbdata.balance = 5
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        multi_sig_address_state.pbdata.balance = 99
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        multi_sig_address_state.pbdata.balance = 100
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        tx.pbdata.multi_sig_spend.expiry_block_number = 10
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        tx.pbdata.multi_sig_spend.expiry_block_number = 15000
        result = tx._validate_extended(state_container)
        self.assertTrue(result)
Ejemplo n.º 13
0
def tx_multi_sig_spend(ctx, src, master, multi_sig_address, dsts, amounts,
                       expiry_block_number, fee, ots_key_index):
    """
    Transfer coins from src to dsts
    """
    address_src_pk = None
    master_addr = None

    addresses_dst = []
    shor_amounts = []
    fee_shor = []

    signing_object = None

    try:
        # Retrieve signing object
        selected_wallet = _select_wallet(ctx, src)
        if selected_wallet is None or len(selected_wallet) != 2:
            click.echo("A wallet was not found")
            quit(1)

        _, src_xmss = selected_wallet

        if not src_xmss:
            click.echo("A local wallet is required to sign the transaction")
            quit(1)

        address_src_pk = src_xmss.pk

        ots_key_index = validate_ots_index(ots_key_index, src_xmss)
        src_xmss.set_ots_index(ots_key_index)

        signing_object = src_xmss

        # Get and validate other inputs
        if master:
            master_addr = parse_qaddress(master)

        addresses_dst, shor_amounts = _parse_dsts_amounts(
            dsts, amounts, check_multi_sig_address=True)
        fee_shor = _quanta_to_shor(fee)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)
    multi_sig_address = bytes(hstr2bin(multi_sig_address[1:]))
    try:
        # MultiSigSpend transaction
        tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                  addrs_to=addresses_dst,
                                  amounts=shor_amounts,
                                  expiry_block_number=expiry_block_number,
                                  fee=fee_shor,
                                  xmss_pk=address_src_pk,
                                  master_addr=master_addr)

        # Sign transaction
        tx.sign(signing_object)

        if not tx.validate():
            print("It was not possible to validate the signature")
            quit(1)

        print("\nTransaction Blob (signed): \n")
        txblob = tx.pbdata.SerializeToString()
        txblobhex = hexlify(txblob).decode()
        print(txblobhex)

        # Push transaction
        print()
        print("Sending to a QRL Node...")
        stub = ctx.obj.get_stub_public_api()
        push_transaction_req = qrl_pb2.PushTransactionReq(
            transaction_signed=tx.pbdata)
        push_transaction_resp = stub.PushTransaction(
            push_transaction_req, timeout=CONNECTION_TIMEOUT)

        # Print result
        print(push_transaction_resp)
    except Exception as e:
        print("Error {}".format(str(e)))
Ejemplo n.º 14
0
    def test_validate_extended(self):
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                        addrs_to=[self.alice.address],
                                        amounts=[100],
                                        expiry_block_number=15000,
                                        fee=0,
                                        xmss_pk=self.alice.pk)
        spend_tx.sign(self.alice)
        tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                                 unvote=False,
                                 fee=5,
                                 xmss_pk=self.alice.pk)
        tx.sign(self.alice)

        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        addresses_state = {
            self.alice.address: alice_address_state,
            multi_sig_address: multi_sig_address_state,
        }
        vote_stats = {
            spend_tx.txhash:
            VoteStats.create(multi_sig_address=multi_sig_address,
                             shared_key=spend_tx.txhash,
                             signatories=multi_sig_address_state.signatories,
                             expiry_block_number=spend_tx.expiry_block_number),
        }
        multi_sig_spend_txs = {
            spend_tx.txhash: spend_tx,
        }
        state_container = StateContainer(
            addresses_state=addresses_state,
            tokens=Indexer(b'token', None),
            slaves=Indexer(b'slave', None),
            lattice_pk=Indexer(b'lattice_pk', None),
            multi_sig_spend_txs=multi_sig_spend_txs,
            votes_stats=vote_stats,
            block_number=10,
            total_coin_supply=100,
            current_dev_config=config.dev,
            write_access=True,
            my_db=None,
            batch=None)

        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        tx._data.multi_sig_vote.unvote = True
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        tx._data.multi_sig_vote.unvote = False
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        alice_address_state.pbdata.balance = 0
        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        alice_address_state.pbdata.balance = 5
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        state_container.block_number = 15000
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        state_container.block_number = 15001
        result = tx._validate_extended(state_container)
        self.assertFalse(result)
Ejemplo n.º 15
0
    def test_validate_all(self):
        """
        Test for Validate Extended when transaction has been signed by slave.
        :return:
        """
        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            b'')
        spend_tx = MultiSigSpend.create(multi_sig_address=multi_sig_address,
                                        addrs_to=[self.alice.address],
                                        amounts=[100],
                                        expiry_block_number=15000,
                                        fee=0,
                                        xmss_pk=self.alice.pk)
        spend_tx.sign(self.alice)
        tx = MultiSigVote.create(shared_key=spend_tx.txhash,
                                 unvote=False,
                                 fee=5,
                                 xmss_pk=self.random.pk,
                                 master_addr=self.alice.address)
        tx.sign(self.random)
        tx._data.nonce = 1
        alice_address_state = OptimizedAddressState.get_default(
            address=self.alice.address)
        alice_address_state.pbdata.balance = 5
        random_address_state = OptimizedAddressState.get_default(
            address=self.random.address)
        multi_sig_address_state = MultiSigAddressState.create(
            creation_tx_hash=b'',
            balance=100,
            signatories=[self.alice.address, self.bob.address],
            weights=[4, 6],
            threshold=5,
            transaction_hash_count=0)
        addresses_state = {
            self.alice.address: alice_address_state,
            self.random.address: random_address_state,
            multi_sig_address: multi_sig_address_state,
        }
        vote_stats = {
            spend_tx.txhash:
            VoteStats.create(multi_sig_address=multi_sig_address,
                             shared_key=spend_tx.txhash,
                             signatories=multi_sig_address_state.signatories,
                             expiry_block_number=spend_tx.expiry_block_number),
        }
        multi_sig_spend_txs = {
            spend_tx.txhash: spend_tx,
        }
        slaves = Indexer(b'slave', None)
        slaves.data[(self.alice.address,
                     self.random.pk)] = SlaveMetadata(access_type=0)
        state_container = StateContainer(
            addresses_state=addresses_state,
            tokens=Indexer(b'token', None),
            slaves=slaves,
            lattice_pk=Indexer(b'lattice_pk', None),
            multi_sig_spend_txs=multi_sig_spend_txs,
            votes_stats=vote_stats,
            block_number=10,
            total_coin_supply=100,
            current_dev_config=config.dev,
            write_access=False,
            my_db=self.state._db,
            batch=None)

        result = tx.validate_all(state_container)
        self.assertTrue(result)

        tx._data.nonce = 2
        result = tx.validate_all(state_container)
        self.assertFalse(result)  # False as nonce is invalid