bool proto_to_abs_locktime(const Locktime *l, struct abs_locktime *locktime) { switch (l->locktime_case) { case LOCKTIME__LOCKTIME_SECONDS: return seconds_to_abs_locktime(l->seconds, locktime); case LOCKTIME__LOCKTIME_BLOCKS: return blocks_to_abs_locktime(l->blocks, locktime); default: return false; } }
static enum channel_add_err add_htlc(struct channel *channel, enum htlc_state state, u64 id, struct amount_msat amount, u32 cltv_expiry, const struct sha256 *payment_hash, const u8 routing[TOTAL_PACKET_SIZE], struct htlc **htlcp, bool enforce_aggregate_limits) { struct htlc *htlc, *old; struct amount_msat msat_in_htlcs, committed_msat, adding_msat, removing_msat; struct amount_sat fee; enum side sender = htlc_state_owner(state), recipient = !sender; const struct htlc **committed, **adding, **removing; const struct channel_view *view; bool ok; size_t i; htlc = tal(tmpctx, struct htlc); htlc->id = id; htlc->amount = amount; htlc->state = state; htlc->shared_secret = NULL; /* FIXME: Change expiry to simple u32 */ /* BOLT #2: * * A receiving node: *... * - if sending node sets `cltv_expiry` to greater or equal to * 500000000: * - SHOULD fail the channel. */ if (!blocks_to_abs_locktime(cltv_expiry, &htlc->expiry)) { return CHANNEL_ERR_INVALID_EXPIRY; } htlc->rhash = *payment_hash; htlc->fail = NULL; htlc->failcode = 0; htlc->failed_scid = NULL; htlc->r = NULL; htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0); old = htlc_get(channel->htlcs, htlc->id, htlc_owner(htlc)); if (old) { if (old->state != htlc->state || !amount_msat_eq(old->amount, htlc->amount) || old->expiry.locktime != htlc->expiry.locktime || !sha256_eq(&old->rhash, &htlc->rhash)) return CHANNEL_ERR_DUPLICATE_ID_DIFFERENT; else return CHANNEL_ERR_DUPLICATE; } /* We're always considering the recipient's view of the channel here */ view = &channel->view[recipient]; /* BOLT #2: * * A receiving node: * - receiving an `amount_msat` equal to 0, OR less than its own * `htlc_minimum_msat`: * - SHOULD fail the channel. */ if (amount_msat_eq(htlc->amount, AMOUNT_MSAT(0))) { return CHANNEL_ERR_HTLC_BELOW_MINIMUM; } if (amount_msat_less(htlc->amount, channel->config[recipient].htlc_minimum)) { return CHANNEL_ERR_HTLC_BELOW_MINIMUM; } /* BOLT #2: * * - for channels with `chain_hash` identifying the Bitcoin blockchain: * - MUST set the four most significant bytes of `amount_msat` to 0. */ if (amount_msat_greater(htlc->amount, channel->chainparams->max_payment)) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } /* Figure out what receiver will already be committed to. */ gather_htlcs(tmpctx, channel, recipient, &committed, &removing, &adding); htlc_arr_append(&adding, htlc); /* BOLT #2: * * - if a sending node adds more than receiver `max_accepted_htlcs` * HTLCs to its local commitment transaction... * - SHOULD fail the channel. */ if (tal_count(committed) - tal_count(removing) + tal_count(adding) > channel->config[recipient].max_accepted_htlcs) { return CHANNEL_ERR_TOO_MANY_HTLCS; } /* These cannot overflow with HTLC amount limitations, but * maybe adding could later if they try to add a maximal HTLC. */ if (!sum_offered_msatoshis(&committed_msat, committed, htlc_owner(htlc)) || !sum_offered_msatoshis(&removing_msat, removing, htlc_owner(htlc)) || !sum_offered_msatoshis(&adding_msat, adding, htlc_owner(htlc))) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } if (!amount_msat_add(&msat_in_htlcs, committed_msat, adding_msat) || !amount_msat_sub(&msat_in_htlcs, msat_in_htlcs, removing_msat)) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } /* BOLT #2: * * - if a sending node... adds more than receiver * `max_htlc_value_in_flight_msat` worth of offered HTLCs to its * local commitment transaction: * - SHOULD fail the channel. */ /* We don't enforce this for channel_force_htlcs: some might already * be fulfilled/failed */ if (enforce_aggregate_limits && amount_msat_greater(msat_in_htlcs, channel->config[recipient].max_htlc_value_in_flight)) { return CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED; } /* BOLT #2: * * A receiving node: *... * - receiving an `amount_msat` that the sending node cannot afford at * the current `feerate_per_kw` (while maintaining its channel * reserve): * - SHOULD fail the channel. */ if (channel->funder == htlc_owner(htlc)) { u32 feerate = view->feerate_per_kw; struct amount_sat dust_limit = channel->config[recipient].dust_limit; size_t untrimmed; untrimmed = commit_tx_num_untrimmed(committed, feerate, dust_limit, recipient) + commit_tx_num_untrimmed(adding, feerate, dust_limit, recipient) - commit_tx_num_untrimmed(removing, feerate, dust_limit, recipient); fee = commit_tx_base_fee(feerate, untrimmed); } else fee = AMOUNT_SAT(0); assert((s64)fee.satoshis >= 0); /* Raw: explicit signedness test */ if (enforce_aggregate_limits) { /* Figure out what balance sender would have after applying all * pending changes. */ struct amount_msat balance = view->owed[sender]; /* This is a little subtle: * * The change is being applied to the receiver but it will * come back to the sender after revoke_and_ack. So the check * here is that the balance to the sender doesn't go below the * sender's reserve. */ const struct amount_sat reserve = channel->config[!sender].channel_reserve; assert(amount_msat_greater_eq(balance, AMOUNT_MSAT(0))); ok = true; for (i = 0; i < tal_count(removing); i++) ok &= balance_remove_htlc(&balance, removing[i], sender); assert(amount_msat_greater_eq(balance, AMOUNT_MSAT(0))); for (i = 0; i < tal_count(adding); i++) ok &= balance_add_htlc(&balance, adding[i], sender); /* Overflow shouldn't happen, but if it does, complain */ if (!ok) { status_broken("Failed to add %zu remove %zu htlcs", tal_count(adding), tal_count(removing)); return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; } if (!amount_msat_sub_sat(&balance, balance, fee)) { status_trace("Cannot afford fee %s with balance %s", type_to_string(tmpctx, struct amount_sat, &fee), type_to_string(tmpctx, struct amount_msat, &balance)); return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; } if (!amount_msat_greater_eq_sat(balance, reserve)) { status_trace("Cannot afford fee %s: would make balance %s" " below reserve %s", type_to_string(tmpctx, struct amount_sat, &fee), type_to_string(tmpctx, struct amount_msat, &balance), type_to_string(tmpctx, struct amount_sat, &reserve)); return CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED; }