From 4c429309402b920e4411632c0146375690022787 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 22 Jan 2016 06:38:08 +1030 Subject: [PATCH] bitcoin/tx, protobuf_convert: support BIP68 as implemented. The format for both the nSequence field and the stack arg for OP_CHECKSEQUENCEVERIFY is either: Time-relative: [Bit 22 = 1] 00000 Block-relative: [Bit 22 = 0] 00000 Signed-off-by: Rusty Russell --- bitcoin/tx.c | 11 ++++------- protobuf_convert.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 00799525a..fb3546970 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -550,13 +550,10 @@ bool bitcoin_tx_write(int fd, const struct bitcoin_tx *tx) u32 bitcoin_nsequence(u32 locktime) { #ifdef HAS_BIP68 - /* BIP66 style sequence numbers */ - if (locktime >= 500000000) - /* A relative time. Set bit 30, shift by 5. */ - return 0x40000000 | ((locktime - 500000000) << 5); - else - /* A block height. Shift by 14. */ - return locktime << 14; + /* FIXME: return fail to caller. */ + /* Can't set disable bit, or other bits except low 16 and bit 22 */ + assert(!(locktime & ~((1 << 22) | 0xFFFF))); + return locktime; #else /* Alpha uses the original proposal: simply invert the bits. */ return ~locktime; diff --git a/protobuf_convert.c b/protobuf_convert.c index e83788e2d..99577fe72 100644 --- a/protobuf_convert.c +++ b/protobuf_convert.c @@ -128,7 +128,28 @@ static bool proto_to_locktime(const Locktime *l, uint32_t off, bool proto_to_rel_locktime(const Locktime *l, uint32_t *locktime) { + /* Original proposal from Elements Alpha was simply locktime. */ +#ifdef HAS_BIP68 + switch (l->locktime_case) { + case LOCKTIME__LOCKTIME_SECONDS: + *locktime = (1 << 22) | (l->seconds / 512); + if (l->seconds / 512 > 0xFFFF) + return false; + break; + case LOCKTIME__LOCKTIME_BLOCKS: + *locktime = l->blocks; + if (l->blocks > 0xFFFF) + return false; + break; + default: + return false; + } + /* No other bits should be set. */ + assert((*locktime & ~((1 << 22) | 0xFFFF)) == 0); + return true; +#else return proto_to_locktime(l, 500000000, locktime); +#endif } bool proto_to_abs_locktime(const Locktime *l, uint32_t *locktime)