You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
4.7 KiB

  1. # Wire Protocol
  2. The [Tendermint wire protocol](https://github.com/tendermint/go-wire) encodes data in [c-style binary](#binary) and [JSON](#json) form.
  3. ## Supported types
  4. - Primitive types
  5. - `uint8` (aka `byte`), `uint16`, `uint32`, `uint64`
  6. - `int8`, `int16`, `int32`, `int64`
  7. - `uint`, `int`: variable length (un)signed integers
  8. - `string`, `[]byte`
  9. - `time`
  10. - Derived types
  11. - structs
  12. - var-length arrays of a particular type
  13. - fixed-length arrays of a particular type
  14. - interfaces: registered union types preceded by a `type byte`
  15. - pointers
  16. ## Binary
  17. **Fixed-length primitive types** are encoded with 1,2,3, or 4 big-endian bytes.
  18. - `uint8` (aka `byte`), `uint16`, `uint32`, `uint64`: takes 1,2,3, and 4 bytes respectively
  19. - `int8`, `int16`, `int32`, `int64`: takes 1,2,3, and 4 bytes respectively
  20. - `time`: `int64` representation of nanoseconds since epoch
  21. **Variable-length integers** are encoded with a single leading byte representing the length of the following big-endian bytes. For signed negative integers, the most significant bit of the leading byte is a 1.
  22. - `uint`: 1-byte length prefixed variable-size (0 ~ 255 bytes) unsigned integers
  23. - `int`: 1-byte length prefixed variable-size (0 ~ 127 bytes) signed integers
  24. NOTE: While the number 0 (zero) is encoded with a single byte `x00`, the number 1 (one) takes two bytes to represent: `x0101`. This isn't the most efficient representation, but the rules are easier to remember.
  25. | number | binary `uint` | binary `int` |
  26. | ------------ | ------------- | ------------- |
  27. | 0 | `x00` | `x00` |
  28. | 1 | `x0101` | `x0101` |
  29. | 2 | `x0102` | `x0102` |
  30. | 256 | `x020100` | `x020100` |
  31. | 2^(127*8)-1 | `x7FFFFF...` | `x7FFFFF...` |
  32. | 2^(127*8) | `x800100...` | overflow |
  33. | 2^(255*8)-1 | `xFFFFFF...` | overflow |
  34. | -1 | n/a | `x8101` |
  35. | -2 | n/a | `x8102` |
  36. | -256 | n/a | `x820100` |
  37. **Structures** are encoded by encoding the field values in order of declaration.
  38. ```go
  39. type Foo struct {
  40. MyString string
  41. MyUint32 uint32
  42. }
  43. var foo = Foo{"626172", math.MaxUint32}
  44. /* The binary representation of foo:
  45. 0103626172FFFFFFFF
  46. 0103: `int` encoded length of string, here 3
  47. 626172: 3 bytes of string "bar"
  48. FFFFFFFF: 4 bytes of uint32 MaxUint32
  49. */
  50. ```
  51. **Variable-length arrays** are encoded with a leading `int` denoting the length of the array followed by the binary representation of the items. **Fixed-length arrays** are similar but aren't preceded by the leading `int`.
  52. ```go
  53. foos := []Foo{foo, foo}
  54. /* The binary representation of foos:
  55. 01020103626172FFFFFFFF0103626172FFFFFFFF
  56. 0102: `int` encoded length of array, here 2
  57. 0103626172FFFFFFFF: the first `foo`
  58. 0103626172FFFFFFFF: the second `foo`
  59. */
  60. foos := [2]Foo{foo, foo} // fixed-length array
  61. /* The binary representation of foos:
  62. 0103626172FFFFFFFF0103626172FFFFFFFF
  63. 0103626172FFFFFFFF: the first `foo`
  64. 0103626172FFFFFFFF: the second `foo`
  65. */
  66. ```
  67. **Interfaces** can represent one of any number of concrete types. The concrete types of an interface must first be declared with their corresponding `type byte`. An interface is then encoded with the leading `type byte`, then the binary encoding of the underlying concrete type.
  68. NOTE: The byte `x00` is reserved for the `nil` interface value and `nil` pointer values.
  69. ```go
  70. type Animal interface{}
  71. type Dog uint32
  72. type Cat string
  73. RegisterInterface(
  74. struct{ Animal }{}, // Convenience for referencing the 'Animal' interface
  75. ConcreteType{Dog(0), 0x01}, // Register the byte 0x01 to denote a Dog
  76. ConcreteType{Cat(""), 0x02}, // Register the byte 0x02 to denote a Cat
  77. )
  78. var animal Animal = Dog(02)
  79. /* The binary representation of animal:
  80. 010102
  81. 01: the type byte for a `Dog`
  82. 0102: the bytes of Dog(02)
  83. */
  84. ```
  85. **Pointers** are encoded with a single leading byte `x00` for `nil` pointers, otherwise encoded with a leading byte `x01` followed by the binary encoding of the value pointed to.
  86. NOTE: It's easy to convert pointer types into interface types, since the `type byte` `x00` is always `nil`.
  87. ## JSON
  88. The JSON codec is compatible with the [`binary`](#binary) codec, and is fairly intuitive if you're already familiar with golang's JSON encoding. Some quirks are noted below:
  89. - variable-length and fixed-length bytes are encoded as uppercase hexadecimal strings
  90. - interface values are encoded as an array of two items: `[type_byte, concrete_value]`
  91. - times are encoded as rfc2822 strings