Ejemplo n.º 1
0
TER
SetSignerList::replaceSignerList ()
{
    auto const accountKeylet = keylet::account (account_);
    auto const ownerDirKeylet = keylet::ownerDir (account_);
    auto const signerListKeylet = keylet::signers (account_);

    // This may be either a create or a replace.  Preemptively remove any
    // old signer list.  May reduce the reserve, so this is done before
    // checking the reserve.
    if (TER const ter = removeSignersFromLedger (
        accountKeylet, ownerDirKeylet, signerListKeylet))
            return ter;

    auto const sle = view().peek(accountKeylet);

    // Compute new reserve.  Verify the account has funds to meet the reserve.
    auto const oldOwnerCount = (*sle)[sfOwnerCount];
    std::uint32_t const addedOwnerCount = ownerCountDelta (signers_.size ());

    auto const newReserve =
        view().fees().accountReserve(oldOwnerCount + addedOwnerCount);

    // We check the reserve against the starting balance because we want to
    // allow dipping into the reserve to pay fees.  This behavior is consistent
    // with CreateTicket.
    if (mPriorBalance < newReserve)
        return tecINSUFFICIENT_RESERVE;

    // Everything's ducky.  Add the ltSIGNER_LIST to the ledger.
    auto signerList = std::make_shared<SLE>(signerListKeylet);
    view().insert (signerList);
    writeSignersToSLE (signerList);

    auto viewJ = ctx_.app.journal ("View");
    // Add the signer list to the account's directory.
    std::uint64_t hint;
    TER result = dirAdd(ctx_.view (), hint, ownerDirKeylet.key,
        signerListKeylet.key, describeOwnerDir (account_), viewJ);

    JLOG(j_.trace) << "Create signer list for account " <<
        toBase58(account_) << ": " << transHuman (result);

    if (result != tesSUCCESS)
        return result;

    signerList->setFieldU64 (sfOwnerNode, hint);

    // If we succeeded, the new entry counts against the creator's reserve.
    adjustOwnerCount(view(), sle, addedOwnerCount, viewJ);

    return result;
}
Ejemplo n.º 2
0
STValidation::STValidation(
    uint256 const& ledgerHash,
    std::uint32_t ledgerSeq,
    uint256 const& consensusHash,
    NetClock::time_point signTime,
    PublicKey const& publicKey,
    SecretKey const& secretKey,
    NodeID const& nodeID,
    bool isFull,
    FeeSettings const& fees,
    std::vector<uint256> const& amendments)
    : STObject(getFormat(), sfValidation), mNodeID(nodeID), mSeen(signTime)
{
    // This is our own public key and it should always be valid.
    if (!publicKeyType(publicKey))
        LogicError("Invalid validation public key");
    assert(mNodeID.isNonZero());
    setFieldH256(sfLedgerHash, ledgerHash);
    setFieldH256(sfConsensusHash, consensusHash);
    setFieldU32(sfSigningTime, signTime.time_since_epoch().count());

    setFieldVL(sfSigningPubKey, publicKey.slice());
    if (isFull)
        setFlag(kFullFlag);

    setFieldU32(sfLedgerSequence, ledgerSeq);

    if (fees.loadFee)
        setFieldU32(sfLoadFee, *fees.loadFee);

    if (fees.baseFee)
        setFieldU64(sfBaseFee, *fees.baseFee);

    if (fees.reserveBase)
        setFieldU32(sfReserveBase, *fees.reserveBase);

    if (fees.reserveIncrement)
        setFieldU32(sfReserveIncrement, *fees.reserveIncrement);

    if (!amendments.empty())
        setFieldV256(sfAmendments, STVector256(sfAmendments, amendments));

    setFlag(vfFullyCanonicalSig);

    auto const signingHash = getSigningHash();
    setFieldVL(
        sfSignature, signDigest(getSignerPublic(), secretKey, signingHash));

    setTrusted();
}