206 lines
4.4 KiB
Go
206 lines
4.4 KiB
Go
|
|
// Copyright (c) 2017-2026 Lethean (https://lt.hn)
|
||
|
|
//
|
||
|
|
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||
|
|
// SPDX-License-Identifier: EUPL-1.2
|
||
|
|
|
||
|
|
package wire
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"encoding/hex"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestDecoderUint8_Good(t *testing.T) {
|
||
|
|
dec := NewDecoder(bytes.NewReader([]byte{0x42}))
|
||
|
|
got := dec.ReadUint8()
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != 0x42 {
|
||
|
|
t.Errorf("got 0x%02x, want 0x42", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderUint64LE_Good(t *testing.T) {
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
hex string
|
||
|
|
want uint64
|
||
|
|
}{
|
||
|
|
{"zero", "0000000000000000", 0},
|
||
|
|
{"one", "0100000000000000", 1},
|
||
|
|
{"genesis_nonce", "adb2b98417000000", 101011010221},
|
||
|
|
}
|
||
|
|
for _, tc := range tests {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
b, _ := hex.DecodeString(tc.hex)
|
||
|
|
dec := NewDecoder(bytes.NewReader(b))
|
||
|
|
got := dec.ReadUint64LE()
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != tc.want {
|
||
|
|
t.Errorf("got %d, want %d", got, tc.want)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderVarint_Good(t *testing.T) {
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
hex string
|
||
|
|
want uint64
|
||
|
|
}{
|
||
|
|
{"zero", "00", 0},
|
||
|
|
{"one", "01", 1},
|
||
|
|
{"127", "7f", 127},
|
||
|
|
{"128", "8001", 128},
|
||
|
|
{"300", "ac02", 300},
|
||
|
|
}
|
||
|
|
for _, tc := range tests {
|
||
|
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
|
b, _ := hex.DecodeString(tc.hex)
|
||
|
|
dec := NewDecoder(bytes.NewReader(b))
|
||
|
|
got := dec.ReadVarint()
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != tc.want {
|
||
|
|
t.Errorf("got %d, want %d", got, tc.want)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderBlob32_Good(t *testing.T) {
|
||
|
|
var want [32]byte
|
||
|
|
want[0] = 0xAB
|
||
|
|
want[31] = 0xCD
|
||
|
|
|
||
|
|
dec := NewDecoder(bytes.NewReader(want[:]))
|
||
|
|
var got [32]byte
|
||
|
|
dec.ReadBlob32(&got)
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != want {
|
||
|
|
t.Error("blob32 mismatch")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderBlob64_Good(t *testing.T) {
|
||
|
|
var want [64]byte
|
||
|
|
want[0] = 0x11
|
||
|
|
want[63] = 0x99
|
||
|
|
|
||
|
|
dec := NewDecoder(bytes.NewReader(want[:]))
|
||
|
|
var got [64]byte
|
||
|
|
dec.ReadBlob64(&got)
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != want {
|
||
|
|
t.Error("blob64 mismatch")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderStickyError_Bad(t *testing.T) {
|
||
|
|
dec := NewDecoder(bytes.NewReader(nil))
|
||
|
|
|
||
|
|
got := dec.ReadUint8()
|
||
|
|
if dec.Err() == nil {
|
||
|
|
t.Fatal("expected error from empty reader")
|
||
|
|
}
|
||
|
|
if got != 0 {
|
||
|
|
t.Errorf("got %d, want 0 on error", got)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Subsequent reads should be no-ops.
|
||
|
|
_ = dec.ReadUint64LE()
|
||
|
|
_ = dec.ReadVarint()
|
||
|
|
var h [32]byte
|
||
|
|
dec.ReadBlob32(&h)
|
||
|
|
if h != ([32]byte{}) {
|
||
|
|
t.Error("expected zero blob on sticky error")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderReadBytes_Good(t *testing.T) {
|
||
|
|
data := []byte{0x01, 0x02, 0x03, 0x04}
|
||
|
|
dec := NewDecoder(bytes.NewReader(data))
|
||
|
|
got := dec.ReadBytes(4)
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if !bytes.Equal(got, data) {
|
||
|
|
t.Error("bytes mismatch")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderReadBytesZero_Good(t *testing.T) {
|
||
|
|
dec := NewDecoder(bytes.NewReader(nil))
|
||
|
|
got := dec.ReadBytes(0)
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("unexpected error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
if got != nil {
|
||
|
|
t.Errorf("expected nil, got %v", got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderReadBytesOversize_Bad(t *testing.T) {
|
||
|
|
dec := NewDecoder(bytes.NewReader(nil))
|
||
|
|
_ = dec.ReadBytes(MaxBlobSize + 1)
|
||
|
|
if dec.Err() == nil {
|
||
|
|
t.Fatal("expected error for oversize blob")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestDecoderVarintOverflow_Ugly(t *testing.T) {
|
||
|
|
data := make([]byte, 11)
|
||
|
|
for i := range data {
|
||
|
|
data[i] = 0x80
|
||
|
|
}
|
||
|
|
dec := NewDecoder(bytes.NewReader(data))
|
||
|
|
_ = dec.ReadVarint()
|
||
|
|
if dec.Err() == nil {
|
||
|
|
t.Fatal("expected overflow error")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEncoderDecoderRoundTrip_Good(t *testing.T) {
|
||
|
|
var buf bytes.Buffer
|
||
|
|
enc := NewEncoder(&buf)
|
||
|
|
enc.WriteUint8(0x01)
|
||
|
|
enc.WriteUint64LE(101011010221)
|
||
|
|
enc.WriteVarint(1770897600)
|
||
|
|
var h [32]byte
|
||
|
|
h[0] = 0xDE
|
||
|
|
h[31] = 0xAD
|
||
|
|
enc.WriteBlob32(&h)
|
||
|
|
if enc.Err() != nil {
|
||
|
|
t.Fatalf("encode error: %v", enc.Err())
|
||
|
|
}
|
||
|
|
|
||
|
|
dec := NewDecoder(bytes.NewReader(buf.Bytes()))
|
||
|
|
if v := dec.ReadUint8(); v != 0x01 {
|
||
|
|
t.Errorf("uint8: got 0x%02x, want 0x01", v)
|
||
|
|
}
|
||
|
|
if v := dec.ReadUint64LE(); v != 101011010221 {
|
||
|
|
t.Errorf("uint64: got %d, want 101011010221", v)
|
||
|
|
}
|
||
|
|
if v := dec.ReadVarint(); v != 1770897600 {
|
||
|
|
t.Errorf("varint: got %d, want 1770897600", v)
|
||
|
|
}
|
||
|
|
var gotH [32]byte
|
||
|
|
dec.ReadBlob32(&gotH)
|
||
|
|
if gotH != h {
|
||
|
|
t.Error("blob32 mismatch")
|
||
|
|
}
|
||
|
|
if dec.Err() != nil {
|
||
|
|
t.Fatalf("decode error: %v", dec.Err())
|
||
|
|
}
|
||
|
|
}
|