Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove Amino #265

Merged
merged 7 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions docs/node/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,43 @@ Every node is persisted by encoding the key, version, height, size and hash. If
```golang
// Writes the node as a serialized byte slice to the supplied io.Writer.
func (node *Node) writeBytes(w io.Writer) error {
cause := amino.EncodeInt8(w, node.height)
cause := encodeVarint(w, node.height)
if cause != nil {
return errors.Wrap(cause, "writing height")
}
cause = amino.EncodeVarint(w, node.size)
cause = encodeVarint(w, node.size)
if cause != nil {
return errors.Wrap(cause, "writing size")
}
cause = amino.EncodeVarint(w, node.version)
cause = encodeVarint(w, node.version)
if cause != nil {
return errors.Wrap(cause, "writing version")
}

// Unlike writeHashBytes, key is written for inner nodes.
cause = amino.EncodeByteSlice(w, node.key)
cause = encodeBytes(w, node.key)
if cause != nil {
return errors.Wrap(cause, "writing key")
}

if node.isLeaf() {
cause = amino.EncodeByteSlice(w, node.value)
cause = encodeBytes(w, node.value)
if cause != nil {
return errors.Wrap(cause, "writing value")
}
} else {
if node.leftHash == nil {
panic("node.leftHash was nil in writeBytes")
}
cause = amino.EncodeByteSlice(w, node.leftHash)
cause = encodeBytes(w, node.leftHash)
if cause != nil {
return errors.Wrap(cause, "writing left hash")
}

if node.rightHash == nil {
panic("node.rightHash was nil in writeBytes")
}
cause = amino.EncodeByteSlice(w, node.rightHash)
cause = encodeBytes(w, node.rightHash)
if cause != nil {
return errors.Wrap(cause, "writing right hash")
}
Expand All @@ -87,42 +87,42 @@ A node's hash is calculated by hashing the height, size, and version of the node
// Writes the node's hash to the given io.Writer. This function expects
// child hashes to be already set.
func (node *Node) writeHashBytes(w io.Writer) error {
err := amino.EncodeInt8(w, node.height)
err := encodeVarint(w, node.height)
if err != nil {
return errors.Wrap(err, "writing height")
}
err = amino.EncodeVarint(w, node.size)
err = encodeVarint(w, node.size)
if err != nil {
return errors.Wrap(err, "writing size")
}
err = amino.EncodeVarint(w, node.version)
err = encodeVarint(w, node.version)
if err != nil {
return errors.Wrap(err, "writing version")
}

// Key is not written for inner nodes, unlike writeBytes.

if node.isLeaf() {
err = amino.EncodeByteSlice(w, node.key)
err = encodeBytes(w, node.key)
if err != nil {
return errors.Wrap(err, "writing key")
}
// Indirection needed to provide proofs without values.
// (e.g. proofLeafNode.ValueHash)
valueHash := tmhash.Sum(node.value)
err = amino.EncodeByteSlice(w, valueHash)
err = encodeBytes(w, valueHash)
if err != nil {
return errors.Wrap(err, "writing value")
}
} else {
if node.leftHash == nil || node.rightHash == nil {
panic("Found an empty child hash")
}
err = amino.EncodeByteSlice(w, node.leftHash)
err = encodeBytes(w, node.leftHash)
if err != nil {
return errors.Wrap(err, "writing left hash")
}
err = amino.EncodeByteSlice(w, node.rightHash)
err = encodeBytes(w, node.rightHash)
if err != nil {
return errors.Wrap(err, "writing right hash")
}
Expand Down
104 changes: 104 additions & 0 deletions encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package iavl

import (
"encoding/binary"
"errors"
"fmt"
"io"
"math/bits"
)

// decodeBytes decodes a varint length-prefixed byte slice, returning it along with the number
// of input bytes read.
func decodeBytes(bz []byte) ([]byte, int, error) {
size, n, err := decodeUvarint(bz)
if err != nil {
return nil, n, err
}
if int(size) < 0 {
return nil, n, fmt.Errorf("invalid negative length %v decoding []byte", size)
}
if len(bz) < n+int(size) {
return nil, n, fmt.Errorf("insufficient bytes decoding []byte of length %v", size)
}
bz2 := make([]byte, size)
copy(bz2, bz[n:n+int(size)])
n += int(size)
return bz2, n, nil
}

// decodeUvarint decodes a varint-encoded unsigned integer from a byte slice, returning it and the
// number of bytes decoded.
func decodeUvarint(bz []byte) (uint64, int, error) {
u, n := binary.Uvarint(bz)
if n == 0 {
// buf too small
return u, n, errors.New("buffer too small")
} else if n < 0 {
// value larger than 64 bits (overflow)
// and -n is the number of bytes read
n = -n
return u, n, errors.New("EOF decoding uvarint")
}
return u, n, nil
}

// decodeVarint decodes a varint-encoded integer from a byte slice, returning it and the number of
// bytes decoded.
func decodeVarint(bz []byte) (int64, int, error) {
i, n := binary.Varint(bz)
if n == 0 {
return i, n, errors.New("buffer too small")
} else if n < 0 {
// value larger than 64 bits (overflow)
// and -n is the number of bytes read
n = -n
return i, n, errors.New("EOF decoding varint")
}
return i, n, nil
}

// encodeBytes writes a varint length-prefixed byte slice to the writer.
func encodeBytes(w io.Writer, bz []byte) error {
err := encodeUvarint(w, uint64(len(bz)))
if err != nil {
return err
}
_, err = w.Write(bz)
return err
}

// encodeBytesSize returns the byte size of the given slice including length-prefixing.
func encodeBytesSize(bz []byte) int {
return encodeUvarintSize(uint64(len(bz))) + len(bz)
}

// encodeUvarint writes a varint-encoded unsigned integer to an io.Writer.
func encodeUvarint(w io.Writer, u uint64) error {
var buf [binary.MaxVarintLen64]byte
n := binary.PutUvarint(buf[:], u)
_, err := w.Write(buf[0:n])
return err
}

// encodeUvarintSize returns the byte size of the given integer as a varint.
func encodeUvarintSize(u uint64) int {
if u == 0 {
return 1
}
return (bits.Len64(u) + 6) / 7
}

// encodeVarint writes a varint-encoded integer to an io.Writer.
func encodeVarint(w io.Writer, i int64) error {
var buf [binary.MaxVarintLen64]byte
n := binary.PutVarint(buf[:], i)
_, err := w.Write(buf[0:n])
return err
}

// encodeVarintSize returns the byte size of the given integer as a varint.
func encodeVarintSize(i int64) int {
var buf [binary.MaxVarintLen64]byte
return binary.PutVarint(buf[:], i)
}
1 change: 1 addition & 0 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func setupExportTreeBasic(t require.TestingT) *ImmutableTree {
}

// setupExportTreeRandom sets up a randomly generated tree.
// nolint: dupl
func setupExportTreeRandom(t *testing.T) *ImmutableTree {
const (
randSeed = 49872768940 // For deterministic tests
Expand Down
Loading