Example #1
0
// make sure the deleted Account hasn't issued credit
// make sure we aren't holding any credit
// make sure the we delete all the offers
// make sure the we delete all the trustlines
// move the XLM to the new account
bool
MergeOpFrame::doApply(Application& app, AbstractLedgerState& ls)
{
    auto header = ls.loadHeader();

    auto otherAccount = stellar::loadAccount(ls, mOperation.body.destination());
    if (!otherAccount)
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "no-account"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_NO_ACCOUNT);
        return false;
    }

    int64_t sourceBalance = 0;
    if (header.current().ledgerVersion > 4 &&
        header.current().ledgerVersion < 8)
    {
        // in versions < 8, merge account could be called with a stale account
        LedgerKey key(ACCOUNT);
        key.account().accountID = getSourceID();
        auto thisAccount = ls.loadWithoutRecord(key);
        if (!thisAccount)
        {
            app.getMetrics()
                .NewMeter({"op-merge", "failure", "no-account"}, "operation")
                .Mark();
            innerResult().code(ACCOUNT_MERGE_NO_ACCOUNT);
            return false;
        }

        if (header.current().ledgerVersion > 5)
        {
            sourceBalance = thisAccount.current().data.account().balance;
        }
    }

    auto sourceAccountEntry = loadSourceAccount(ls, header);
    auto const& sourceAccount = sourceAccountEntry.current().data.account();
    // Only set sourceBalance here if it wasn't set in the previous block
    if (header.current().ledgerVersion <= 5 ||
        header.current().ledgerVersion >= 8)
    {
        sourceBalance = sourceAccount.balance;
    }

    if (isImmutableAuth(sourceAccountEntry))
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "static-auth"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_IMMUTABLE_SET);
        return false;
    }

    if (sourceAccount.numSubEntries != sourceAccount.signers.size())
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "has-sub-entries"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_HAS_SUB_ENTRIES);
        return false;
    }

    if (header.current().ledgerVersion >= 10)
    {
        SequenceNumber maxSeq = getStartingSequenceNumber(header);

        // don't allow the account to be merged if recreating it would cause it
        // to jump backwards
        if (sourceAccount.seqNum >= maxSeq)
        {
            app.getMetrics()
                .NewMeter({"op-merge", "failure", "too-far"}, "operation")
                .Mark();
            innerResult().code(ACCOUNT_MERGE_SEQNUM_TOO_FAR);
            return false;
        }
    }

    // "success" path starts
    if (!addBalance(header, otherAccount, sourceBalance))
    {
        app.getMetrics()
            .NewMeter({"op-merge", "failure", "dest-full"}, "operation")
            .Mark();
        innerResult().code(ACCOUNT_MERGE_DEST_FULL);
        return false;
    }

    sourceAccountEntry.erase();

    app.getMetrics()
        .NewMeter({"op-merge", "success", "apply"}, "operation")
        .Mark();
    innerResult().code(ACCOUNT_MERGE_SUCCESS);
    innerResult().sourceAccountBalance() = sourceBalance;
    return true;
}
Example #2
0
void Job::evaluate(Brain * brain)
{
    //
    addRatio(brain->getRatio());
    addBalance(brain->getBalance());
    addError(brain->getError());
    QString fileName = saveDirectory + "/" +
            QString::number(brain->getBalance(),'f',2) + " | " +
            QString::number(brain->getRatio(),'f',4) + " | " +
            QString::number(brain->getError(),'f',2) +".brain";
    //
    if(evaluationMode == BALANCE)
    {
        mutexAverageBalance.lock();
        float averageBalanceTmp = averageBalance;
        mutexAverageBalance.unlock();
        if(brain->getBalance() > averageBalanceTmp)
        {
            copyToBestBrain(brain);
        }
        if(brain->getBalance() > bestBalanceEver)
        {
            copyToBestBrainEver(brain);
            bestBalanceEver = brain->getBalance();
            saveBestBrain(fileName);
        }
    }
    else if(evaluationMode == RATIO)
    {
        mutexAverageRatio.lock();
        float averageRatioTmp = averageRatio;
        mutexAverageRatio.unlock();
        if(brain->getRatio() > averageRatioTmp)
        {
            copyToBestBrain(brain);
        }
        /*if(brain->getRatio() > bestRatioEver)
        {
            copyToBestBrainEver(brain);
            bestRatioEver = brain->getRatio();
            saveBestBrain(fileName);
        }*/
    }
    else if(evaluationMode == ERROR)
    {
        mutexAverageError.lock();
        float averageErrorTmp = averageError;
        mutexAverageError.unlock();
        if(brain->getError() < averageErrorTmp)
        {
            copyToBestBrain(brain);
        }
        if(brain->getError() < bestErrorEver)
        {
            copyToBestBrainEver(brain);
            bestErrorEver = brain->getError();
            saveBestBrain(fileName);
        }
    }
    //
    copyFromBestBrain(brain);
    brain->mutate(mutationFrequency, mutationIntensity);
}