Esempio n. 1
0
def test_generate_block():
    signing_key, account_number = create_account()
    encoded_account_number = encode_verify_key(verify_key=account_number)

    transactions = [
        {
            'amount': 1,
            'recipient': random_encoded_account_number(),
        },
        {
            'amount': 1,
            'recipient': random_encoded_account_number(),
        },
        {
            'amount': 5,
            'recipient': random_encoded_account_number(),
        }
    ]

    block = generate_block(
        account_number=account_number,
        balance_lock=encoded_account_number,
        signing_key=signing_key,
        transactions=transactions
    )

    assert block['account_number'] == encoded_account_number
    assert block['message']['balance_key'] == encoded_account_number
    assert len(block['message']['txs']) == 3
    assert len(block['signature']) == SIGNATURE_LENGTH
Esempio n. 2
0
def send_signed_block(*, block, ip_address, port, protocol, url_path):
    """
    Sign block and send to recipient
    """

    network_signing_key = get_environment_variable('NETWORK_SIGNING_KEY')
    signing_key = SigningKey(network_signing_key, encoder=HexEncoder)
    node_identifier = get_verify_key(signing_key=signing_key)
    node_identifier = encode_verify_key(verify_key=node_identifier)
    message = sort_and_encode(block)

    signed_block = {
        'block': block,
        'node_identifier': node_identifier,
        'signature': generate_signature(message=message,
                                        signing_key=signing_key)
    }

    node_address = format_address(ip_address=ip_address,
                                  port=port,
                                  protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_block)
    except Exception as e:
        logger.exception(e)
def generate_signed_message(*, account_number, message, signing_key):
    block = {
        'account_number': encode_verify_key(verify_key=account_number),
        'message': message,
        'signature': signing_key.sign(message.encode('utf-8')).signature.hex()
    }
    return block
Esempio n. 4
0
def test_generate_block():
    signing_key, account_number = create_account()
    encoded_account_number = encode_verify_key(verify_key=account_number)

    transactions = [{
        'amount': 1,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 1,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 5,
        'recipient': random_encoded_account_number(),
    }]

    block = generate_block(account_number=account_number,
                           balance_lock=encoded_account_number,
                           signing_key=signing_key,
                           transactions=transactions)

    assert block['account_number'] == encoded_account_number
    assert block['message']['balance_key'] == encoded_account_number
    assert len(block['message']['txs']) == 3
    assert len(block['signature']) == SIGNATURE_LENGTH

    # Verify that signature is valid and the message has not been modified
    verify_signature(message=sort_and_encode(block['message']),
                     signature=block['signature'],
                     verify_key=block['account_number'])
Esempio n. 5
0
def send_signed_block(*, block, ip_address, port, protocol, url_path):
    """
    Sign block and send to recipient
    """

    signing_key = get_signing_key()
    node_identifier = get_verify_key(signing_key=signing_key)
    node_identifier = encode_verify_key(verify_key=node_identifier)
    message = sort_and_encode(block)

    signed_block = {
        'block': block,
        'node_identifier': node_identifier,
        'signature': generate_signature(message=message,
                                        signing_key=signing_key)
    }
    node_address = format_address(ip_address=ip_address,
                                  port=port,
                                  protocol=protocol)
    url = f'{node_address}{url_path}'

    try:
        post(url=url, body=signed_block)
    except Exception as e:
        request_new_primary_validator()
        logger.exception(e)
Esempio n. 6
0
def test_network_block_serializer():
    signing_key, account_number = create_account()
    encoded_account_number = encode_verify_key(verify_key=account_number)

    transactions = [{
        'amount': 1,
        'fee': BANK,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 1,
        'fee': PRIMARY_VALIDATOR,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 5,
        'memo': 'Hello there I am 123 years old',
        'recipient': random_encoded_account_number(),
    }]

    block = generate_block(account_number=account_number,
                           balance_lock=encoded_account_number,
                           signing_key=signing_key,
                           transactions=transactions)

    serializer = NetworkBlockSerializer(data=block)
    assert serializer.is_valid()
def test_generate_block():
    signing_key, account_number = create_account()
    encoded_account_number = encode_verify_key(verify_key=account_number)

    transactions = [{
        'amount': 1,
        'fee': BANK,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 1,
        'fee': PRIMARY_VALIDATOR,
        'recipient': random_encoded_account_number(),
    }, {
        'amount': 5,
        'memo': 'Hello there I am 123 years old',
        'recipient': random_encoded_account_number(),
    }]

    block = generate_block(account_number=account_number,
                           balance_lock=encoded_account_number,
                           signing_key=signing_key,
                           transactions=transactions)

    assert block['account_number'] == encoded_account_number
    assert block['message']['balance_key'] == encoded_account_number
    assert len(block['message']['txs']) == 3
    assert len(block['signature']) == SIGNATURE_LENGTH
Esempio n. 8
0
def generate_signed_request(*, data, nid_signing_key):
    """Generate and return signed request"""
    node_identifier = get_verify_key(signing_key=nid_signing_key)
    signature = generate_signature(
        message=sort_and_encode(data),
        signing_key=nid_signing_key
    )
    return {
        'message': data,
        'node_identifier': encode_verify_key(verify_key=node_identifier),
        'signature': signature
    }
Esempio n. 9
0
def run():
    """
    Create new account and save signing key
    """

    file_path = os.path.join(SIGNING_KEY_DIR, 'cv_nid')
    create_account_and_save_signing_key_file(file=file_path)

    signing_key = read_signing_key_file(file_path)
    verify_key = get_verify_key(signing_key=signing_key)
    verify_key = encode_verify_key(verify_key=verify_key)

    print(f'verify_key: {verify_key}')
Esempio n. 10
0
def signed_block(block_data, bank_signing_key):
    yield {
        'block':
        block_data,
        'node_identifier':
        encode_verify_key(verify_key=get_verify_key(
            signing_key=bank_signing_key, ), ),
        'signature':
        generate_signature(
            message=sort_and_encode(block_data),
            signing_key=bank_signing_key,
        ),
    }
Esempio n. 11
0
def block_data(account_data, encoded_account_number,
               random_encoded_account_number):
    signing_key, account_number = create_account()

    yield generate_block(account_number=account_number,
                         balance_lock=encode_verify_key(
                             verify_key=account_number, ),
                         signing_key=signing_key,
                         transactions=[{
                             'amount':
                             1,
                             'recipient':
                             random_encoded_account_number
                         }])
Esempio n. 12
0
def generate_block(*, account_number, balance_lock, signing_key, transactions):
    """Generate block"""
    message = {
        'balance_key': balance_lock,
        'txs': sorted(transactions, key=itemgetter('recipient'))
    }

    signature = generate_signature(message=sort_and_encode(message),
                                   signing_key=signing_key)

    block = {
        'account_number': encode_verify_key(verify_key=account_number),
        'message': message,
        'signature': signature
    }

    return block
Esempio n. 13
0
def run(send_to_pv=False):
    """
    Create block used for:
    - POST /bank_blocks
    - Bank > PV
    """

    treasury_signing_key = read_signing_key_file(
        os.path.join(SIGNING_KEY_DIR, 'treasury'))
    account_number = get_verify_key(signing_key=treasury_signing_key)

    balance_lock = get_account_balance_lock(
        account_number=TREASURY_ACCOUNT_NUMBER, live_pv=True)
    transactions = [{
        'amount': BANK_TX_FEE,
        'recipient': BANK_ACCOUNT_NUMBER,
    }, {
        'amount': PV_TX_FEE,
        'recipient': PV_ACCOUNT_NUMBER,
    }, {
        'amount': 1.0,
        'recipient': BUCKY_ACCOUNT_NUMBER,
    }]
    block = generate_block(account_number=account_number,
                           balance_lock=balance_lock,
                           signing_key=treasury_signing_key,
                           transactions=transactions)

    bank_nid_sk = read_signing_key_file(
        os.path.join(SIGNING_KEY_DIR, 'bank_nid'))
    bank_nid = get_verify_key(signing_key=bank_nid_sk)
    bank_nid = encode_verify_key(verify_key=bank_nid)
    message = sort_and_encode(block)

    signed_block = {
        'block': block,
        'node_identifier': bank_nid,
        'signature': generate_signature(message=message,
                                        signing_key=bank_nid_sk)
    }

    write_json(os.path.join(BLOCKS_DIR, 'bank-blocks-request.json'),
               signed_block)

    if send_to_pv:
        send_request_to_pv(signed_block)
def block_data(account_data, encoded_account_number, random_encoded_account_number):
    signing_key, account_number = create_account()

    yield generate_block(
        account_number=account_number,
        balance_lock=encode_verify_key(
            verify_key=account_number,
        ),
        signing_key=signing_key,
        transactions=[
            {
                'amount': 4,
                'fee': PRIMARY_VALIDATOR,
                'recipient': 'ad1f8845c6a1abb6011a2a434a079a087c460657aad54329a84b406dce8bf314'
            },
            {
                'amount': 1,
                'recipient': random_encoded_account_number
            }
        ]
    )
Esempio n. 15
0
    def test_post(self):
        """
        Create block
        """

        signing_key, account_number = create_account()
        encoded_account_number = encode_verify_key(verify_key=account_number)
        Account.objects.create(account_number=encoded_account_number, trust=50)

        self_configuration = get_self_configuration(
            exception_class=RuntimeError)
        primary_validator = self_configuration.primary_validator

        block = generate_block(
            account_number=account_number,
            balance_lock=encoded_account_number,
            signing_key=signing_key,
            transactions=[{
                'amount':
                float(self_configuration.default_transaction_fee),
                'recipient':
                self_configuration.account_number
            }, {
                'amount':
                float(primary_validator.default_transaction_fee),
                'recipient':
                primary_validator.account_number
            }, {
                'amount':
                self.fake.pyfloat(min_value=1,
                                  max_value=100,
                                  positive=True,
                                  right_digits=4),
                'recipient':
                random_account_number()
            }])

        self.validate_post('/blocks', block, status.HTTP_201_CREATED)
Esempio n. 16
0
def random_encoded_account_number():
    signing_key, account_number = create_account()
    return encode_verify_key(verify_key=account_number)
Esempio n. 17
0
def encoded_account_number(account_number):
    yield encode_verify_key(verify_key=account_number)
Esempio n. 18
0
def faucet_view(request):
    form = FaucetForm()
    if request.method == 'POST':
        form = FaucetForm(request.POST)
        if form.is_valid():
            # form data
            url_str = form.cleaned_data['url']
            amount = form.cleaned_data['amount']

            platform = get_platform(url_str)
            if platform:
                post = platform.process(url_str, amount)

                if post:
                    receiver_account_number = post.get_account_number()
                    post_id = post.get_id()
                    platform = post.get_platform()
                    user_id = post.get_user()

                    bank_config = SelfConfiguration.objects.first()
                    pv_config = bank_config.primary_validator

                    signing_key = get_signing_key()
                    sender_account_number = encode_verify_key(
                        verify_key=signing_key.verify_key)

                    account = validate_post_exists(receiver_account_number,
                                                   post_id)
                    faucet_model = validate_expiry(account, user_id)

                    if account and not faucet_model:
                        response = requests.get(
                            (f'{pv_config.protocol}://{pv_config.ip_address}'
                             f':{pv_config.port}'
                             f'/accounts/'
                             f'{sender_account_number}/balance_lock'))

                        if response.status_code == 200:
                            balance_lock = response.json().get('balance_lock')
                            if not balance_lock:
                                balance_lock = bank_config.node_identifier

                            faucet_model, created = (
                                FaucetModel.objects.update_or_create(
                                    account=account,
                                    social_user_id=user_id,
                                    social_type=platform,
                                    defaults={
                                        'next_valid_access_time':
                                        (timezone.now() +
                                         timedelta(hours=amount.delay))
                                    }))

                            post_model, created = PostModel.objects.get_or_create(
                                post_id=post_id,
                                reward=amount,
                                social_user=faucet_model)

                            transactions = [{
                                'amount':
                                amount.coins,
                                'recipient':
                                receiver_account_number,
                                'memo':
                                "Thank you for using TNBExplorer testnet"
                            }, {
                                'amount': bank_config.default_transaction_fee,
                                'recipient': bank_config.account_number,
                                'fee': "BANK"
                            }, {
                                'amount': pv_config.default_transaction_fee,
                                'recipient': pv_config.account_number,
                                'fee': "PRIMARY_VALIDATOR"
                            }]

                            block = generate_block(
                                account_number=signing_key.verify_key,
                                balance_lock=balance_lock,
                                signing_key=signing_key,
                                transactions=transactions)
                            serializer = BlockSerializerCreate(
                                data=block,
                                context={'request': request},
                            )
                            serializer.is_valid(raise_exception=True)
                            block = serializer.save()
                            messages.success(request, (
                                f'SUCCESS! {amount.coins} faucet funds'
                                f' transferred to {receiver_account_number}.'))
                            form = FaucetForm()
                        else:
                            messages.error(
                                request,
                                'Unable to obtain TNB account details!')
                    else:
                        form = FaucetForm()
                        if faucet_model:
                            duration = (faucet_model.next_valid_access_time -
                                        timezone.now())
                            totsec = duration.total_seconds()
                            h = int(totsec // 3600)
                            m = int((totsec % 3600) // 60)
                            sec = round((totsec % 3600) % 60)
                            messages.error(
                                request, ('Slow down! Try again after ('
                                          f'{h} hours {m} mins and {sec} secs'
                                          ') till cooldown period expires.'))
                        else:
                            messages.error(request,
                                           ('Same post cannot be used again! '
                                            ' Try again with a new one :P'))
                else:
                    messages.error(
                        request,
                        ('Failed to extract information!'
                         ' Make sure post is public,'
                         ' contains #TNBFaucet and your account number'))
            else:
                messages.error(request,
                               'Only facebook and twitter URL allowed!')
        else:
            messages.error(request,
                           'Form invalid! Please provide correct details!')

    context = {'form': form}
    return render(request, 'index.html', context)
Esempio n. 19
0
    def post(self, request, format=None):
        serializer = FormSerializer(data=request.data,
                                    context={"request": request})
        if serializer.is_valid(raise_exception=True):
            try:
                amount = FaucetOption.objects.get(
                    pk=serializer.data['faucet_option_id'])
                url_str = serializer.data['url']

                platform = get_platform(url_str)
                if platform:
                    post = platform.process(url_str, amount)

                    if post:
                        receiver_account_number = post.get_account_number()
                        post_id = post.get_id()
                        platform = post.get_platform()
                        user_id = post.get_user()

                        bank_config = SelfConfiguration.objects.first()
                        pv_config = bank_config.primary_validator

                        signing_key = get_signing_key()
                        sender_account_number = encode_verify_key(
                            verify_key=signing_key.verify_key)

                        account = validate_post_exists(receiver_account_number,
                                                       post_id)
                        faucet_model = validate_expiry(account, user_id)

                        if account and not faucet_model:
                            response = requests.get((
                                f'{pv_config.protocol}://{pv_config.ip_address}'
                                f':{pv_config.port}'
                                f'/accounts/'
                                f'{sender_account_number}/balance_lock'))

                            if response.status_code == 200:
                                balance_lock = response.json().get(
                                    'balance_lock')
                                if not balance_lock:
                                    balance_lock = bank_config.node_identifier

                                faucet_model, created = (
                                    FaucetModel.objects.update_or_create(
                                        account=account,
                                        social_user_id=user_id,
                                        social_type=platform,
                                        defaults={
                                            'next_valid_access_time':
                                            (timezone.now() +
                                             timedelta(hours=amount.delay))
                                        }))

                                post_model, created = PostModel.objects.get_or_create(
                                    post_id=post_id,
                                    reward=amount,
                                    social_user=faucet_model)

                                transactions = [{
                                    'amount':
                                    amount.coins,
                                    'recipient':
                                    receiver_account_number,
                                    'memo':
                                    "Thank you for using TNBExplorer testnet"
                                }, {
                                    'amount':
                                    bank_config.default_transaction_fee,
                                    'recipient': bank_config.account_number,
                                    'fee': "BANK"
                                }, {
                                    'amount':
                                    pv_config.default_transaction_fee,
                                    'recipient': pv_config.account_number,
                                    'fee': "PRIMARY_VALIDATOR"
                                }]

                                block = generate_block(
                                    account_number=signing_key.verify_key,
                                    balance_lock=balance_lock,
                                    signing_key=signing_key,
                                    transactions=transactions)
                                serializer = BlockSerializerCreate(
                                    data=block,
                                    context={'request': request},
                                )
                                serializer.is_valid(raise_exception=True)
                                block = serializer.save()
                                return Response(
                                    success_response((
                                        f'SUCCESS! {amount.coins} faucet funds'
                                        f' transferred to {receiver_account_number}.'
                                    )))
                            else:
                                return Response(error_response(
                                    'Unable to obtain TNB account details!'),
                                                status=status.
                                                HTTP_500_INTERNAL_SERVER_ERROR)
                        else:
                            if faucet_model:
                                duration = (
                                    faucet_model.next_valid_access_time -
                                    timezone.now())
                                totsec = duration.total_seconds()
                                h = int(totsec // 3600)
                                m = int((totsec % 3600) // 60)
                                sec = round((totsec % 3600) % 60)
                                return Response(
                                    error_response(
                                        ('Slow down! Try again after ('
                                         f'{h} hours {m} mins and {sec} secs'
                                         ') till cooldown period expires.')),
                                    status=status.HTTP_429_TOO_MANY_REQUESTS)
                            else:
                                return Response(
                                    error_response(
                                        ('Same post cannot be used again! '
                                         ' Try again with a new one :P')),
                                    status=status.HTTP_400_BAD_REQUEST)
                    else:
                        return Response(error_response(
                            ('Failed to extract information!'
                             ' Make sure post is public,'
                             ' contains #TNBFaucet and your account number')),
                                        status=status.HTTP_400_BAD_REQUEST)
                else:
                    return Response(error_response(
                        'Only facebook and twitter URL allowed!'),
                                    status=status.HTTP_400_BAD_REQUEST)
            except FaucetOption.DoesNotExist:
                return Response(error_response('bad request format/data'),
                                status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(error_response('bad request format/data'),
                            status=status.HTTP_400_BAD_REQUEST)
Esempio n. 20
0
def random_encoded_account_number():
    _, account_number = create_account()
    yield encode_verify_key(verify_key=account_number)