bool PaymentOpFrame::doApply(medida::MetricsRegistry& metrics, LedgerDelta& delta, LedgerManager& ledgerManager) { // if sending to self directly, just mark as success if (mPayment.destination == getSourceID()) { metrics.NewMeter({"op-payment", "success", "apply"}, "operation") .Mark(); innerResult().code(PAYMENT_SUCCESS); return true; } // build a pathPaymentOp Operation op; op.sourceAccount = mOperation.sourceAccount; op.body.type(PATH_PAYMENT); PathPaymentOp& ppOp = op.body.pathPaymentOp(); ppOp.sendAsset = mPayment.asset; ppOp.destAsset = mPayment.asset; ppOp.destAmount = mPayment.amount; ppOp.sendMax = mPayment.amount; ppOp.destination = mPayment.destination; OperationResult opRes; opRes.code(opINNER); opRes.tr().type(PATH_PAYMENT); PathPaymentOpFrame ppayment(op, opRes, mParentTx); ppayment.setSourceAccountPtr(mSourceAccount); if (!ppayment.doCheckValid(metrics) || !ppayment.doApply(metrics, delta, ledgerManager)) { if (ppayment.getResultCode() != opINNER) { throw std::runtime_error("Unexpected error code from pathPayment"); } PaymentResultCode res; switch (PathPaymentOpFrame::getInnerCode(ppayment.getResult())) { case PATH_PAYMENT_UNDERFUNDED: metrics.NewMeter({"op-payment", "failure", "underfunded"}, "operation").Mark(); res = PAYMENT_UNDERFUNDED; break; case PATH_PAYMENT_SRC_NOT_AUTHORIZED: metrics.NewMeter({"op-payment", "failure", "src-not-authorized"}, "operation").Mark(); res = PAYMENT_SRC_NOT_AUTHORIZED; break; case PATH_PAYMENT_SRC_NO_TRUST: metrics.NewMeter({"op-payment", "failure", "src-no-trust"}, "operation").Mark(); res = PAYMENT_SRC_NO_TRUST; break; case PATH_PAYMENT_NO_DESTINATION: metrics.NewMeter({"op-payment", "failure", "no-destination"}, "operation").Mark(); res = PAYMENT_NO_DESTINATION; break; case PATH_PAYMENT_NO_TRUST: metrics.NewMeter({"op-payment", "failure", "no-trust"}, "operation") .Mark(); res = PAYMENT_NO_TRUST; break; case PATH_PAYMENT_NOT_AUTHORIZED: metrics.NewMeter({"op-payment", "failure", "not-authorized"}, "operation").Mark(); res = PAYMENT_NOT_AUTHORIZED; break; case PATH_PAYMENT_LINE_FULL: metrics.NewMeter({"op-payment", "failure", "line-full"}, "operation").Mark(); res = PAYMENT_LINE_FULL; break; case PATH_PAYMENT_NO_ISSUER: metrics.NewMeter({"op-payment", "failure", "no-issuer"}, "operation").Mark(); res = PAYMENT_NO_ISSUER; break; default: throw std::runtime_error("Unexpected error code from pathPayment"); } innerResult().code(res); return false; } assert(PathPaymentOpFrame::getInnerCode(ppayment.getResult()) == PATH_PAYMENT_SUCCESS); metrics.NewMeter({"op-payment", "success", "apply"}, "operation").Mark(); innerResult().code(PAYMENT_SUCCESS); return true; }
bool PaymentOpFrame::doApply(LedgerDelta& delta, LedgerManager& ledgerManager) { AccountFrame destination; // if sending to self directly, just mark as success if (mPayment.destination == getSourceID()) { innerResult().code(PAYMENT_SUCCESS); return true; } Database& db = ledgerManager.getDatabase(); if (!AccountFrame::loadAccount(mPayment.destination, destination, db)) { innerResult().code(PAYMENT_NO_DESTINATION); return false; } // build a pathPaymentOp Operation op; op.sourceAccount = mOperation.sourceAccount; op.body.type(PATH_PAYMENT); PathPaymentOp& ppOp = op.body.pathPaymentOp(); ppOp.sendCurrency = mPayment.currency; ppOp.destCurrency = mPayment.currency; ppOp.destAmount = mPayment.amount; ppOp.sendMax = mPayment.amount; ppOp.destination = mPayment.destination; OperationResult opRes; opRes.code(opINNER); opRes.tr().type(PATH_PAYMENT); PathPaymentOpFrame ppayment(op, opRes, mParentTx); ppayment.setSourceAccountPtr(mSourceAccount); if (!ppayment.doCheckValid() || !ppayment.doApply(delta, ledgerManager)) { if (ppayment.getResultCode() != opINNER) { throw std::runtime_error("Unexpected error code from pathPayment"); } PaymentResultCode res; switch (PathPaymentOpFrame::getInnerCode(ppayment.getResult())) { case PATH_PAYMENT_UNDERFUNDED: res = PAYMENT_UNDERFUNDED; break; case PATH_PAYMENT_NO_DESTINATION: res = PAYMENT_NO_DESTINATION; break; case PATH_PAYMENT_NO_TRUST: res = PAYMENT_NO_TRUST; break; case PATH_PAYMENT_NOT_AUTHORIZED: res = PAYMENT_NOT_AUTHORIZED; break; case PATH_PAYMENT_LINE_FULL: res = PAYMENT_LINE_FULL; break; default: throw std::runtime_error("Unexpected error code from pathPayment"); } innerResult().code(res); return false; } assert(PathPaymentOpFrame::getInnerCode(ppayment.getResult()) == PATH_PAYMENT_SUCCESS); innerResult().code(PAYMENT_SUCCESS); return true; }