Skip to content

Commit

Permalink
varint: new file.
Browse files Browse the repository at this point in the history
Move varint handling from tx.c and generalize it.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Apr 12, 2016
1 parent af080d5 commit 6b956ea
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 56 deletions.
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ BITCOIN_SRC := \
bitcoin/script.c \
bitcoin/shadouble.c \
bitcoin/signature.c \
bitcoin/tx.c
bitcoin/tx.c \
bitcoin/varint.c
BITCOIN_OBJS := $(BITCOIN_SRC:.c=.o)

CORE_SRC := \
Expand Down Expand Up @@ -135,7 +136,8 @@ BITCOIN_HEADERS := bitcoin/address.h \
bitcoin/script.h \
bitcoin/shadouble.h \
bitcoin/signature.h \
bitcoin/tx.h
bitcoin/tx.h \
bitcoin/varint.h

CORE_HEADERS := close_tx.h \
commit_tx.h \
Expand Down
1 change: 1 addition & 0 deletions bitcoin/test/run-tx-encode.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "bitcoin/tx.c"
#include "bitcoin/shadouble.c"
#include "bitcoin/varint.c"
#include <assert.h>
#include <ccan/str/hex/hex.h>

Expand Down
60 changes: 9 additions & 51 deletions bitcoin/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,9 @@
static void add_varint(varint_t v,
void (*add)(const void *, size_t, void *), void *addp)
{
u8 buf[9], *p = buf;

if (v < 0xfd) {
*(p++) = v;
} else if (v <= 0xffff) {
(*p++) = 0xfd;
(*p++) = v;
(*p++) = v >> 8;
} else if (v <= 0xffffffff) {
(*p++) = 0xfe;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
} else {
(*p++) = 0xff;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
(*p++) = v >> 32;
(*p++) = v >> 40;
(*p++) = v >> 48;
(*p++) = v >> 56;
}
add(buf, p - buf, addp);
u8 buf[VARINT_MAX_LEN];

add(buf, varint_put(buf, v), addp);
}

static void add_le32(u32 v,
Expand Down Expand Up @@ -376,34 +353,15 @@ static const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
static u64 pull_varint(const u8 **cursor, size_t *max)
{
u64 ret;
const u8 *p;
size_t len;

p = pull(cursor, max, NULL, 1);
if (!p)
len = varint_get(*cursor, *max, &ret);
if (len == 0) {
*cursor = NULL;
*max = 0;
return 0;

if (*p < 0xfd) {
ret = *p;
} else if (*p == 0xfd) {
p = pull(cursor, max, NULL, 2);
if (!p)
return 0;
ret = ((u64)p[1] << 8) + p[0];
} else if (*p == 0xfe) {
p = pull(cursor, max, NULL, 4);
if (!p)
return 0;
ret = ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
} else {
p = pull(cursor, max, NULL, 8);
if (!p)
return 0;
ret = ((u64)p[7] << 56) + ((u64)p[6] << 48)
+ ((u64)p[5] << 40) + ((u64)p[4] << 32)
+ ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
}
pull(cursor, max, NULL, len);
return ret;
}

Expand Down
4 changes: 1 addition & 3 deletions bitcoin/tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
#include "config.h"
#include "shadouble.h"
#include "signature.h"
#include "varint.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>

/* We unpack varints for our in-memory representation */
#define varint_t u64

struct bitcoin_tx {
u32 version;
varint_t input_count;
Expand Down
62 changes: 62 additions & 0 deletions bitcoin/varint.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "varint.h"

size_t varint_put(u8 buf[VARINT_MAX_LEN], varint_t v)
{
u8 *p = buf;

if (v < 0xfd) {
*(p++) = v;
} else if (v <= 0xffff) {
(*p++) = 0xfd;
(*p++) = v;
(*p++) = v >> 8;
} else if (v <= 0xffffffff) {
(*p++) = 0xfe;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
} else {
(*p++) = 0xff;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
(*p++) = v >> 32;
(*p++) = v >> 40;
(*p++) = v >> 48;
(*p++) = v >> 56;
}
return p - buf;
}

size_t varint_get(const u8 *p, size_t max, varint_t *val)
{
if (max < 1)
return 0;

switch (*p) {
case 0xfd:
if (max < 3)
return 0;
*val = ((u64)p[1] << 8) + p[0];
return 3;
case 0xfe:
if (max < 5)
return 0;
*val = ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
return 5;
case 0xff:
if (max < 9)
return 0;
*val = ((u64)p[7] << 56) + ((u64)p[6] << 48)
+ ((u64)p[5] << 40) + ((u64)p[4] << 32)
+ ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
return 9;
default:
*val = *p;
return 1;
}
}
17 changes: 17 additions & 0 deletions bitcoin/varint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef LIGHTNING_BITCOIN_VARINT_H
#define LIGHTNING_BITCOIN_VARINT_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <stdlib.h>

/* We unpack varints for our in-memory representation */
#define varint_t u64

#define VARINT_MAX_LEN 9

/* Returns bytes used (up to 9) */
size_t varint_put(u8 buf[VARINT_MAX_LEN], varint_t v);

/* Returns bytes used: 0 if max_len too small. */
size_t varint_get(const u8 *p, size_t max_len, varint_t *val);
#endif /* LIGHTNING_BITCOIN_VARINT_H */

0 comments on commit 6b956ea

Please sign in to comment.