示例#1
0
def register_owner_account(token: Token):
    if Wallet.objects.filter(token=token, address__iexact=remove_0x_prefix(settings.HUB_OWNER_ACCOUNT_ADDRESS)).exists():
        logger.error('Owner account already registered.')
        return

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    logger.warning('Registering owner account: {}'.format(
        settings.HUB_OWNER_ACCOUNT_ADDRESS))

    latest_eon_number = LocalViewInterface.latest().eon_number()

    authorization_digest = Wallet(
        token=token, address=settings.HUB_OWNER_ACCOUNT_ADDRESS).get_admission_hash(latest_eon_number)
    authorization = sign_message(
        authorization_digest, settings.HUB_OWNER_ACCOUNT_KEY)
    latest_tos_config = TOSConfig.objects.all().order_by('time').last()
    tos_signature = sign_message(
        hex_value(latest_tos_config.digest()), settings.HUB_OWNER_ACCOUNT_KEY)
    registration = AdmissionRequestSerializer(data={
        'token': token.address,
        'address': remove_0x_prefix(settings.HUB_OWNER_ACCOUNT_ADDRESS),
        'authorization': {
            'value': encode_signature(authorization)
        },
        'tos_signature': {
            'value': encode_signature(tos_signature)
        }
    })
    registration.is_valid(raise_exception=True)
    registration.save()
    process_admissions()
示例#2
0
 def get_last_checkpoint(self, block_identifier='latest'):
     eon_number = self.get_last_checkpoint_submission_eon()
     eons_kept = LocalViewInterface.get_contract_parameters().eons_kept
     return self.contract\
         .functions\
         .getCheckpointAtSlot(eon_number % eons_kept)\
         .call(block_identifier=block_identifier)
示例#3
0
def register_owner_account(token: Token):
    if Wallet.objects.filter(token=token,
                             address=remove_0x_prefix(
                                 settings.HUB_OWNER_ACCOUNT_ADDRESS)).exists():
        return

    if not LocalViewInterface.get_contract_parameters():
        return

    latest_eon_number = LocalViewInterface.latest().eon_number()

    authorization_digest = Wallet(
        token=token,
        address=settings.HUB_OWNER_ACCOUNT_ADDRESS).get_admission_hash(
            latest_eon_number)
    authorization = sign_message(authorization_digest,
                                 settings.HUB_OWNER_ACCOUNT_KEY)
    latest_tos_config = TOSConfig.objects.all().order_by('time').last()
    tos_signature = sign_message(decode_hex(latest_tos_config.digest()),
                                 settings.HUB_OWNER_ACCOUNT_KEY)

    registration = AdmissionRequestSerializer(
        data={
            'token': token.address,
            'address': remove_0x_prefix(settings.HUB_OWNER_ACCOUNT_ADDRESS),
            'authorization': {
                'value': encode_signature(authorization)
            },
            'tos_signature': {
                'value': encode_signature(tos_signature)
            }
        })
    registration.is_valid(raise_exception=True)
    registration.save()
示例#4
0
def process_admissions():

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    # This lock is needed because new wallets can be introduced, which would affect the checkpoint.
    with RootCommitment.global_lock():
        process_admissions_for_latest_eon()
示例#5
0
    def get_deposits(self,
                     token_address,
                     eon_number,
                     block_identifier='latest'):
        eons_kept = LocalViewInterface.get_contract_parameters().eons_kept
        aggregate_eon, aggregate_value = self.contract\
            .functions\
            .getDepositsAtSlot(add_0x_prefix(token_address), eon_number % eons_kept)\
            .call(block_identifier=block_identifier)

        return aggregate_value if aggregate_eon == eon_number else 0
def cancel_finalize_swaps():

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    latest_eon_number = LocalViewInterface.latest().eon_number()

    # This lock is required because the ledger will be mutated as the swaps are processed
    with RootCommitment.global_lock():
        cancel_finalize_swaps_for_eon(latest_eon_number)
示例#7
0
def process_passive_transfers():
    logger.info('Processing passive transfers')

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    latest_eon_number = LocalViewInterface.latest().eon_number()

    # This lock is required because the ledger will be mutated as the transfers are processed
    with RootCommitment.global_lock():
        logger.info('Start')
        process_passive_transfers_for_eon(latest_eon_number)
示例#8
0
def create_checkpoint_for_eon(eon_number, latest_block_number):
    if RootCommitment.objects.filter(eon_number=eon_number).count() > 0:
        return False

    if eon_number > 1:
        last_eon_number = eon_number - 1
        last_eon = LocalViewInterface.confirmed(eon_number=last_eon_number)
        if not last_eon:
            logger.error(
                'Missing confirmed contract state for eon {}.'.format(last_eon_number))
            send_admin_email(
                subject='Soft Checkpoint Error: Missing Contract State',
                content='Missing confirmed contract state for previous eon {}. We may not be in sync with the blockchain!'.format(last_eon_number))
            return False

        last_confirmed_eon_number, last_confirmed_sub_block = last_eon.eon_number_and_sub_block()
        if last_confirmed_eon_number != last_eon_number:
            logger.error(
                'Attempted to use confirmed state for eon {}. Expected {}.'.format(last_confirmed_eon_number,
                                                                                   last_eon_number))
            send_admin_email(
                subject='Soft Checkpoint Error: Wrong last eon #',
                content='Need to sync chain! Attempted to use confirmed state for eon {}. Expected {}!'
                .format(last_confirmed_eon_number,
                        last_eon_number))
            return False
        last_sub_block_number = LocalViewInterface.get_contract_parameters().blocks_per_eon - 1
        if last_confirmed_sub_block != last_sub_block_number:
            logger.error(
                'Attempted to use confirmed state for sub block {}. Expected {}.'.format(last_confirmed_sub_block,
                                                                                         last_sub_block_number))
            send_admin_email(
                subject='Soft Checkpoint Error: Wrong last Sub block #',
                content='Need to sync chain! Attempted to use confirmed state for sub block {}. Expected {}.'
                .format(last_confirmed_sub_block,
                        last_sub_block_number))
            return False

    # commitment write read lock makes sure transaction confirmation will not mutate ledger while checkpoint is being created
    with transaction.atomic(), RootCommitment.read_write_lock(suffix=eon_number-1, is_write=True, auto_renewal=True):
        # TODO parallelism
        token_commitments = [create_token_commitment_for_eon(token, eon_number) for token in
                             Token.objects.all().order_by('trail')]

        root_commitment = create_root_commitment_for_eon(
            token_commitments, eon_number, latest_block_number)

        NOCUSTContractInterface().queue_submit_checkpoint(root_commitment)

    return True
示例#9
0
def synchronize_contract_state(verbose=False):
    logger.info('Retrieving confirmed events')

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    with ContractState.global_lock():
        logger.info('Start..')
        contract_interface = NOCUSTContractInterface()
        logger.info('Interface acquired')
        contract_event_decoder = NOCUSTContractEventDecoder()
        logger.info('Decoder acquired')
        contract_interface.get_blocks_per_eon()

        return concurrently_retrieve_state(contract_interface,
                                           contract_event_decoder, verbose)
示例#10
0
def create_checkpoint():

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    latest = LocalViewInterface.latest()
    latest_eon_number, latest_sub_block = latest.eon_number_and_sub_block()
    blocks_for_creation = LocalViewInterface.blocks_for_creation()

    confirmed_eon_number, confirmed_sub_block = LocalViewInterface.confirmed(
    ).eon_number_and_sub_block()
    if confirmed_eon_number < latest_eon_number:
        return
    if latest_sub_block < blocks_for_creation:
        return

    with RootCommitment.global_lock():
        new_checkpoint = create_checkpoint_for_eon(latest_eon_number, latest.block)
        if new_checkpoint:
            operator_celery.send_task('auditor.tasks.broadcast_wallet_data')
示例#11
0
def register_sla_recipient_account():
    if same_hex_value(settings.SLA_RECIPIENT_ADDRESS,
                      settings.HUB_OWNER_ACCOUNT_ADDRESS):
        logger.warning('Skipping registration: Hub Owner is SLA recipient.')
        return

    token = Token.objects.filter(
        address__iexact=remove_0x_prefix(settings.SLA_TOKEN_ADDRESS))

    if not token.exists():
        logger.error('SLA Payment Token not yet registered.')
        return

    if Wallet.objects.filter(token=token,
                             address__iexact=remove_0x_prefix(
                                 settings.SLA_RECIPIENT_ADDRESS)).exists():
        logger.error('Recipient account already registered.')
        return

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    latest_eon = LocalViewInterface.latest().eon_number()

    authorization_digest = Wallet(
        token=token,
        address=settings.SLA_RECIPIENT_ADDRESS).get_admission_hash(latest_eon)
    authorization = sign_message(authorization_digest,
                                 settings.SLA_RECIPIENT_KEY)
    registration = AdmissionRequestSerializer(
        data={
            'token': token.address,
            'address': remove_0x_prefix(settings.SLA_RECIPIENT_ADDRESS),
            'authorization': encode_signature(authorization)
        })
    registration.is_valid(raise_exception=True)
    registration.save()
    process_admissions()
示例#12
0
def register_eth_token():
    if Token.objects.filter(address__iexact=remove_0x_prefix(
            settings.HUB_LQD_CONTRACT_ADDRESS)).exists():
        logger.error('ETH token already registered.')
        return

    if not LocalViewInterface.get_contract_parameters():
        logger.error('Contract parameters not yet populated.')
        return

    logger.warning('Registering ETH Token')

    eth_token = register_token(token_address=settings.HUB_LQD_CONTRACT_ADDRESS,
                               name='Ethereum',
                               short_name='ETH',
                               register_on_chain=False)

    ContractLedgerState.objects.create(
        contract_state=LocalViewInterface.genesis(),
        token=eth_token,
        pending_withdrawals=0,
        confirmed_withdrawals=0,
        deposits=0,
        total_balance=0)
示例#13
0
    def fetch_contract_state_at_block(self, block_number):
        try:
            local_params = LocalViewInterface.get_contract_parameters()
            current_eon = 1 + \
                (block_number - local_params.genesis_block) // local_params.blocks_per_eon

            contract_state_variables = self.contract\
                .functions\
                .getServerContractStateVariables()\
                .call(block_identifier=block_number)

            basis = contract_state_variables[0]
            last_checkpoint_submission_eon = contract_state_variables[1]
            last_checkpoint = contract_state_variables[2]
            is_checkpoint_submitted_for_current_eon = contract_state_variables[
                3]
            has_missed_checkpoint_submission = contract_state_variables[4]
            live_challenge_count = contract_state_variables[5]

        except Exception as exception:
            traceback.print_exc()
            logger.error('Could not query contract state: {}'.format(
                str(exception)))
            return None

        contract_state = ContractState(
            block=block_number,
            confirmed=False,
            basis=crypto.hex_value(basis),
            last_checkpoint_submission_eon=last_checkpoint_submission_eon,
            last_checkpoint=crypto.hex_value(last_checkpoint),
            is_checkpoint_submitted_for_current_eon=
            is_checkpoint_submitted_for_current_eon,
            has_missed_checkpoint_submission=has_missed_checkpoint_submission,
            live_challenge_count=live_challenge_count)

        contract_ledger_states = []
        for token in Token.objects.all():
            if token.block >= block_number:
                continue

            try:
                contract_state_ledger_variables = self.contract\
                    .functions\
                    .getServerContractLedgerStateVariables(current_eon, add_0x_prefix(token.address))\
                    .call(block_identifier=block_number)

                pending_withdrawals = contract_state_ledger_variables[0]
                confirmed_withdrawals = contract_state_ledger_variables[1]
                deposits = contract_state_ledger_variables[2]
                total_balance = contract_state_ledger_variables[3]

                contract_ledger_states.append(
                    ContractLedgerState(
                        token=token,
                        pending_withdrawals=pending_withdrawals,
                        confirmed_withdrawals=confirmed_withdrawals,
                        deposits=deposits,
                        total_balance=total_balance))
            except Exception as exception:
                traceback.print_exc()
                logger.error(
                    'Could not query contract ledger state for {}: {}'.format(
                        token.address, str(exception)))
                contract_ledger_states.append(
                    ContractLedgerState(token=token,
                                        pending_withdrawals=0,
                                        confirmed_withdrawals=0,
                                        deposits=0,
                                        total_balance=0))

        return contract_state, contract_ledger_states
示例#14
0
 def get_basis(self, eon_number, block_identifier='latest'):
     eons_kept = LocalViewInterface.get_contract_parameters().eons_kept
     return self.contract\
         .functions\
         .getParentChainAccumulatorAtSlot(eon_number % eons_kept)\
         .call(block_identifier=block_identifier)