def test_disaster_recovery(web3, prepared_contracts, transactions, signed,
                           airdrops):
    """
    Assuming transactions got sent partially, are we able to resume with confidence?
    """
    _, omg_token = prepared_contracts

    unsent, unsent_unsigned = Sender(web3).recover_unsent(signed, transactions)

    assert unsent == signed
    assert unsent_unsigned == transactions

    Sender(web3).send_transactions(signed[:1], transactions[:1])

    # airdrop partially done by now
    check_entirely_airdropped(airdrops[0:BATCH_SIZE], omg_token)

    # recovery
    unsent, unsent_unsigned = Sender(web3).recover_unsent(signed, transactions)

    assert len(unsent) == 1
    assert len(unsent_unsigned) == 1
    assert unsent[0] == signed[1]
    assert unsent_unsigned[0] == transactions[1]

    Sender(web3).send_transactions(unsent, unsent_unsigned)

    check_entirely_airdropped(airdrops, omg_token)
def test_logging(web3, prepared_contracts, transactions, signed, mocker):
    _, omg_token = prepared_contracts

    mocker.patch('logging.info')
    Sender(web3).send_transactions(signed, transactions)

    assert len(logging.info.call_args_list) == 4 * len(signed)
Example #3
0
def reply_mail(account_id, mail_id):
    if request.method == 'POST':
        response_object = {'status': 'reply mail success'}
        Login.log('replying mail...')
        vertification = {}
        # find vertification of the account
        for account in ACCOUNTS:
            if account['id'] == account_id:
                vertification = account
                Login.log('find account: {}'.format((str)(vertification)))
                break
        # the posted data is in form of jsonified mail as sent to client, so do the reverse
        post_data = request.get_json()
        Sender.send_mail(vertification, post_data, account_id, mail_id)
        Login.log('Mail replied!')
        response_object.update({'message': 'Mail replied!'})
        return jsonify(response_object)
def test_small_flow(web3, prepared_contracts, creator, airdrops):
    _, omg_token = prepared_contracts

    transactions = creator.create_txs(airdrops, BATCH_SIZE)
    signed = Signer(web3).sign_transactions(transactions)
    Sender(web3).send_transactions(signed, transactions)

    check_entirely_airdropped(airdrops, omg_token)
def test_check_amount_before_send(web3, creator, airdrops, signed):
    """
    as above
    """
    airdrops[0][1] += 1
    different_transactions = creator.create_txs(airdrops, BATCH_SIZE)

    with pytest.raises(AirdropException):
        Sender(web3).send_transactions(signed, different_transactions)
def test_check_address_before_send(web3, creator, airdrops, signed):
    """
    Tests whether the final check throws, in case local data differs from signed transactions
    """
    airdrops[0][0] = web3.eth.accounts[0]
    different_transactions = creator.create_txs(airdrops, BATCH_SIZE)

    with pytest.raises(AirdropException):
        Sender(web3).send_transactions(signed, different_transactions)
Example #7
0
def send_txs(ipc_path, rpc_host, rpc_port, recovery_mode,
             final_check_unsigned_file, signed_file):

    if ipc_path and (rpc_host or rpc_port):
        raise Exception("both ipc and rpc cannot be specified")
    if ipc_path:
        web3 = Web3(IPCProvider(ipc_path))
    else:
        web3 = Web3(RPCProvider(host=rpc_host, port=rpc_port))

    sender = Sender(web3)

    signed = json.loads(signed_file.read())
    final_check_local_transactions = json.loads(
        final_check_unsigned_file.read())

    if recovery_mode:
        signed, final_check_local_transactions = sender.recover_unsent(
            signed, final_check_local_transactions)

    sender.send_transactions(signed, final_check_local_transactions)
def test_oog_handling(web3, prepared_contracts, transactions, airdrops):
    """
    Do we halt the sending when an oog occurs?
    """
    _, omg_token = prepared_contracts

    transactions[0]['tx']['gas'] = web3.toHex(transactions[0]['gasEstimate'] -
                                              1)

    signed = Signer(web3).sign_transactions(transactions)

    with pytest.raises(AirdropOOGException):
        Sender(web3).send_transactions(signed, transactions)

    check_none_airdropped(airdrops, omg_token)

    # check recovery works with OOG
    unsent, unsent_unsigned = Sender(web3).recover_unsent(signed, transactions)

    assert unsent == signed
    assert unsent_unsigned == transactions
def test_logging_failed_wait(web3, prepared_contracts, transactions, signed,
                             mocker):
    _, omg_token = prepared_contracts

    mocker.patch('logging.info')
    mocker.patch('populus.wait.Wait.for_receipt')
    populus.wait.Wait.for_receipt.side_effect = [Exception]

    with pytest.raises(Exception):
        Sender(web3).send_transactions(signed, transactions)

    assert len(logging.info.call_args_list) == 2
def test_logging_failed_send(web3, prepared_contracts, transactions, signed,
                             mocker):
    _, omg_token = prepared_contracts

    mocker.patch('logging.info')
    mocker.patch('web3.eth.Eth.sendRawTransaction')
    web3module.eth.Eth.sendRawTransaction.side_effect = [Exception]

    with pytest.raises(Exception):
        Sender(web3).send_transactions(signed, transactions)

    assert len(logging.info.call_args_list) == 1
def test_entire_flow(web3, prepared_contracts, creator, input_file):

    airdropper, omg_token = prepared_contracts
    airdrops = process(input_file.read())
    transactions = creator.create_txs(airdrops, BATCH_SIZE)

    # this being a long-running test, the unlocking from web3 fixture might have expired
    web3.personal.unlockAccount(web3.eth.accounts[0], "")

    signed = Signer(web3).sign_transactions(transactions)
    Sender(web3).send_transactions(signed, transactions)

    check_entirely_airdropped(airdrops, omg_token)
def test_recover_sent_airdrops(web3, prepared_contracts, transactions, signed,
                               airdrops, creator):
    """
    Assuming partially sent airdrops, when there's need to sign transactions again
    e.g. when it turned out that too little gas was allowed (unlikely)
    """
    airdropper, omg_token = prepared_contracts

    Sender(web3).send_transactions(signed[:1], transactions[:1])

    # airdrop partially done by now
    check_entirely_airdropped(airdrops[0:BATCH_SIZE], omg_token)

    not_airdropped = Sender(web3).recover_unsent_airdrops(
        airdrops, signed, airdropper, omg_token)

    assert not_airdropped == airdrops[BATCH_SIZE:]

    unsigned = creator.create_txs(not_airdropped, BATCH_SIZE)
    new_signed = Signer(web3).sign_transactions(unsigned)
    Sender(web3).send_transactions(new_signed, unsigned)

    check_entirely_airdropped(airdrops, omg_token)
def test_secondary_oog_protection(web3, transactions, mocker):
    """
    "Do we halt the sending when an oog occurs?" - continued.
    Check the secondary, double-checking protection
    """

    transactions[0]['tx']['gas'] = web3.toHex(transactions[0]['gasEstimate'] -
                                              1)

    signed = Signer(web3).sign_transactions(transactions)

    # check the secondary OOG-detection measure, by tricking the primary
    mocker.patch('utils.Sender._did_oog')
    Sender._did_oog.side_effect = [False, False]

    with pytest.raises(AirdropOOGException):
        Sender(web3).send_transactions(signed, transactions)
def test_throw_in_contract_handling(web3, prepared_contracts, transactions,
                                    airdrops):
    _, omg_token = prepared_contracts

    # whoops, omg_token got paused! omg_token should throw now
    pause_tx_hash = omg_token.transact().pause()
    Wait(web3).for_receipt(pause_tx_hash)

    # need to bump nonce in the pre-prepared transactions
    for transaction in transactions:
        transaction['tx']['nonce'] = web3.toHex(
            web3.toDecimal(transaction['tx']['nonce']) + 1)
    signed = Signer(web3).sign_transactions(transactions)

    with pytest.raises(AirdropOOGException):
        Sender(web3).send_transactions(signed, transactions)

    check_none_airdropped(airdrops, omg_token)
Example #15
0
def test_sender():
    Sender.__test()
Example #16
0
def send_mail(account_id):
    if request.method == 'POST':
        response_object = {'status': 'send mail success'}
        Login.log('sending mail...')
        vertification = {}
        # find vertification of the account
        for account in ACCOUNTS:
            if account['id'] == account_id:
                vertification = account
                Login.log('find account: {}'.format((str)(vertification)))
                break
        # the posted data is in form of jsonified mail as sent to client, so do the reverse
        post_data = request.get_json()
        Sender.send_mail(vertification, post_data)
        Login.log('Mail sent!')
        response_object.update({'message': 'Mail sent!'})
        return jsonify(response_object)
    else:  # GET, when getting mails
        # print('get_mails: {}'.format(account_id))
        response_object = {'status': 'get mail success'}
        account = {}
        mails = []
        for single_account in ACCOUNTS:
            if single_account['id'] == account_id:
                account = single_account
                break
        #### if there are mails of the account, clear them
        #### this step appears only removes mails on the odd position
        #### temporarily, the function cannot work properly, thus I choose to reset the MAILS every time client logins
        # for mail in MAILS:
        #     print(mail['Subject'])
        #     print(mail['account_id'])
        # for mail in MAILS:
        #     if (str)(mail['account_id']) == (str)(account_id):
        #         # print('remove duplicated mail {}'.format(mail['Subject']))
        #         MAILS.remove(mail)
        MAILS.clear()
        #### get mails of the account
        mail_link = Login.login(account, True)
        # raw_mails = Mails.retrMail(mail_link, end_retr_num=60, start_retr_num=10)
        # retrieve all the mails
        raw_mails = Mails.retrMail(mail_link)
        account_mails = Mails.contentSeparator(account_id, raw_mails)
        for raw_mail, account_mail in zip(raw_mails, account_mails):
            mail_id = uuid.uuid4().hex
            Mails.__save_raw_mails(raw_mail, account_id, mail_id)
            account_mail['id'] = mail_id
            account_mail['account_id'] = account_id
            MAILS.append(account_mail)
        #### return mails
        #### NOTICE: the function is designed to dynamically send mail to client at 100 a time
        #### and in reverse
        for mail in MAILS:
            if mail['account_id'] == account_id:
                if 'Subject' in mail.keys():
                    Login.log('find mail! {}'.format(mail['Subject']))
                else:
                    Login.log('find mail without Subject!\n{}'.format(
                        (str)(mail)))
                mails.append(mail)
        mails.reverse()
        response_object['mails'] = mails
        return jsonify(response_object)