diff --git a/tools/generate-wire.py b/tools/generate-wire.py index 4e2ddbe1a..040b22082 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -28,7 +28,8 @@ type2size = { 'u32': 4, 'u16': 2, 'u8': 1, - 'bool': 1 + 'bool': 1, + 'var_int': 8, } # These struct array helpers require a context to allocate from. @@ -46,8 +47,11 @@ class FieldType(object): def __init__(self, name): self.name = name + def is_var_int(self): + return self.name == 'var_int' + def is_assignable(self): - return self.name in ['u8', 'u16', 'u32', 'u64', 'bool', 'struct amount_msat', 'struct amount_sat'] or self.name.startswith('enum ') + return self.name in ['u8', 'u16', 'u32', 'u64', 'bool', 'struct amount_msat', 'struct amount_sat', 'var_int'] or self.name.startswith('enum ') # We only accelerate the u8 case: it's common and trivial. def has_array_helper(self): @@ -59,6 +63,8 @@ class FieldType(object): basetype = basetype[7:] elif basetype.startswith('enum '): basetype = basetype[5:] + elif self.name == 'var_int': + return 'u64' return basetype # Returns base size @@ -160,8 +166,12 @@ class Field(object): # Bolts use just a number: Guess type based on size. if options.bolt: - base_size = int(size) - self.fieldtype = Field._guess_type(message, self.name, base_size) + if size == 'var_int': + base_size = 8 + self.fieldtype = FieldType(size) + else: + base_size = int(size) + self.fieldtype = Field._guess_type(message, self.name, base_size) # There are some arrays which we have to guess, based on sizes. tsize = FieldType._typesize(self.fieldtype.name) if base_size % tsize != 0: @@ -352,8 +362,8 @@ class Message(object): return for f in self.fields: if f.name == field.lenvar: - if f.fieldtype.name != 'u16' and options.bolt: - raise ValueError('Field {} has non-u16 length variable {} (type {})' + if not (f.fieldtype.name == 'u16' or f.fieldtype.name == 'var_int') and options.bolt: + raise ValueError('Field {} has non-u16 and non-var_int length variable {} (type {})' .format(field.name, field.lenvar, f.fieldtype.name)) if f.is_array() or f.needs_ptr_to_ptr(): @@ -399,7 +409,7 @@ class Message(object): to populate, instead of fields, as well as a length to read in """ ctx_arg = 'const tal_t *ctx, ' if self.has_variable_fields else '' - args = 'const u8 **cursor, size_t *plen, const u16 len, struct tlv_msg_{name} *{name}'.format(name=self.name) + args = 'const u8 **cursor, size_t *plen, const u64 len, struct tlv_msg_{name} *{name}'.format(name=self.name) fields = ['\t{} {};\n'.format(f.fieldtype.name, f.name) for f in self.fields if f.is_len_var] subcalls = CCode() for f in self.fields: @@ -482,11 +492,13 @@ class Message(object): args.append(', {} {}{}'.format(f.fieldtype.name, ptrs, f.name)) template = fromwire_header_templ if is_header else fromwire_impl_templ - fields = ['\t{} {};\n'.format(f.fieldtype.name, f.name) for f in self.fields if f.is_len_var] + fields = ['\t{} {};\n'.format(f.fieldtype.base(), f.name) for f in self.fields if f.is_len_var] subcalls = CCode() for f in self.fields: basetype = f.fieldtype.base() + if f.fieldtype.is_var_int(): + basetype = 'var_int' for c in f.comments: subcalls.append('/*{} */'.format(c)) @@ -636,7 +648,7 @@ class Message(object): if f.is_len_var: if f.lenvar_for.is_tlv: # used below... - field_decls.append('\t{0} {1};'.format(f.fieldtype.name, f.name)) + field_decls.append('\t{0} {1};'.format(f.fieldtype.base(), f.name)) else: field_decls.append('\t{0} {1} = tal_count({2});'.format( f.fieldtype.name, f.name, f.lenvar_for.name @@ -833,20 +845,21 @@ tlv__type_impl_towire_fields = """\tif ({tlv_name}->{name}) {{ \t\ttowire_u8(p, {enum}); \t\ttowire_{tlv_name}_{name}(&tlv_msg, {tlv_name}->{name}); \t\tmsg_len = tal_count(tlv_msg); -\t\ttowire_u8(p, msg_len); +\t\ttowire_var_int(p, msg_len); \t\ttowire_u8_array(p, tlv_msg, msg_len); \t\ttal_free(tlv_msg); \t}} """ tlv__type_impl_towire_template = """static void towire__{tlv_name}(const tal_t *ctx, u8 **p, const struct {tlv_name} *{tlv_name}) {{ -\tu8 msg_len; +\tu64 msg_len; \tu8 *tlv_msg; {fields}}} """ -tlv__type_impl_fromwire_template = """static struct {tlv_name} *fromwire__{tlv_name}(const tal_t *ctx, const u8 **p, size_t *plen, const u16 *len) {{ -\tu8 msg_type, msg_len; +tlv__type_impl_fromwire_template = """static struct {tlv_name} *fromwire__{tlv_name}(const tal_t *ctx, const u8 **p, size_t *plen, const u64 *len) {{ +\tu8 msg_type; +\tu64 msg_len; \tsize_t start_len = *plen; \tif (*plen < *len) \t\treturn NULL; @@ -855,7 +868,7 @@ tlv__type_impl_fromwire_template = """static struct {tlv_name} *fromwire__{tlv_n \twhile (*plen) {{ \t\tmsg_type = fromwire_u8(p, plen); -\t\tmsg_len = fromwire_u8(p, plen); +\t\tmsg_len = fromwire_var_int(p, plen); \t\tif (*plen < msg_len) {{ \t\t\tfromwire_fail(p, plen); \t\t\tbreak;