Skip to content

Commit

Permalink
Merge pull request #232 from kcalvinalvin/2024-11-27-msgutreexoproof
Browse files Browse the repository at this point in the history
wire: add msgutreexoproof and msggetutreexoproof
  • Loading branch information
kcalvinalvin authored Jan 3, 2025
2 parents 3d12d65 + b78a1b0 commit 40330b1
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 0 deletions.
8 changes: 8 additions & 0 deletions wire/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const (
CmdCFHeaders = "cfheaders"
CmdCFCheckpt = "cfcheckpt"
CmdSendAddrV2 = "sendaddrv2"
CmdUtreexoProof = "uproof"
CmdGetUtreexoProof = "getuproof"
)

// MessageEncoding represents the wire message encoding format to be used.
Expand Down Expand Up @@ -155,6 +157,12 @@ func makeEmptyMessage(command string) (Message, error) {
case CmdUtreexoHeader:
msg = &MsgUtreexoHeader{}

case CmdUtreexoProof:
msg = &MsgUtreexoProof{}

case CmdGetUtreexoProof:
msg = &MsgGetUtreexoProof{}

case CmdAlert:
msg = &MsgAlert{}

Expand Down
111 changes: 111 additions & 0 deletions wire/msggetutreexoproof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (c) 2024 The utreexo developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
"io"

"github.com/utreexo/utreexod/chaincfg/chainhash"
)

// MsgGetUtreexoProof encodes uint64s in varints to request specifics indexes of a
// utreexoproof from a peer.
type MsgGetUtreexoProof struct {
// BlockHash is the hash of the block we want the utreexo proof for.
BlockHash chainhash.Hash

// ProofIndexes are the indexes from the utreexo proof hashes that we want.
ProofIndexes []uint64

// LeafIndexes are the indexes from the leaf datas we want.
LeafIndexes []uint64
}

// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding transactions stored to disk, such as in a
// database, as opposed to decoding transactions from the wire.
func (msg *MsgGetUtreexoProof) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
_, err := r.Read(msg.BlockHash[:])
if err != nil {
return err
}

proofCount, err := ReadVarInt(r, 0)
if err != nil {
return err
}

msg.ProofIndexes = make([]uint64, proofCount)
for i := range msg.ProofIndexes {
msg.ProofIndexes[i], err = ReadVarInt(r, pver)
if err != nil {
return err
}
}

leafCount, err := ReadVarInt(r, 0)
if err != nil {
return err
}

msg.LeafIndexes = make([]uint64, leafCount)
for i := range msg.LeafIndexes {
msg.LeafIndexes[i], err = ReadVarInt(r, pver)
if err != nil {
return err
}
}

return nil
}

// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding transactions to be stored to disk, such as in a
// database, as opposed to encoding transactions for the wire.
func (msg *MsgGetUtreexoProof) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
_, err := w.Write(msg.BlockHash[:])
if err != nil {
return err
}

err = WriteVarInt(w, pver, uint64(len(msg.ProofIndexes)))
if err != nil {
return err
}

for i := range msg.ProofIndexes {
err = WriteVarInt(w, pver, msg.ProofIndexes[i])
if err != nil {
return err
}
}

err = WriteVarInt(w, pver, uint64(len(msg.LeafIndexes)))
if err != nil {
return err
}

for i := range msg.LeafIndexes {
err = WriteVarInt(w, pver, msg.LeafIndexes[i])
if err != nil {
return err
}
}
return nil
}

// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetUtreexoProof) Command() string {
return CmdGetUtreexoProof
}

// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetUtreexoProof) MaxPayloadLength(pver uint32) uint32 {
return MaxBlockPayload
}
115 changes: 115 additions & 0 deletions wire/msgutreexoproof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) 2024 The utreexo developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package wire

import (
"io"

"github.com/utreexo/utreexo"
"github.com/utreexo/utreexod/chaincfg/chainhash"
)

// MsgUtreexoProof is a utreexo proof for a given block that includes the rest of the data not
// communicated by the utreexo header. It may or may not include all the data needed to prove
// the given block as a peer is able to ask for only the proof data it needs.
type MsgUtreexoProof struct {
// BlockHash is the hash of the block this utreexo proof proves.
BlockHash chainhash.Hash

// ProofHashes is the hashes needed to hash up to the utreexo roots.
ProofHashes []utreexo.Hash

// LeafDatas are the tx validation data for every input.
LeafDatas []LeafData
}

// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding transactions stored to disk, such as in a
// database, as opposed to decoding transactions from the wire.
func (msg *MsgUtreexoProof) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
_, err := r.Read(msg.BlockHash[:])
if err != nil {
return err
}

proofCount, err := ReadVarInt(r, 0)
if err != nil {
return err
}

msg.ProofHashes = make([]utreexo.Hash, proofCount)
for i := range msg.ProofHashes {
_, err = io.ReadFull(r, msg.ProofHashes[i][:])
if err != nil {
return err
}
}

leafCount, err := ReadVarInt(r, 0)
if err != nil {
return err
}

msg.LeafDatas = make([]LeafData, leafCount)
for i := range msg.LeafDatas {
err = msg.LeafDatas[i].DeserializeCompact(r)
if err != nil {
return err
}
}

return nil
}

// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding transactions to be stored to disk, such as in a
// database, as opposed to encoding transactions for the wire.
func (msg *MsgUtreexoProof) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
_, err := w.Write(msg.BlockHash[:])
if err != nil {
return err
}

err = WriteVarInt(w, 0, uint64(len(msg.ProofHashes)))
if err != nil {
return err
}

for _, h := range msg.ProofHashes {
_, err = w.Write(h[:])
if err != nil {
return err
}
}

// Write the size of the leaf datas.
err = WriteVarInt(w, 0, uint64(len(msg.LeafDatas)))
if err != nil {
return err
}

// Write the actual leaf datas.
for _, ld := range msg.LeafDatas {
err = ld.SerializeCompact(w)
if err != nil {
return err
}
}
return nil
}

// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgUtreexoProof) Command() string {
return CmdUtreexoProof
}

// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgUtreexoProof) MaxPayloadLength(pver uint32) uint32 {
return MaxBlockPayload
}

0 comments on commit 40330b1

Please sign in to comment.