Ejemplo n.º 1
0
def post_uri(guid):
    offer_channel = channel_to_dict(
        g.chain.offer_registry.contract.functions.guidToChannel(
            guid.int).call())
    msig_address = offer_channel['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()

    try:
        _post_uri_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message)

    websocket_uri = body['websocketUri']

    transactions = [
        build_transaction(
            offer_msig.functions.setCommunicationUri(
                g.chain.w3.toHex(text=websocket_uri)), base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 2
0
def post_challange(guid):
    offer_channel = channel_to_dict(
        g.chain.offer_registry.contract.functions.guidToChannel(
            guid.int).call())
    msig_address = offer_channel['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()

    try:
        _post_challange_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message)

    state = g.chain.w3.toBytes(hexstr=body['state'])
    v = body['v']
    r = list(map(lambda s: g.chain.w3.toBytes(hexstr=s), body['r']))
    s = list(map(lambda s: g.chain.w3.toBytes(hexstr=s), body['s']))

    transactions = [
        build_transaction(offer_msig.functions.challengeSettle(state, v, r, s),
                          base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 3
0
def post_artifacts():
    config = app.config['POLYSWARMD']
    session = app.config['REQUESTS_SESSION']
    try:
        files = [(f'{i:06d}', f)
                 for (i, f) in enumerate(request.files.getlist(key='file'))
                 if check_size(f, g.user.max_artifact_size)]
    except (AttributeError, IOError):
        logger.error('Error checking file size')
        return failure('Unable to read file sizes', 400)
    except ArtifactTooLargeException:
        return failure('Artifact too large', 413)
    except ArtifactEmptyException:
        return failure('Artifact empty', 400)

    if not files:
        return failure('No artifacts', 400)
    if len(files) > config.artifact.limit:
        return failure('Too many artifacts', 400)

    try:
        response = success(config.artifact.client.add_artifacts(
            files, session))
    except HTTPError as e:
        response = failure(e.response.content, e.response.status_code)
    except ArtifactException as e:
        response = failure(e.message, 500)

    return response
Ejemplo n.º 4
0
def post_create_offer_channel():
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()

    try:
        _post_create_offer_channel_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message)

    guid = uuid.uuid4()
    ambassador = g.chain.w3.toChecksumAddress(body['ambassador'])
    expert = g.chain.w3.toChecksumAddress(body['expert'])
    settlement_period_length = body['settlementPeriodLength']

    transactions = [
        build_transaction(
            g.chain.offer_registry.contract.functions.initializeOfferChannel(
                guid.int, ambassador, expert, settlement_period_length),
            base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 5
0
def get_bounty_parameters():
    bounty_fee = g.chain.bounty_registry.contract.functions.bountyFee().call()
    assertion_fee = g.chain.bounty_registry.contract.functions.assertionFee(
    ).call()
    bounty_amount_minimum = g.chain.bounty_registry.contract.functions.BOUNTY_AMOUNT_MINIMUM(
    ).call()
    assertion_bid_minimum = g.chain.bounty_registry.contract.functions.ASSERTION_BID_ARTIFACT_MINIMUM(
    ).call()
    assertion_bid_maximum = g.chain.bounty_registry.contract.functions.ASSERTION_BID_ARTIFACT_MAXIMUM(
    ).call()
    arbiter_lookback_range = g.chain.bounty_registry.contract.functions.ARBITER_LOOKBACK_RANGE(
    ).call()
    max_duration = g.chain.bounty_registry.contract.functions.MAX_DURATION(
    ).call()
    assertion_reveal_window = g.chain.bounty_registry.contract.functions.assertionRevealWindow(
    ).call()
    arbiter_vote_window = g.chain.bounty_registry.contract.functions.arbiterVoteWindow(
    ).call()

    return success({
        'bounty_fee': bounty_fee,
        'assertion_fee': assertion_fee,
        'bounty_amount_minimum': bounty_amount_minimum,
        'assertion_bid_maximum': assertion_bid_maximum,
        'assertion_bid_minimum': assertion_bid_minimum,
        'arbiter_lookback_range': arbiter_lookback_range,
        'max_duration': max_duration,
        'assertion_reveal_window': assertion_reveal_window,
        'arbiter_vote_window': arbiter_vote_window
    })
Ejemplo n.º 6
0
def post_assertion_metadata():
    config = app.config['POLYSWARMD']
    session = app.config['REQUESTS_SESSION']
    body = request.get_json()
    loaded_body = json.loads(body) if isinstance(body, str) else body

    try:
        if not AssertionMetadata.validate(loaded_body, silent=True) and \
                not BountyMetadata.validate(loaded_body, silent=True):
            return failure('Invalid metadata', 400)
    except json.JSONDecodeError:
        # Expected when people provide incorrect metadata. Not stack worthy
        return failure('Invalid Assertion metadata', 400)

    try:
        uri = config.artifact.client.add_artifact(json.dumps(loaded_body),
                                                  session,
                                                  redis=config.redis.client)
        response = success(uri)
    except HTTPError as e:
        response = failure(e.response.content, e.response.status_code)
    except ArtifactException as e:
        response = failure(e.message, 500)
    except Exception:
        logger.exception('Received error posting to IPFS got response')
        response = failure('Could not add metadata to ipfs', 500)

    return response
Ejemplo n.º 7
0
def post_join(guid):
    offer_channel = channel_to_dict(
        g.chain.offer_registry.contract.functions.guidToChannel(
            guid.int).call())
    msig_address = offer_channel['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()

    try:
        _post_join_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message)

    state = body['state']
    v = body['v']
    r = body['r']
    s = body['s']

    transactions = [
        build_transaction(
            offer_msig.functions.joinAgreement(state, v, to_padded_hex(r),
                                               to_padded_hex(s)), base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 8
0
def post_bounties_guid_assertions(guid):
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()
    try:
        _post_bounties_guid_assertions_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    bid = [int(b) for b in body['bid']]
    mask = bool_list_to_int(body['mask'])
    verdict_count = len([m for m in body['mask'] if m])

    commitment = body.get('commitment')
    verdicts = body.get('verdicts')

    if commitment is None and verdicts is None:
        return failure('Require verdicts and bid_portions or a commitment',
                       400)

    if not bid or len(bid) != verdict_count:
        return failure(
            'bid_portions must be equal in length to the number of true mask values',
            400)

    max_bid = eth.assertion_bid_max(g.chain.bounty_registry.contract)
    min_bid = eth.assertion_bid_min(g.chain.bounty_registry.contract)
    if any((b for b in bid if max_bid < b < min_bid)):
        return failure('Invalid assertion bid', 400)

    approve_amount = sum(bid) + eth.assertion_fee(
        g.chain.bounty_registry.contract)

    nonce = None
    if commitment is None:
        nonce, commitment = calculate_commitment(account,
                                                 bool_list_to_int(verdicts))
    else:
        commitment = int(commitment)

    ret = {
        'transactions': [
            build_transaction(
                g.chain.nectar_token.contract.functions.approve(
                    g.chain.bounty_registry.contract.address, approve_amount),
                base_nonce),
            build_transaction(
                g.chain.bounty_registry.contract.functions.postAssertion(
                    guid.int, bid, mask, commitment), base_nonce + 1),
        ]
    }

    if nonce is not None:
        # Pass generated nonce onto user in response, used for reveal
        ret['nonce'] = nonce

    return success(ret)
Ejemplo n.º 9
0
def post_arbiter_staking_deposit():
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()
    try:
        _post_arbiter_staking_deposit_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    amount = int(body['amount'])

    total = g.chain.arbiter_staking.contract.functions.balanceOf(
        account).call()

    if amount + total >= eth.staking_total_max(
            g.chain.arbiter_staking.contract):
        return failure('Total stake above allowable maximum.', 400)

    transactions = [
        build_transaction(
            g.chain.nectar_token.contract.functions.approve(
                g.chain.arbiter_staking.contract.address, amount), base_nonce),
        build_transaction(
            g.chain.arbiter_staking.contract.functions.deposit(amount),
            base_nonce + 1),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 10
0
def post_arbiter_staking_withdrawal():
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))
    body = request.get_json()
    try:
        _post_arbiter_staking_withdrawal_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    amount = int(body['amount'])

    available = g.chain.arbiter_staking.contract.functions.withdrawableBalanceOf(
        account).call()

    if amount > available:
        return failure('Exceeds withdrawal eligible %s' % available, 400)

    transactions = [
        build_transaction(
            g.chain.arbiter_staking.contract.functions.withdraw(amount),
            base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 11
0
def get_settlement_period(guid):
    offer_channel = g.chain.offer_registry.contract.functions.guidToChannel(
        guid.int).call()
    channel_data = channel_to_dict(offer_channel)
    msig_address = channel_data['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)

    settlement_period_end = offer_msig.functions.settlementPeriodEnd().call()

    return success({'settlementPeriodEnd': settlement_period_end})
Ejemplo n.º 12
0
def post_bounties():
    config = app.config['POLYSWARMD']
    session = app.config['REQUESTS_SESSION']
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()
    try:
        _post_bounties_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    guid = uuid.uuid4()
    artifact_type = ArtifactType.from_string(body['artifact_type'])
    amount = int(body['amount'])
    artifact_uri = body['uri']
    duration_blocks = body['duration']
    metadata = body.get('metadata', '')

    try:
        arts = config.artifact.client.ls(artifact_uri, session)
    except HTTPError as e:
        return failure(e.response.content, e.response.status_code)
    except ArtifactException:
        logger.exception('Failed to ls given artifact uri')
        return failure(f'Failed to check artifact uri', 500)

    if amount < eth.bounty_amount_min(
            g.chain.bounty_registry.contract) * len(arts):
        return failure('Invalid bounty amount', 400)

    if metadata and not config.artifact.client.check_uri(metadata):
        return failure('Invalid bounty metadata URI (should be IPFS hash)',
                       400)

    num_artifacts = len(arts)
    bloom = calculate_bloom(arts)

    approve_amount = amount + eth.bounty_fee(g.chain.bounty_registry.contract)

    transactions = [
        build_transaction(
            g.chain.nectar_token.contract.functions.approve(
                g.chain.bounty_registry.contract.address, approve_amount),
            base_nonce),
        build_transaction(
            g.chain.bounty_registry.contract.functions.postBounty(
                guid.int, artifact_type.value, amount, artifact_uri,
                num_artifacts, duration_blocks, bloom, metadata),
            base_nonce + 1),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 13
0
def get_artifacts_status():
    config = app.config['POLYSWARMD']
    session = app.config['REQUESTS_SESSION']

    try:
        return success(config.artifact.client.status(session))

    except HTTPError as e:
        return failure(e.response.content, e.response.status_code)
    except ArtifactException as e:
        return failure(e.message, 500)
Ejemplo n.º 14
0
def get_balance_address_eth(address):
    if not g.chain.w3.isAddress(address):
        return failure('Invalid address', 400)

    address = g.chain.w3.toChecksumAddress(address)
    try:
        balance = g.chain.w3.eth.getBalance(address)
        return success(str(balance))
    except Exception:
        logger.exception('Unexpected exception retrieving ETH balance')
        return failure("Could not retrieve balance")
Ejemplo n.º 15
0
def get_pending_nonces():
    tx_pool = get_txpool()
    logger.debug('Got txpool response from Ethereum node: %s', tx_pool)
    transactions = dict()
    for key in tx_pool.keys():
        tx_pool_category_nonces = tx_pool[key].get(g.eth_address, {})
        transactions.update(dict(tx_pool_category_nonces))

    nonces = [str(nonce) for nonce in transactions.keys()]
    logger.debug('Pending txpool for %s: %s', g.eth_address, nonces)
    return success(nonces)
Ejemplo n.º 16
0
def get_balance_address_nct(address):
    if not g.chain.w3.isAddress(address):
        return failure('Invalid address', 400)

    address = g.chain.w3.toChecksumAddress(address)
    try:
        balance = g.chain.nectar_token.contract.functions.balanceOf(
            address).call()
        return success(str(balance))
    except Exception:
        logger.exception('Unexpected exception retrieving NCT balance')
        return failure("Could not retrieve balance")
Ejemplo n.º 17
0
def get_balance_total_stake(address):
    if not g.chain.w3.isAddress(address):
        return failure('Invalid address', 400)
    address = g.chain.w3.toChecksumAddress(address)
    try:
        balance = g.chain.arbiter_staking.contract.functions.balanceOf(
            address).call()
        return success(str(balance))
    except Exception:
        logger.exception(
            'Unexpected exception retrieving total staking balance')
        return failure("Could not retrieve balance")
Ejemplo n.º 18
0
def get_bounties_guid_assertions_id(guid, id_):
    bounty = bounty_to_dict(
        g.chain.bounty_registry.contract.functions.bountiesByGuid(
            guid.int).call())
    if bounty['author'] == ZERO_ADDRESS:
        return failure('Bounty not found', 404)

    try:
        assertion = get_assertion(guid, id_, bounty['num_artifacts'])
        return success(assertion)
    except:  # noqa: E772
        return failure('Assertion not found', 404)
Ejemplo n.º 19
0
def post_bounties_guid_settle(guid):
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    transactions = [
        build_transaction(
            g.chain.bounty_registry.contract.functions.settleBounty(guid.int),
            base_nonce)
    ]

    return success({'transactions': transactions})
Ejemplo n.º 20
0
def get_bounties_guid_votes_id(guid, id_):
    bounty = bounty_to_dict(
        g.chain.bounty_registry.contract.functions.bountiesByGuid(
            guid.int).call())
    if bounty['author'] == ZERO_ADDRESS:
        return failure('Bounty not found', 404)

    try:
        vote = vote_to_dict(
            g.chain.bounty_registry.contract.functions.votesByGuid(
                guid.int, id_).call(), bounty['num_artifacts'])
        return success(vote)
    except:  # noqa: E772
        return failure('Vote not found', 404)
Ejemplo n.º 21
0
def create_state():
    body = request.get_json()

    try:
        _create_state_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message)

    body['token_address'] = str(g.chain.nectar_token.address)

    if 'verdicts' in body and 'mask' in body:
        body['verdicts'] = bool_list_to_int(body['verdicts'])
        body['mask'] = bool_list_to_int(body['mask'])

    return success({'state': dict_to_state(body)})
Ejemplo n.º 22
0
def get_websocket(guid):
    offer_channel = g.chain.offer_registry.contract.functions.guidToChannel(
        guid.int).call()
    channel_data = channel_to_dict(offer_channel)
    msig_address = channel_data['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)
    socket_uri = offer_msig.functions.websocketUri().call()

    # TODO find a better way than replace
    socket_uri = g.chain.w3.toText(socket_uri).replace('\u0000', '')

    if not validate_ws_url(socket_uri):
        return failure('Contract does not have a valid WebSocket uri', 400)

    return success({'websocket': socket_uri})
Ejemplo n.º 23
0
def post_cancel(guid):
    offer_channel = channel_to_dict(
        g.chain.offer_registry.contract.functions.guidToChannel(
            guid.int).call())
    msig_address = offer_channel['msig_address']
    offer_msig = g.chain.offer_multi_sig.bind(msig_address)
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    transactions = [
        build_transaction(offer_msig.functions.cancel(), base_nonce),
    ]

    return success({'transactions': transactions})
Ejemplo n.º 24
0
def get_staking_parameters():
    minimum_stake = g.chain.arbiter_staking.contract.functions.MINIMUM_STAKE(
    ).call()
    maximum_stake = g.chain.arbiter_staking.contract.functions.MAXIMUM_STAKE(
    ).call()
    vote_ratio_numerator = g.chain.arbiter_staking.contract.functions.VOTE_RATIO_NUMERATOR(
    ).call()
    vote_ratio_denominator = g.chain.arbiter_staking.contract.functions.VOTE_RATIO_DENOMINATOR(
    ).call()

    return success({
        'minimum_stake': minimum_stake,
        'maximum_stake': maximum_stake,
        'vote_ratio_numerator': vote_ratio_numerator,
        'vote_ratio_denominator': vote_ratio_denominator
    })
Ejemplo n.º 25
0
def get_artifacts_identifier_id_stat(identifier, id_):
    config = app.config['POLYSWARMD']
    session = app.config['REQUESTS_SESSION']
    try:
        response = success(
            config.artifact.client.details(identifier, id_, session))
    except HTTPError as e:
        response = failure(e.response.content, e.response.status_code)
    except InvalidUriException:
        response = failure('Invalid artifact URI', 400)
    except ArtifactNotFoundException:
        response = failure(f'Artifact with URI {identifier} not found', 404)
    except ArtifactException as e:
        response = failure(e.message, 500)

    return response
Ejemplo n.º 26
0
def get_transactions():
    body = request.get_json()
    try:
        _get_transactions_schema_validator(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    ret: Dict[str, List[Any]] = defaultdict(list)
    for transaction in body['transactions']:
        event = events_from_transaction(HexBytes(transaction), g.chain.name)
        for k, v in event.items():
            ret[k].extend(v)

    if ret['errors']:
        logging.error('Got transaction errors: %s', ret['errors'])
        return failure(ret, 400)
    return success(ret)
Ejemplo n.º 27
0
def get_bounties_guid_bloom(guid):
    bounty = bounty_to_dict(
        g.chain.bounty_registry.contract.functions.bountiesByGuid(
            guid.int).call())
    if bounty['author'] == ZERO_ADDRESS:
        return failure('Bounty not found', 404)

    try:
        bloom_parts = []
        for i in range(0, 8):
            bloom_parts.append(
                g.chain.bounty_registry.contract.functions.bloomByGuid(
                    guid.int, i).call())
        bloom = bloom_to_dict(bloom_parts)
        return success(bloom)
    except:  # noqa: E772
        logger.exception('Bloom not found')
        return failure('Bloom not found', 404)
Ejemplo n.º 28
0
def get_closed():
    offers_closed = []
    num_of_offers = g.chain.offer_registry.contract.functions.getNumberOfOffers(
    ).call()

    for i in range(0, num_of_offers):
        guid = g.chain.offer_registry.contract.functions.channelsGuids(
            i).call()
        offer_channel = g.chain.offer_registry.contract.functions.guidToChannel(
            guid).call()
        channel_data = channel_to_dict(offer_channel)
        msig_address = channel_data['msig_address']
        offer_msig = g.chain.offer_multi_sig.bind(msig_address)
        closed_channel = offer_msig.functions.isClosed().call()
        if closed_channel:
            offers_closed.append({'guid': guid, 'address': msig_address})

    return success(offers_closed)
Ejemplo n.º 29
0
def post_bounties_guid_vote(guid):
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(
        request.args.get('base_nonce',
                         g.chain.w3.eth.getTransactionCount(account)))

    body = request.get_json()
    try:
        _post_bounties_guid_vote_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    votes = bool_list_to_int(body['votes'])
    valid_bloom = bool(body['valid_bloom'])

    transactions = [
        build_transaction(
            g.chain.bounty_registry.contract.functions.voteOnBounty(
                guid.int, votes, valid_bloom), base_nonce),
    ]
    return success({'transactions': transactions})
Ejemplo n.º 30
0
def send_funds_from():
    # Grab correct versions by chain type
    account = g.chain.w3.toChecksumAddress(g.eth_address)
    base_nonce = int(request.args.get('base_nonce', g.chain.w3.eth.getTransactionCount(account)))
    erc20_relay_address = g.chain.w3.toChecksumAddress(g.chain.erc20_relay.address)

    body = request.get_json()
    try:
        _send_funds_from_schema(body)
    except fastjsonschema.JsonSchemaException as e:
        return failure('Invalid JSON: ' + e.message, 400)

    amount = int(body['amount'])

    transactions = [
        build_transaction(
            g.chain.nectar_token.contract.functions.transfer(erc20_relay_address, amount), base_nonce
        ),
    ]

    return success({'transactions': transactions})