/* This file was generated by generate-wire.py */
/* Do not modify this file! Modify the .csv file it was generated from. */
/* Original template can be found at tools/gen/impl_template */

#include <wire/onion_wiregen.h>
#include <assert.h>
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <common/utils.h>
#include <stdio.h>

#ifndef SUPERVERBOSE
#define SUPERVERBOSE(...)
#endif


const char *onion_wire_name(int e)
{
	static char invalidbuf[sizeof("INVALID ") + STR_MAX_CHARS(e)];

	switch ((enum onion_wire)e) {
	case WIRE_INVALID_REALM: return "WIRE_INVALID_REALM";
	case WIRE_TEMPORARY_NODE_FAILURE: return "WIRE_TEMPORARY_NODE_FAILURE";
	case WIRE_PERMANENT_NODE_FAILURE: return "WIRE_PERMANENT_NODE_FAILURE";
	case WIRE_REQUIRED_NODE_FEATURE_MISSING: return "WIRE_REQUIRED_NODE_FEATURE_MISSING";
	case WIRE_INVALID_ONION_VERSION: return "WIRE_INVALID_ONION_VERSION";
	case WIRE_INVALID_ONION_HMAC: return "WIRE_INVALID_ONION_HMAC";
	case WIRE_INVALID_ONION_KEY: return "WIRE_INVALID_ONION_KEY";
	case WIRE_TEMPORARY_CHANNEL_FAILURE: return "WIRE_TEMPORARY_CHANNEL_FAILURE";
	case WIRE_PERMANENT_CHANNEL_FAILURE: return "WIRE_PERMANENT_CHANNEL_FAILURE";
	case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING: return "WIRE_REQUIRED_CHANNEL_FEATURE_MISSING";
	case WIRE_UNKNOWN_NEXT_PEER: return "WIRE_UNKNOWN_NEXT_PEER";
	case WIRE_AMOUNT_BELOW_MINIMUM: return "WIRE_AMOUNT_BELOW_MINIMUM";
	case WIRE_FEE_INSUFFICIENT: return "WIRE_FEE_INSUFFICIENT";
	case WIRE_INCORRECT_CLTV_EXPIRY: return "WIRE_INCORRECT_CLTV_EXPIRY";
	case WIRE_EXPIRY_TOO_SOON: return "WIRE_EXPIRY_TOO_SOON";
	case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: return "WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS";
	case WIRE_FINAL_INCORRECT_CLTV_EXPIRY: return "WIRE_FINAL_INCORRECT_CLTV_EXPIRY";
	case WIRE_FINAL_INCORRECT_HTLC_AMOUNT: return "WIRE_FINAL_INCORRECT_HTLC_AMOUNT";
	case WIRE_CHANNEL_DISABLED: return "WIRE_CHANNEL_DISABLED";
	case WIRE_EXPIRY_TOO_FAR: return "WIRE_EXPIRY_TOO_FAR";
	case WIRE_INVALID_ONION_PAYLOAD: return "WIRE_INVALID_ONION_PAYLOAD";
	case WIRE_MPP_TIMEOUT: return "WIRE_MPP_TIMEOUT";
	}

	snprintf(invalidbuf, sizeof(invalidbuf), "INVALID %i", e);
	return invalidbuf;
}

bool onion_wire_is_defined(u16 type)
{
	switch ((enum onion_wire)type) {
	case WIRE_INVALID_REALM:;
	case WIRE_TEMPORARY_NODE_FAILURE:;
	case WIRE_PERMANENT_NODE_FAILURE:;
	case WIRE_REQUIRED_NODE_FEATURE_MISSING:;
	case WIRE_INVALID_ONION_VERSION:;
	case WIRE_INVALID_ONION_HMAC:;
	case WIRE_INVALID_ONION_KEY:;
	case WIRE_TEMPORARY_CHANNEL_FAILURE:;
	case WIRE_PERMANENT_CHANNEL_FAILURE:;
	case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING:;
	case WIRE_UNKNOWN_NEXT_PEER:;
	case WIRE_AMOUNT_BELOW_MINIMUM:;
	case WIRE_FEE_INSUFFICIENT:;
	case WIRE_INCORRECT_CLTV_EXPIRY:;
	case WIRE_EXPIRY_TOO_SOON:;
	case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS:;
	case WIRE_FINAL_INCORRECT_CLTV_EXPIRY:;
	case WIRE_FINAL_INCORRECT_HTLC_AMOUNT:;
	case WIRE_CHANNEL_DISABLED:;
	case WIRE_EXPIRY_TOO_FAR:;
	case WIRE_INVALID_ONION_PAYLOAD:;
	case WIRE_MPP_TIMEOUT:;
	      return true;
	}
	return false;
}





struct tlv_tlv_payload *tlv_tlv_payload_new(const tal_t *ctx)
{
	/* Initialize everything to NULL. (Quiet, C pedants!) */
	struct tlv_tlv_payload *inst = talz(ctx, struct tlv_tlv_payload);

	/* Initialized the fields to an empty array. */
	inst->fields = tal_arr(inst, struct tlv_field, 0);
	return inst;
}

/* TLV_PAYLOAD MSG: amt_to_forward */
static u8 *towire_tlv_tlv_payload_amt_to_forward(const tal_t *ctx, const void *vrecord)
{
	const struct tlv_tlv_payload *r = vrecord;
	u8 *ptr;

	if (!r->amt_to_forward)
		return NULL;


	ptr = tal_arr(ctx, u8, 0);

	towire_tu64(&ptr, *r->amt_to_forward);
	return ptr;
}
static void fromwire_tlv_tlv_payload_amt_to_forward(const u8 **cursor, size_t *plen, void *vrecord)
{
	struct tlv_tlv_payload *r = vrecord;

	    r->amt_to_forward = tal(r, u64);

*r->amt_to_forward = fromwire_tu64(cursor, plen);
}
/* TLV_PAYLOAD MSG: outgoing_cltv_value */
static u8 *towire_tlv_tlv_payload_outgoing_cltv_value(const tal_t *ctx, const void *vrecord)
{
	const struct tlv_tlv_payload *r = vrecord;
	u8 *ptr;

	if (!r->outgoing_cltv_value)
		return NULL;


	ptr = tal_arr(ctx, u8, 0);

	towire_tu32(&ptr, *r->outgoing_cltv_value);
	return ptr;
}
static void fromwire_tlv_tlv_payload_outgoing_cltv_value(const u8 **cursor, size_t *plen, void *vrecord)
{
	struct tlv_tlv_payload *r = vrecord;

	    r->outgoing_cltv_value = tal(r, u32);

*r->outgoing_cltv_value = fromwire_tu32(cursor, plen);
}
/* TLV_PAYLOAD MSG: short_channel_id */
static u8 *towire_tlv_tlv_payload_short_channel_id(const tal_t *ctx, const void *vrecord)
{
	const struct tlv_tlv_payload *r = vrecord;
	u8 *ptr;

	if (!r->short_channel_id)
		return NULL;


	ptr = tal_arr(ctx, u8, 0);

	towire_short_channel_id(&ptr, r->short_channel_id);
	return ptr;
}
static void fromwire_tlv_tlv_payload_short_channel_id(const u8 **cursor, size_t *plen, void *vrecord)
{
	struct tlv_tlv_payload *r = vrecord;

	    r->short_channel_id = tal(r, struct short_channel_id);

fromwire_short_channel_id(cursor, plen, &*r->short_channel_id);
}
/* TLV_PAYLOAD MSG: payment_data */
static u8 *towire_tlv_tlv_payload_payment_data(const tal_t *ctx, const void *vrecord)
{
	const struct tlv_tlv_payload *r = vrecord;
	u8 *ptr;

	if (!r->payment_data)
		return NULL;


	ptr = tal_arr(ctx, u8, 0);

	towire_secret(&ptr, &r->payment_data->payment_secret);

	towire_tu64(&ptr, r->payment_data->total_msat);
	return ptr;
}
static void fromwire_tlv_tlv_payload_payment_data(const u8 **cursor, size_t *plen, void *vrecord)
{
	struct tlv_tlv_payload *r = vrecord;

	r->payment_data = tal(r, struct tlv_tlv_payload_payment_data);
	fromwire_secret(cursor, plen, &r->payment_data->payment_secret);
	r->payment_data->total_msat = fromwire_tu64(cursor, plen);
}

const struct tlv_record_type tlvs_tlv_payload[] = {
	{ 2, towire_tlv_tlv_payload_amt_to_forward, fromwire_tlv_tlv_payload_amt_to_forward },
	{ 4, towire_tlv_tlv_payload_outgoing_cltv_value, fromwire_tlv_tlv_payload_outgoing_cltv_value },
	{ 6, towire_tlv_tlv_payload_short_channel_id, fromwire_tlv_tlv_payload_short_channel_id },
	{ 8, towire_tlv_tlv_payload_payment_data, fromwire_tlv_tlv_payload_payment_data },
};

void towire_tlv_payload(u8 **pptr,
			const void *record)
{
	size_t num_types = 4;
	const struct tlv_record_type *types = tlvs_tlv_payload;
	if (!record)
		return;

	for (size_t i = 0; i < num_types; i++) {
		u8 *val;
		if (i != 0)
			assert(types[i].type > types[i-1].type);
		val = types[i].towire(NULL, record);
		if (!val)
			continue;

		/* BOLT #1:
		 *
		 * The sending node:
		 ...
		 *  - MUST minimally encode `type` and `length`.
		 */
		towire_bigsize(pptr, types[i].type);
		towire_bigsize(pptr, tal_bytelen(val));
		towire(pptr, val, tal_bytelen(val));
		tal_free(val);
	}
}


bool fromwire_tlv_payload(const u8 **cursor, size_t *max, struct tlv_tlv_payload *record)
{
	size_t num_types = 4;
	const struct tlv_record_type *types = tlvs_tlv_payload;
	while (*max > 0) {
		struct tlv_field field;

		/* BOLT #1:
		 *
		 * The `type` is encoded using the BigSize format.
		 */
		field.numtype = fromwire_bigsize(cursor, max);

		/* BOLT #1:
		 *  - if a `type` or `length` is not minimally encoded:
		 *    - MUST fail to parse the `tlv_stream`.
		 */
		if (!*cursor) {
			SUPERVERBOSE("type");
			goto fail;
		}
		field.length = fromwire_bigsize(cursor, max);

		/* BOLT #1:
		 *  - if a `type` or `length` is not minimally encoded:
		 *    - MUST fail to parse the `tlv_stream`.
		 */
		if (!*cursor) {
			SUPERVERBOSE("length");
			goto fail;
		}

		/* BOLT #1:
		 *  - if `length` exceeds the number of bytes remaining in the
		 *    message:
		 *    - MUST fail to parse the `tlv_stream`.
		 */
		if (field.length > *max) {
			SUPERVERBOSE("value");
			goto fail;
		}
		field.value = tal_dup_arr(record, u8, *cursor, field.length, 0);

		/* BOLT #1:
		 * - if `type` is known:
		 *   - MUST decode the next `length` bytes using the known
		 *     encoding for `type`.
		 */
		field.meta = NULL;
		for (size_t i = 0; i < num_types; i++) {
			if (types[i].type == field.numtype)
				field.meta = &types[i];
		}

		if (field.meta) {
			/* Length of message can't exceed 16 bits anyway. */
			size_t tlvlen = field.length;
			field.meta->fromwire(cursor, &tlvlen, record);

			if (!*cursor)
				goto fail;

			/* BOLT #1:
			 *  - if `length` is not exactly equal to that required
			 *    for the known encoding for `type`:
			 *    - MUST fail to parse the `tlv_stream`.
			 */
			if (tlvlen != 0) {
				SUPERVERBOSE("greater than encoding length");
				goto fail;
			}
		} else {
			/* We didn't read from *cursor through a fromwire, so
			 * update manually. */
			*cursor += field.length;
		}
		/* We've read bytes in ->fromwire, so update max */
		*max -= field.length;
		tal_arr_expand(&record->fields, field);
	}
	return true;
fail:
	fromwire_fail(cursor, max);
	return false;
}

bool tlv_payload_is_valid(const struct tlv_tlv_payload *record, size_t *err_index)
{
	size_t numfields = tal_count(record->fields);
	bool first = true;
	u64 prev_type = 0;
	for (int i=0; i<numfields; i++) {
		struct tlv_field *f = &record->fields[i];
		if (f->numtype % 2 == 0 && f->meta == NULL) {
			/* BOLT #1:
			 * - otherwise, if `type` is unknown:
			 *   - if `type` is even:
			 *     - MUST fail to parse the `tlv_stream`.
			 *   - otherwise, if `type` is odd:
			 *     - MUST discard the next `length` bytes.
			 */
			SUPERVERBOSE("unknown even");
			if (err_index != NULL)
				*err_index = i;
			return false;
		} else if (!first && f->numtype <= prev_type) {
			/* BOLT #1:
			 *  - if decoded `type`s are not strictly-increasing
			 *    (including situations when two or more occurrences
			 *    of the same `type` are met):
			 *    - MUST fail to parse the `tlv_stream`.
			 */
			if (f->numtype == prev_type)
				SUPERVERBOSE("duplicate tlv type");
			else
				SUPERVERBOSE("invalid ordering");
			if (err_index != NULL)
				*err_index = i;
			return false;
		}
		first = false;
		prev_type = f->numtype;
	}
	return true;
}


/* WIRE: INVALID_REALM */
u8 *towire_invalid_realm(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INVALID_REALM);

	return memcheck(p, tal_count(p));
}
bool fromwire_invalid_realm(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INVALID_REALM)
		return false;
	return cursor != NULL;
}

/* WIRE: TEMPORARY_NODE_FAILURE */
u8 *towire_temporary_node_failure(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_TEMPORARY_NODE_FAILURE);

	return memcheck(p, tal_count(p));
}
bool fromwire_temporary_node_failure(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_TEMPORARY_NODE_FAILURE)
		return false;
	return cursor != NULL;
}

/* WIRE: PERMANENT_NODE_FAILURE */
u8 *towire_permanent_node_failure(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_PERMANENT_NODE_FAILURE);

	return memcheck(p, tal_count(p));
}
bool fromwire_permanent_node_failure(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_PERMANENT_NODE_FAILURE)
		return false;
	return cursor != NULL;
}

/* WIRE: REQUIRED_NODE_FEATURE_MISSING */
u8 *towire_required_node_feature_missing(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_REQUIRED_NODE_FEATURE_MISSING);

	return memcheck(p, tal_count(p));
}
bool fromwire_required_node_feature_missing(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_REQUIRED_NODE_FEATURE_MISSING)
		return false;
	return cursor != NULL;
}

/* WIRE: INVALID_ONION_VERSION */
u8 *towire_invalid_onion_version(const tal_t *ctx, const struct sha256 *sha256_of_onion)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INVALID_ONION_VERSION);
	towire_sha256(&p, sha256_of_onion);

	return memcheck(p, tal_count(p));
}
bool fromwire_invalid_onion_version(const void *p, struct sha256 *sha256_of_onion)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INVALID_ONION_VERSION)
		return false;
 	fromwire_sha256(&cursor, &plen, sha256_of_onion);
	return cursor != NULL;
}

/* WIRE: INVALID_ONION_HMAC */
u8 *towire_invalid_onion_hmac(const tal_t *ctx, const struct sha256 *sha256_of_onion)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INVALID_ONION_HMAC);
	towire_sha256(&p, sha256_of_onion);

	return memcheck(p, tal_count(p));
}
bool fromwire_invalid_onion_hmac(const void *p, struct sha256 *sha256_of_onion)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INVALID_ONION_HMAC)
		return false;
 	fromwire_sha256(&cursor, &plen, sha256_of_onion);
	return cursor != NULL;
}

/* WIRE: INVALID_ONION_KEY */
u8 *towire_invalid_onion_key(const tal_t *ctx, const struct sha256 *sha256_of_onion)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INVALID_ONION_KEY);
	towire_sha256(&p, sha256_of_onion);

	return memcheck(p, tal_count(p));
}
bool fromwire_invalid_onion_key(const void *p, struct sha256 *sha256_of_onion)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INVALID_ONION_KEY)
		return false;
 	fromwire_sha256(&cursor, &plen, sha256_of_onion);
	return cursor != NULL;
}

/* WIRE: TEMPORARY_CHANNEL_FAILURE */
u8 *towire_temporary_channel_failure(const tal_t *ctx, const u8 *channel_update)
{
	u16 len = tal_count(channel_update);
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_TEMPORARY_CHANNEL_FAILURE);
	towire_u16(&p, len);
	towire_u8_array(&p, channel_update, len);

	return memcheck(p, tal_count(p));
}
bool fromwire_temporary_channel_failure(const tal_t *ctx, const void *p, u8 **channel_update)
{
	u16 len;

	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_TEMPORARY_CHANNEL_FAILURE)
		return false;
 	len = fromwire_u16(&cursor, &plen);
 	// 2nd case channel_update
	*channel_update = len ? tal_arr(ctx, u8, len) : NULL;
	fromwire_u8_array(&cursor, &plen, *channel_update, len);
	return cursor != NULL;
}

/* WIRE: PERMANENT_CHANNEL_FAILURE */
u8 *towire_permanent_channel_failure(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_PERMANENT_CHANNEL_FAILURE);

	return memcheck(p, tal_count(p));
}
bool fromwire_permanent_channel_failure(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_PERMANENT_CHANNEL_FAILURE)
		return false;
	return cursor != NULL;
}

/* WIRE: REQUIRED_CHANNEL_FEATURE_MISSING */
u8 *towire_required_channel_feature_missing(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_REQUIRED_CHANNEL_FEATURE_MISSING);

	return memcheck(p, tal_count(p));
}
bool fromwire_required_channel_feature_missing(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_REQUIRED_CHANNEL_FEATURE_MISSING)
		return false;
	return cursor != NULL;
}

/* WIRE: UNKNOWN_NEXT_PEER */
u8 *towire_unknown_next_peer(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_UNKNOWN_NEXT_PEER);

	return memcheck(p, tal_count(p));
}
bool fromwire_unknown_next_peer(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_UNKNOWN_NEXT_PEER)
		return false;
	return cursor != NULL;
}

/* WIRE: AMOUNT_BELOW_MINIMUM */
u8 *towire_amount_below_minimum(const tal_t *ctx, struct amount_msat htlc_msat, const u8 *channel_update)
{
	u16 len = tal_count(channel_update);
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_AMOUNT_BELOW_MINIMUM);
	towire_amount_msat(&p, htlc_msat);
	towire_u16(&p, len);
	towire_u8_array(&p, channel_update, len);

	return memcheck(p, tal_count(p));
}
bool fromwire_amount_below_minimum(const tal_t *ctx, const void *p, struct amount_msat *htlc_msat, u8 **channel_update)
{
	u16 len;

	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_AMOUNT_BELOW_MINIMUM)
		return false;
 	*htlc_msat = fromwire_amount_msat(&cursor, &plen);
 	len = fromwire_u16(&cursor, &plen);
 	// 2nd case channel_update
	*channel_update = len ? tal_arr(ctx, u8, len) : NULL;
	fromwire_u8_array(&cursor, &plen, *channel_update, len);
	return cursor != NULL;
}

/* WIRE: FEE_INSUFFICIENT */
u8 *towire_fee_insufficient(const tal_t *ctx, struct amount_msat htlc_msat, const u8 *channel_update)
{
	u16 len = tal_count(channel_update);
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_FEE_INSUFFICIENT);
	towire_amount_msat(&p, htlc_msat);
	towire_u16(&p, len);
	towire_u8_array(&p, channel_update, len);

	return memcheck(p, tal_count(p));
}
bool fromwire_fee_insufficient(const tal_t *ctx, const void *p, struct amount_msat *htlc_msat, u8 **channel_update)
{
	u16 len;

	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_FEE_INSUFFICIENT)
		return false;
 	*htlc_msat = fromwire_amount_msat(&cursor, &plen);
 	len = fromwire_u16(&cursor, &plen);
 	// 2nd case channel_update
	*channel_update = len ? tal_arr(ctx, u8, len) : NULL;
	fromwire_u8_array(&cursor, &plen, *channel_update, len);
	return cursor != NULL;
}

/* WIRE: INCORRECT_CLTV_EXPIRY */
u8 *towire_incorrect_cltv_expiry(const tal_t *ctx, u32 cltv_expiry, const u8 *channel_update)
{
	u16 len = tal_count(channel_update);
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INCORRECT_CLTV_EXPIRY);
	towire_u32(&p, cltv_expiry);
	towire_u16(&p, len);
	towire_u8_array(&p, channel_update, len);

	return memcheck(p, tal_count(p));
}
bool fromwire_incorrect_cltv_expiry(const tal_t *ctx, const void *p, u32 *cltv_expiry, u8 **channel_update)
{
	u16 len;

	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INCORRECT_CLTV_EXPIRY)
		return false;
 	*cltv_expiry = fromwire_u32(&cursor, &plen);
 	len = fromwire_u16(&cursor, &plen);
 	// 2nd case channel_update
	*channel_update = len ? tal_arr(ctx, u8, len) : NULL;
	fromwire_u8_array(&cursor, &plen, *channel_update, len);
	return cursor != NULL;
}

/* WIRE: EXPIRY_TOO_SOON */
u8 *towire_expiry_too_soon(const tal_t *ctx, const u8 *channel_update)
{
	u16 len = tal_count(channel_update);
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_EXPIRY_TOO_SOON);
	towire_u16(&p, len);
	towire_u8_array(&p, channel_update, len);

	return memcheck(p, tal_count(p));
}
bool fromwire_expiry_too_soon(const tal_t *ctx, const void *p, u8 **channel_update)
{
	u16 len;

	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_EXPIRY_TOO_SOON)
		return false;
 	len = fromwire_u16(&cursor, &plen);
 	// 2nd case channel_update
	*channel_update = len ? tal_arr(ctx, u8, len) : NULL;
	fromwire_u8_array(&cursor, &plen, *channel_update, len);
	return cursor != NULL;
}

/* WIRE: INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
u8 *towire_incorrect_or_unknown_payment_details(const tal_t *ctx, struct amount_msat htlc_msat, u32 height)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS);
	towire_amount_msat(&p, htlc_msat);
	towire_u32(&p, height);

	return memcheck(p, tal_count(p));
}
bool fromwire_incorrect_or_unknown_payment_details(const void *p, struct amount_msat *htlc_msat, u32 *height)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS)
		return false;
 	*htlc_msat = fromwire_amount_msat(&cursor, &plen);
 	*height = fromwire_u32(&cursor, &plen);
	return cursor != NULL;
}

/* WIRE: FINAL_INCORRECT_CLTV_EXPIRY */
u8 *towire_final_incorrect_cltv_expiry(const tal_t *ctx, u32 cltv_expiry)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_FINAL_INCORRECT_CLTV_EXPIRY);
	towire_u32(&p, cltv_expiry);

	return memcheck(p, tal_count(p));
}
bool fromwire_final_incorrect_cltv_expiry(const void *p, u32 *cltv_expiry)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_FINAL_INCORRECT_CLTV_EXPIRY)
		return false;
 	*cltv_expiry = fromwire_u32(&cursor, &plen);
	return cursor != NULL;
}

/* WIRE: FINAL_INCORRECT_HTLC_AMOUNT */
u8 *towire_final_incorrect_htlc_amount(const tal_t *ctx, struct amount_msat incoming_htlc_amt)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_FINAL_INCORRECT_HTLC_AMOUNT);
	towire_amount_msat(&p, incoming_htlc_amt);

	return memcheck(p, tal_count(p));
}
bool fromwire_final_incorrect_htlc_amount(const void *p, struct amount_msat *incoming_htlc_amt)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_FINAL_INCORRECT_HTLC_AMOUNT)
		return false;
 	*incoming_htlc_amt = fromwire_amount_msat(&cursor, &plen);
	return cursor != NULL;
}

/* WIRE: CHANNEL_DISABLED */
u8 *towire_channel_disabled(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_CHANNEL_DISABLED);

	return memcheck(p, tal_count(p));
}
bool fromwire_channel_disabled(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_CHANNEL_DISABLED)
		return false;
	return cursor != NULL;
}

/* WIRE: EXPIRY_TOO_FAR */
u8 *towire_expiry_too_far(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_EXPIRY_TOO_FAR);

	return memcheck(p, tal_count(p));
}
bool fromwire_expiry_too_far(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_EXPIRY_TOO_FAR)
		return false;
	return cursor != NULL;
}

/* WIRE: INVALID_ONION_PAYLOAD */
u8 *towire_invalid_onion_payload(const tal_t *ctx, bigsize type, u16 offset)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_INVALID_ONION_PAYLOAD);
	towire_bigsize(&p, type);
	towire_u16(&p, offset);

	return memcheck(p, tal_count(p));
}
bool fromwire_invalid_onion_payload(const void *p, bigsize *type, u16 *offset)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_INVALID_ONION_PAYLOAD)
		return false;
 	*type = fromwire_bigsize(&cursor, &plen);
 	*offset = fromwire_u16(&cursor, &plen);
	return cursor != NULL;
}

/* WIRE: MPP_TIMEOUT */
u8 *towire_mpp_timeout(const tal_t *ctx)
{
	u8 *p = tal_arr(ctx, u8, 0);

	towire_u16(&p, WIRE_MPP_TIMEOUT);

	return memcheck(p, tal_count(p));
}
bool fromwire_mpp_timeout(const void *p)
{
	const u8 *cursor = p;
	size_t plen = tal_count(p);

	if (fromwire_u16(&cursor, &plen) != WIRE_MPP_TIMEOUT)
		return false;
	return cursor != NULL;
}
// SHA256STAMP:43b0761145cf51e4de37f46c966c199ba305d02ca43e03350151e8435b9b1153
