Esempio n. 1
0
def add_user(community_signing_key, community_id, user_signing_key,
             user_verify_key, user_id):
    """Add a test user to the network."""

    new_user_info = storage.Entity()
    new_user_info.id = user_id
    new_user_info.verify_key = user_verify_key.encode(
        encoder=nacl.encoding.RawEncoder)
    new_user_info.user.display_name = "New User One".encode('utf8')
    new_user_info.user.home_community_id = community_id

    new_user_blob = new_user_info.SerializeToString()
    signature = community_signing_key.sign(new_user_blob).signature

    add_user_message = handshake.AddUser()
    add_user_message.new_user = new_user_blob
    add_user_message.home_signature = signature

    binary_add_user = add_user_message.SerializeToString()
    res = requests.post(url="http://localhost:5000/register/user",
                        data=binary_add_user,
                        headers={'Content-Type': 'application/octet-stream'})

    if not res.ok:
        print(res)
        for line in res.iter_lines():
            print(line)
Esempio n. 2
0
def add_community(entity_id, verify_key):
    """Add a test community to the network"""
    new_community_info = storage.Entity()
    new_community_info.id = entity_id
    new_community_info.verify_key = verify_key.encode(
        encoder=nacl.encoding.RawEncoder)
    new_community_info.server.display_name = "New Community One".encode('utf8')

    binary_new_community_info = new_community_info.SerializeToString()

    add_community_message = handshake.AddCommunity()
    add_community_message.anchor_id = 0
    # TODO(matt9j) Figure out how the add signature will work for the first community.
    add_community_message.anchor_signature = b''
    add_community_message.new_community = binary_new_community_info

    binary_add_community = add_community_message.SerializeToString()

    res = requests.post(url="http://localhost:5000/register/community",
                        data=binary_add_community,
                        headers={'Content-Type': 'application/octet-stream'})

    if not res.ok:
        print(res)
        for line in res.iter_lines():
            print(line)
Esempio n. 3
0
def _parse_user_id_from_add_user(add_user_blob):
    add_user_payload = handshake_pb2.AddUser()
    add_user_payload.ParseFromString(add_user_blob)

    new_user_info = storage_pb2.Entity()
    new_user_info.ParseFromString(add_user_payload.new_user)

    return new_user_info.id
Esempio n. 4
0
def _parse_id_from_add_community(action_payload):
    # Parse outer message
    add_community_payload = handshake_pb2.AddCommunity()
    add_community_payload.ParseFromString(action_payload)

    new_community_info = storage_pb2.Entity()
    new_community_info.ParseFromString(add_community_payload.new_community)

    community_id = new_community_info.id

    return community_id
Esempio n. 5
0
def _parse_add_user(add_user_blob):
    """Deserialize the add user payload"""
    add_user_payload = handshake_pb2.AddUser()
    add_user_payload.ParseFromString(add_user_blob)
    blob_sig = add_user_payload.home_signature

    new_user_info = storage_pb2.Entity()
    new_user_info.ParseFromString(add_user_payload.new_user)

    home_id = new_user_info.user.home_community_id
    user_id = new_user_info.id

    return home_id, blob_sig, user_id, add_user_payload.new_user
Esempio n. 6
0
def _parse_add_community(action_payload):
    # Parse outer message
    add_community_payload = handshake_pb2.AddCommunity()
    add_community_payload.ParseFromString(action_payload)

    anchor_id = add_community_payload.anchor_id
    message_sig = add_community_payload.anchor_signature

    new_community_info = storage_pb2.Entity()
    new_community_info.ParseFromString(add_community_payload.new_community)

    community_id = new_community_info.id

    return anchor_id, message_sig, community_id, add_community_payload.new_community
Esempio n. 7
0
def _add_ledger_crdt(action_payload, context):
    """Add a crdt record to the on-chain crdt implementation."""

    exchange = asterales_parsers.parse_exchange_record(action_payload)

    # TODO(matt9j) handle gaps in the receive SQN?
    # TODO(matt9j) Validate that the sequence number has indeed progressed
    receive_sqn = exchange.receiver_sequence_number_msb * (2 ** 64) + \
                  exchange.receiver_sequence_number_lsb
    LOG.debug("Processing id: %d, sqn: %d to the ledger crdt",
              exchange.receiver_id, receive_sqn)

    # Validate the exchange signatures
    receiver_blob = _get_state_data(make_entity_address(exchange.receiver_id),
                                    context)
    receiver_data = storage_pb2.Entity()
    receiver_data.ParseFromString(receiver_blob)
    receive_verify_key = nacl.signing.VerifyKey(
        receiver_data.verify_key, encoder=nacl.encoding.RawEncoder)
    try:
        receive_verify_key.verify(exchange.receiver_signed_blob,
                                  exchange.receiver_signature,
                                  encoder=nacl.encoding.RawEncoder)
    except nacl.exceptions.BadSignatureError as e:
        LOG.error(e)
        raise InvalidTransaction(
            'Exchange receive signature invalid sqn:{}'.format(receive_sqn))

    sender_blob = _get_state_data(make_entity_address(exchange.sender_id),
                                  context)
    sender_data = storage_pb2.Entity()
    sender_data.ParseFromString(sender_blob)
    sender_verify_key = nacl.signing.VerifyKey(
        sender_data.verify_key, encoder=nacl.encoding.RawEncoder)
    try:
        sender_verify_key.verify(exchange.sender_signed_blob,
                                 exchange.sender_signature,
                                 encoder=nacl.encoding.RawEncoder)
    except nacl.exceptions.BadSignatureError:
        raise InvalidTransaction(
            'Exchange send signature invalid sqn:{}'.format(receive_sqn))

    crdt_address = make_crdt_address(exchange.receiver_id)
    current_crdt_blob = _get_state_data(crdt_address, context)

    if current_crdt_blob is not None:
        crdt_history = cbor.loads(current_crdt_blob)
    else:
        crdt_history = []

    if receive_sqn in crdt_history:
        LOG.info("Discarding duplicate upload sqn: %d", receive_sqn)
        return

    LOG.info("Record is new, adding id: %d, sqn: %d to the ledger crdt",
             exchange.receiver_id, receive_sqn)

    crdt_history.append(receive_sqn)
    _set_state_data(crdt_address, cbor.dumps(crdt_history), context)

    receiver_data.balance += exchange.amount
    _set_state_data(make_entity_address(exchange.receiver_id),
                    receiver_data.SerializeToString(), context)

    sender_data.balance -= exchange.amount
    _set_state_data(make_entity_address(exchange.sender_id),
                    sender_data.SerializeToString(), context)
Esempio n. 8
0
def _flatten_delta_crdt(action_payload, context, crdt_endpoint):
    """Flattens contiguous local CRDT records into the entity state"""
    # Parse the request.
    flatten_request = cbor2.loads(action_payload)
    # TODO(matt9j) Use the origin as a fallback if deltas are missing.
    # request_origin = flatten_request['origin']
    entity_id = flatten_request['entity_id']
    proposed_frontier = flatten_request['sqn']
    LOG.info("Attempting to flatten delta crdt for id: %d to frontier_sqn: %d",
             entity_id, proposed_frontier)

    # Lookup the current frontier sqn.
    entity_blob = _get_state_data(make_entity_address(entity_id), context)
    entity_pb = storage_pb2.Entity()
    entity_pb.ParseFromString(entity_blob)
    current_frontier = entity_pb.frontier_sequence_number
    LOG.debug('requesting endorsement for (%d, %d] for entity %d',
              current_frontier, proposed_frontier, entity_id)

    # ask the local CRDT for exchanges up to the new proposed frontier SQN
    crdt_request = {
        'receive_id': entity_id,
        'current_frontier': current_frontier,
        'proposed_frontier': proposed_frontier,
    }

    response = CRDT_SESSION.post(
        url=crdt_endpoint + "/crdt/endorsingRecords",
        data=cbor2.dumps(crdt_request),
        headers={'Content-Type': 'application/octet-stream'})
    if not response.ok:
        LOG.error("Unable to request endorsing crdt records %s", response)
        raise InvalidTransaction("Unable to request endorsement from CRDT")

    # Set aside the receiver information
    receiver_blob = _get_state_data(make_entity_address(entity_id), context)
    receiver_data = storage_pb2.Entity()
    receiver_data.ParseFromString(receiver_blob)
    receive_verify_key = nacl.signing.VerifyKey(
        receiver_data.verify_key, encoder=nacl.encoding.RawEncoder)

    # exchanges must be sorted already in ascending order by sequence number
    exchanges = cbor2.loads(response.content)
    frontier = current_frontier

    # TODO(matt9j) Possibly speedup by re-using exchange protobufs
    # validate all the exchanges
    for exchange_blob in exchanges:
        if frontier >= proposed_frontier:
            LOG.warning("Got too many exchange records or bad frontier req?!")
            break

        exchange = asterales_parsers.parse_exchange_record(exchange_blob)
        receive_sqn = exchange.receiver_sequence_number_msb * (2 ** 64) + \
                      exchange.receiver_sequence_number_lsb
        last_valid_receive_sqn = exchange.last_valid_sequence_number_msb * (2**64) + \
                                 exchange.last_valid_sequence_number_lsb
        # Validate signatures
        try:
            receive_verify_key.verify(exchange.receiver_signed_blob,
                                      exchange.receiver_signature,
                                      encoder=nacl.encoding.RawEncoder)
        except nacl.exceptions.BadSignatureError as e:
            LOG.error(e)
            raise InvalidTransaction(
                'Exchange receive signature invalid sqn:{}'.format(
                    receive_sqn))

        sender_blob = _get_state_data(make_entity_address(exchange.sender_id),
                                      context)
        sender_data = storage_pb2.Entity()
        sender_data.ParseFromString(sender_blob)
        sender_verify_key = nacl.signing.VerifyKey(
            sender_data.verify_key, encoder=nacl.encoding.RawEncoder)
        try:
            sender_verify_key.verify(exchange.sender_signed_blob,
                                     exchange.sender_signature,
                                     encoder=nacl.encoding.RawEncoder)
        except nacl.exceptions.BadSignatureError:
            raise InvalidTransaction(
                'Exchange send signature invalid sqn:{}'.format(receive_sqn))

        if last_valid_receive_sqn != frontier:
            LOG.warning("Gap discovered-- in this hacky initial implementation"
                        " state may now be corrupted.")
            raise InvalidTransaction()

        receiver_data.balance += exchange.amount

        # TODO(matt9j) Don't serialize all the send messages until done! Some
        #  may be repeated...
        sender_data.balance -= exchange.amount
        _set_state_data(make_entity_address(exchange.sender_id),
                        sender_data.SerializeToString(), context)

        frontier = receive_sqn

    # Serialize the common receive buffer at the end of processing.
    # TODO(matt9j) Fix LSB/MSB precision laziness.
    frontier_sequence_number_lsb = frontier & 0xFFFFFFFFFFFFFFFF
    frontier_sequence_number_msb = frontier >> 64
    receiver_data.frontier_sequence_number = frontier_sequence_number_lsb
    _set_state_data(make_entity_address(exchange.receiver_id),
                    receiver_data.SerializeToString(), context)