From a4aaa7123978bb5a734935c23fbd9d5bf0cb7846 Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Wed, 19 Jun 2024 18:14:04 +0900 Subject: [PATCH 1/2] wire, main, indexers: remove unconfirmed marker The unconfirmed marker created a discrepancy between the proof sent out for blocks and transactions. It was used for marking if a referenced tx that was being spent was unconfirmed or not but it's removed in favor of the node checking locally for the referenced tx. If the node is unable to find all the referenced txs, the tx is put into the orphan pool. --- blockchain/indexers/flatutreexoproofindex.go | 16 +-- blockchain/indexers/utreexobackend.go | 4 - blockchain/indexers/utreexoproofindex.go | 8 +- blockchain/indexers/utreexoproofstats.go | 2 +- server.go | 6 +- wire/leaf.go | 77 +++---------- wire/leaf_test.go | 108 ++++--------------- wire/msgblock.go | 4 +- wire/msgtx.go | 4 +- wire/udata.go | 57 ++++------ wire/udata_test.go | 73 ++++--------- 11 files changed, 96 insertions(+), 263 deletions(-) diff --git a/blockchain/indexers/flatutreexoproofindex.go b/blockchain/indexers/flatutreexoproofindex.go index 59ae0a5d..f62c14ac 100644 --- a/blockchain/indexers/flatutreexoproofindex.go +++ b/blockchain/indexers/flatutreexoproofindex.go @@ -177,7 +177,7 @@ func (idx *FlatUtreexoProofIndex) Init(chain *blockchain.BlockChain) error { } r := bytes.NewReader(proofBytes) ud := new(wire.UData) - err = ud.DeserializeCompact(r, udataSerializeBool, 0) + err = ud.DeserializeCompact(r) if err != nil { return err } @@ -827,7 +827,7 @@ func (idx *FlatUtreexoProofIndex) FetchUtreexoProof(height int32, excludeAccProo return nil, err } } else { - err = ud.DeserializeCompact(r, udataSerializeBool, 0) + err = ud.DeserializeCompact(r) if err != nil { return nil, err } @@ -923,7 +923,7 @@ func (idx *FlatUtreexoProofIndex) FetchMultiUtreexoProof(height int32) ( // Deserialize the utreexo data that will provide the proof for the upcoming // blocks in the interval. multiUd := new(wire.UData) - err = multiUd.DeserializeCompact(r, udataSerializeBool, 0) + err = multiUd.DeserializeCompact(r) if err != nil { return nil, nil, nil, err } @@ -967,7 +967,7 @@ func (idx *FlatUtreexoProofIndex) FetchRemembers(height int32) ([]uint32, error) // storeProof serializes and stores the utreexo data in the proof state. func (idx *FlatUtreexoProofIndex) storeProof(height int32, excludeAccProof bool, ud *wire.UData) error { if excludeAccProof { - bytesBuf := bytes.NewBuffer(make([]byte, 0, ud.SerializeUxtoDataSizeCompact(udataSerializeBool))) + bytesBuf := bytes.NewBuffer(make([]byte, 0, ud.SerializeUxtoDataSizeCompact())) err := ud.SerializeCompactNoAccProof(bytesBuf) if err != nil { return err @@ -978,8 +978,8 @@ func (idx *FlatUtreexoProofIndex) storeProof(height int32, excludeAccProof bool, return fmt.Errorf("store proof err. %v", err) } } else { - bytesBuf := bytes.NewBuffer(make([]byte, 0, ud.SerializeSizeCompact(udataSerializeBool))) - err := ud.SerializeCompact(bytesBuf, udataSerializeBool) + bytesBuf := bytes.NewBuffer(make([]byte, 0, ud.SerializeSizeCompact())) + err := ud.SerializeCompact(bytesBuf) if err != nil { return err } @@ -1000,7 +1000,7 @@ func (idx *FlatUtreexoProofIndex) storeMultiBlockProof(height int32, ud, multiUd dels []utreexo.Hash) error { size := ud.SerializeSizeCompactNoAccProof() - size += multiUd.SerializeSizeCompact(udataSerializeBool) + size += multiUd.SerializeSizeCompact() size += (len(dels) * chainhash.HashSize) + 4 // 4 for uint32 size bytesBuf := bytes.NewBuffer(make([]byte, 0, size)) @@ -1010,7 +1010,7 @@ func (idx *FlatUtreexoProofIndex) storeMultiBlockProof(height int32, ud, multiUd } multiUd.LeafDatas = []wire.LeafData{} - err = multiUd.SerializeCompact(bytesBuf, udataSerializeBool) + err = multiUd.SerializeCompact(bytesBuf) if err != nil { return err } diff --git a/blockchain/indexers/utreexobackend.go b/blockchain/indexers/utreexobackend.go index 2a02e04e..36c09851 100644 --- a/blockchain/indexers/utreexobackend.go +++ b/blockchain/indexers/utreexobackend.go @@ -25,10 +25,6 @@ const ( nodesDBDirName = "nodes" cachedLeavesDBDirName = "cachedleaves" defaultUtreexoFileName = "forest.dat" - - // udataSerializeBool defines the argument that should be passed to the - // serialize and deserialize functions for udata. - udataSerializeBool = false ) // UtreexoConfig is a descriptor which specifies the Utreexo state instance configuration. diff --git a/blockchain/indexers/utreexoproofindex.go b/blockchain/indexers/utreexoproofindex.go index 9b7d7338..8f29f952 100644 --- a/blockchain/indexers/utreexoproofindex.go +++ b/blockchain/indexers/utreexoproofindex.go @@ -151,7 +151,7 @@ func (idx *UtreexoProofIndex) Init(chain *blockchain.BlockChain) error { } r := bytes.NewReader(proofBytes) - err = ud.DeserializeCompact(r, udataSerializeBool, 0) + err = ud.DeserializeCompact(r) if err != nil { return err } @@ -399,7 +399,7 @@ func (idx *UtreexoProofIndex) FetchUtreexoProof(hash *chainhash.Hash) (*wire.UDa } r := bytes.NewReader(proofBytes) - err = ud.DeserializeCompact(r, udataSerializeBool, 0) + err = ud.DeserializeCompact(r) if err != nil { return err } @@ -606,10 +606,10 @@ func DropUtreexoProofIndex(db database.DB, dataDir string, interrupt <-chan stru // TODO Use the compact serialization. func dbStoreUtreexoProof(dbTx database.Tx, hash *chainhash.Hash, ud *wire.UData) error { // Pre-allocated the needed buffer. - udSize := ud.SerializeSizeCompact(udataSerializeBool) + udSize := ud.SerializeSizeCompact() buf := bytes.NewBuffer(make([]byte, 0, udSize)) - err := ud.SerializeCompact(buf, udataSerializeBool) + err := ud.SerializeCompact(buf) if err != nil { return err } diff --git a/blockchain/indexers/utreexoproofstats.go b/blockchain/indexers/utreexoproofstats.go index 755d56a6..49a5207d 100644 --- a/blockchain/indexers/utreexoproofstats.go +++ b/blockchain/indexers/utreexoproofstats.go @@ -71,7 +71,7 @@ func (ps *proofStats) UpdateUDStats(excludeAccProof bool, ud *wire.UData) { ps.TgCount += uint64(len(ud.AccProof.Targets)) // Update leaf data size. - ps.LdSize += uint64(ud.SerializeUxtoDataSizeCompact(false)) + ps.LdSize += uint64(ud.SerializeUxtoDataSizeCompact()) ps.LdCount += uint64(len(ud.LeafDatas)) // Update proof size if the proof is to be included. diff --git a/server.go b/server.go index b62f71f1..74fcc96f 100644 --- a/server.go +++ b/server.go @@ -2722,7 +2722,7 @@ func (s *server) GetProofSizeforTx(msgTx *wire.MsgTx) (int, int, error) { return 0, 0, err } - return ud.SerializeAccSizeCompact(), ud.SerializeUxtoDataSizeCompact(true), nil + return ud.SerializeAccSizeCompact(), ud.SerializeUxtoDataSizeCompact(), nil } // UpdateProofBytesRead updates the bytes for utreexo proofs that would have @@ -2739,7 +2739,7 @@ func (s *server) UpdateProofBytesRead(msgTx *wire.MsgTx) error { } else if s.chain.IsUtreexoViewActive() { if msgTx.UData != nil { - s.addProofBytesReceived(uint64(msgTx.UData.SerializeSizeCompact(true))) + s.addProofBytesReceived(uint64(msgTx.UData.SerializeSizeCompact())) s.addAccBytesReceived(uint64(msgTx.UData.SerializeAccSizeCompact())) } } @@ -2761,7 +2761,7 @@ func (s *server) UpdateProofBytesWritten(msgTx *wire.MsgTx) error { } else if s.chain.IsUtreexoViewActive() { if msgTx.UData != nil { - s.addProofBytesSent(uint64(msgTx.UData.SerializeSizeCompact(true))) + s.addProofBytesSent(uint64(msgTx.UData.SerializeSizeCompact())) s.addAccBytesSent(uint64(msgTx.UData.SerializeAccSizeCompact())) } } diff --git a/wire/leaf.go b/wire/leaf.go index 40587e9a..a068bf8a 100644 --- a/wire/leaf.go +++ b/wire/leaf.go @@ -5,7 +5,6 @@ package wire import ( - "bytes" "crypto/sha512" "encoding/hex" "encoding/json" @@ -325,21 +324,6 @@ func (l *LeafData) Deserialize(r io.Reader) error { // pkscript length VLQ variable // pkscript []byte variable // -// The serialized format for a transaction is: -// [
] -// -// All other fields with the exception of 'unconfirmed marker' is the same as -// the serialization for a block. The unconfirmed marker is represented in -// the struct as height = -1. -// -// Field Type Size -// unconfirmed marker byte 1 -// header code int32 4 -// amount int64 8 -// pkType byte 1 -// pkscript length VLQ variable -// pkscript []byte variable -// // ----------------------------------------------------------------------------- // PkType is a list of different pkScript types that can be reconstructed. @@ -443,43 +427,24 @@ func PkScriptDeserializeCompact(r io.Reader) (PkType, []byte, error) { // SerializeSizeCompact returns the number of bytes it would take to serialize the // LeafData in the compact serialization format. -func (l *LeafData) SerializeSizeCompact(isForTx bool) int { - if isForTx { - if l.IsUnconfirmed() { - // If the leaf data corresponds to an unconfirmed tx, we only - // send a byte. - return 1 - } else { - // header code 4 bytes + amount 8 bytes + unconfirmed marker + pkscript. - return 13 + PkScriptSerializeSizeCompact( - l.ReconstructablePkType, l.PkScript) - } +func (l *LeafData) SerializeSizeCompact() int { + // If the leaf data corresponds to an unconfirmed tx, we don't + // serialize it. + if l.IsUnconfirmed() { + return 0 } + // header code 4 bytes + amount 8 bytes + pkscript. return 12 + PkScriptSerializeSizeCompact( l.ReconstructablePkType, l.PkScript) } // SerializeCompact encodes the LeafData to w using the compact leaf data serialization format. -func (l *LeafData) SerializeCompact(w io.Writer, isForTx bool) error { - if isForTx { - // If the tx is unconfirmed, write the unconfirmed marker and - // return immediately. - if l.IsUnconfirmed() { - _, err := w.Write([]byte{0x1}) - if err != nil { - return err - } - - // Return if unconfirmed. - return nil - } - - // Write 0 to mark that this transaction is confirmed. - _, err := w.Write([]byte{0x0}) - if err != nil { - return err - } +func (l *LeafData) SerializeCompact(w io.Writer) error { + // If the tx is unconfirmed, write the unconfirmed marker and + // return immediately. + if l.IsUnconfirmed() { + return nil } bs := newSerializer() @@ -508,25 +473,7 @@ func (l *LeafData) SerializeCompact(w io.Writer, isForTx bool) error { } // DeserializeCompact encodes the LeafData to w using the compact leaf serialization format. -func (l *LeafData) DeserializeCompact(r io.Reader, isForTx bool) error { - if isForTx { - // Read unconfirmed marker. - unconfirmed := make([]byte, 1) - _, err := io.ReadFull(r, unconfirmed) - if err != nil { - return err - } - - // 1 means that the LeafData corresponds to an uncomfirmed tx. - // Set IsUnconfirmed as true and return. - if bytes.Equal(unconfirmed, []byte{0x1}) { - l.SetUnconfirmed() - - // Return immediately here if the tx is unconfirmed. - return nil - } - } - +func (l *LeafData) DeserializeCompact(r io.Reader) error { bs := newSerializer() defer bs.free() diff --git a/wire/leaf_test.go b/wire/leaf_test.go index 250b9a9e..2c938798 100644 --- a/wire/leaf_test.go +++ b/wire/leaf_test.go @@ -195,14 +195,12 @@ func TestLeafDataSerialize(t *testing.T) { func TestSerializeSizeCompact(t *testing.T) { tests := []struct { - name string - isForTx bool - ld LeafData - size int + name string + ld LeafData + size int }{ { - name: "For block", - isForTx: false, + name: "Standard", ld: LeafData{ BlockHash: *newHashFromStr("0000000000002b6b9070e6e62e865a5624829eccba1784d058620bf84387d31d"), OutPoint: OutPoint{ @@ -218,25 +216,7 @@ func TestSerializeSizeCompact(t *testing.T) { size: 13, // 8 + 1 + 4 }, { - name: "For tx", - isForTx: true, - ld: LeafData{ - BlockHash: *newHashFromStr("0000000000002b6b9070e6e62e865a5624829eccba1784d058620bf84387d31d"), - OutPoint: OutPoint{ - Hash: *newHashFromStr("061bb0bf3a1b9df13773da06bf92920394887a9c2b8b8772ac06be4e077df5eb"), - Index: 10, - }, - Amount: 200000, - ReconstructablePkType: ScriptHashTy, - PkScript: hexToBytes("a914e8d74935cfa223f9750a32b18d609cba17a5c3fe87"), - Height: 1599255, - IsCoinBase: false, - }, - size: 14, // 1 + 8 + 1 + 4 - }, - { - name: "For tx && unconfirmed", - isForTx: true, + name: "unconfirmed", ld: LeafData{ BlockHash: *newHashFromStr("0000000000002b6b9070e6e62e865a5624829eccba1784d058620bf84387d31d"), OutPoint: OutPoint{ @@ -249,11 +229,10 @@ func TestSerializeSizeCompact(t *testing.T) { Height: -1, IsCoinBase: false, }, - size: 1, + size: 0, }, { - name: "non-standard for block", - isForTx: false, + name: "non-standard", ld: LeafData{ BlockHash: *newHashFromStr("0000000025cc25f695d0f2be43cd87082d39e095f7b77e8b90976f4980f25ef2"), OutPoint: OutPoint{ @@ -273,29 +252,7 @@ func TestSerializeSizeCompact(t *testing.T) { size: 102, // 8 + 1 + 89 + 4 }, { - name: "non-standard for tx", - isForTx: true, - ld: LeafData{ - BlockHash: *newHashFromStr("0000000025cc25f695d0f2be43cd87082d39e095f7b77e8b90976f4980f25ef2"), - OutPoint: OutPoint{ - Hash: *newHashFromStr("8d897ca91774a7fafa086a3275e679248d6bffee015d3b2efefd5dab00df152d"), - Index: 0, - }, - Amount: 1000000, - ReconstructablePkType: OtherTy, - PkScript: hexToBytes( - "76a9145f1426c2ce4a8e1abaa9dbe819b6303eb8a25a2688ad6376a9146c7" + - "ceafe76c56843c9d2868f616fdc9370355eb988ac67aa20644d79" + - "d87e0907833e888e272e5d7b925deb261a8499a65cbc0bf26797a" + - "15e8e8768"), - Height: 319318, - IsCoinBase: false, - }, - size: 103, // 1 + 8 + 1 + 89 + 4 - }, - { - name: "non-standard for tx && unconfirmed", - isForTx: true, + name: "non-standard && unconfirmed", ld: LeafData{ BlockHash: *newHashFromStr("0000000025cc25f695d0f2be43cd87082d39e095f7b77e8b90976f4980f25ef2"), OutPoint: OutPoint{ @@ -312,13 +269,13 @@ func TestSerializeSizeCompact(t *testing.T) { Height: -1, IsCoinBase: false, }, - size: 1, + size: 0, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { - serializedSize := test.ld.SerializeSizeCompact(test.isForTx) + serializedSize := test.ld.SerializeSizeCompact() if serializedSize != test.size { t.Errorf("MsgTx.SerializeSizeCompact: #%d got: %d, want: %d", i, serializedSize, test.size) @@ -327,7 +284,7 @@ func TestSerializeSizeCompact(t *testing.T) { // Sanity check. Actually serialize the data and compare against our hardcoded number. var buf bytes.Buffer - err := test.ld.SerializeCompact(&buf, test.isForTx) + err := test.ld.SerializeCompact(&buf) if err != nil { t.Fatal(err) } @@ -379,15 +336,13 @@ func TestLeafDataSerializeCompact(t *testing.T) { t.Parallel() tests := []struct { - name string - isForTx bool - ld LeafData - before []byte - after []byte + name string + ld LeafData + before []byte + after []byte }{ { - name: "Testnet3 tx 061bb0bf... from block 1600000", - isForTx: false, + name: "Testnet3 tx 061bb0bf... from block 1600000", ld: LeafData{ BlockHash: *newHashFromStr("00000000000172ff8a4e14441512072bacaf8d38b995a3fcd2f8435efc61717d"), OutPoint: OutPoint{ @@ -401,8 +356,7 @@ func TestLeafDataSerializeCompact(t *testing.T) { }, }, { - name: "Mainnet coinbase tx fa201b65... from block 573123", - isForTx: false, + name: "Mainnet coinbase tx fa201b65... from block 573123", ld: LeafData{ BlockHash: *newHashFromStr("000000000000000000278eb9386b4e70b850a4ec21907af3a27f50330b7325aa"), OutPoint: OutPoint{ @@ -416,23 +370,7 @@ func TestLeafDataSerializeCompact(t *testing.T) { }, }, { - name: "unconfirmed", - isForTx: true, - ld: LeafData{ - BlockHash: *newHashFromStr("000000000000000000278eb9386b4e70b850a4ec21907af3a27f50330b7325aa"), - OutPoint: OutPoint{ - Hash: *newHashFromStr("fa201b650eef761f5701afbb610e4a211b86985da4745aec3ac0f4b7a8e2c8d2"), - Index: 0, - }, - Amount: 1315080370, - PkScript: hexToBytes("76a9142cc2b87a28c8a097f48fcc1d468ced6e7d39958d88ac"), - Height: -1, - IsCoinBase: true, - }, - }, - { - name: "confirmed", - isForTx: true, + name: "confirmed", ld: LeafData{ BlockHash: *newHashFromStr("000000000000000000278eb9386b4e70b850a4ec21907af3a27f50330b7325aa"), OutPoint: OutPoint{ @@ -450,12 +388,12 @@ func TestLeafDataSerializeCompact(t *testing.T) { for _, test := range tests { // Serialize writer := &bytes.Buffer{} - test.ld.SerializeCompact(writer, test.isForTx) + test.ld.SerializeCompact(writer) test.before = writer.Bytes() // Deserialize checkLeaf := NewLeafData() - checkLeaf.DeserializeCompact(writer, test.isForTx) + checkLeaf.DeserializeCompact(writer) err := checkCompactLeafEqual(test.ld, checkLeaf) if err != nil { @@ -464,7 +402,7 @@ func TestLeafDataSerializeCompact(t *testing.T) { // Re-serialize afterWriter := &bytes.Buffer{} - checkLeaf.SerializeCompact(afterWriter, test.isForTx) + checkLeaf.SerializeCompact(afterWriter) test.after = afterWriter.Bytes() // Check if before and after match. @@ -615,13 +553,13 @@ func TestIsCompact(t *testing.T) { } var w bytes.Buffer - err := test.ld.SerializeCompact(&w, false) + err := test.ld.SerializeCompact(&w) if err != nil { t.Fatal(err) } compact := NewLeafData() - err = compact.DeserializeCompact(&w, false) + err = compact.DeserializeCompact(&w) if err != nil { t.Fatal(err) } diff --git a/wire/msgblock.go b/wire/msgblock.go index ff200b52..a9e688ab 100644 --- a/wire/msgblock.go +++ b/wire/msgblock.go @@ -115,7 +115,7 @@ func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) er // checked for length, this probably is ok. But do think of // a better solution. msg.UData = new(UData) - err = msg.UData.DeserializeCompact(r, false, 0) + err = msg.UData.DeserializeCompact(r) if err != nil { if enc&UtreexoEncoding == UtreexoEncoding { return err @@ -232,7 +232,7 @@ func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) er str := "utreexo encoding specified but MsgBlock.UData field is nil" return messageError("MsgBlock.BtcEncode", str) } - err = msg.UData.SerializeCompact(w, false) + err = msg.UData.SerializeCompact(w) if err != nil { return err } diff --git a/wire/msgtx.go b/wire/msgtx.go index 70c3cfec..8a959a03 100644 --- a/wire/msgtx.go +++ b/wire/msgtx.go @@ -681,7 +681,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error if enc&UtreexoEncoding == UtreexoEncoding { msg.UData = new(UData) - err = msg.UData.DeserializeCompact(r, true, len(msg.TxIn)) + err = msg.UData.DeserializeCompact(r) if err != nil { return err } @@ -790,7 +790,7 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error // AccProof can be nil for transactions that are included in // a block. if msg.UData != nil { - err = msg.UData.SerializeCompact(w, true) + err = msg.UData.SerializeCompact(w) if err != nil { return err } diff --git a/wire/udata.go b/wire/udata.go index cc42ffad..a153f1f2 100644 --- a/wire/udata.go +++ b/wire/udata.go @@ -186,16 +186,13 @@ func (ud *UData) SerializeAccSizeCompact() int { // SerializeUxtoDataSizeCompact returns the number of bytes it would take to serialize // the utxo data and the remember idx data with the compact serialization format. -func (ud *UData) SerializeUxtoDataSizeCompact(isForTx bool) int { +func (ud *UData) SerializeUxtoDataSizeCompact() int { var size int - // Explicitly serialize the count for utreexo only if they're for - // blocks. - if !isForTx { - size += VarIntSerializeSize(uint64(len(ud.LeafDatas))) - } + // Explicitly serialize the count for the leaf datas. + size += VarIntSerializeSize(uint64(len(ud.LeafDatas))) for _, l := range ud.LeafDatas { - size += l.SerializeSizeCompact(isForTx) + size += l.SerializeSizeCompact() } return size @@ -203,12 +200,12 @@ func (ud *UData) SerializeUxtoDataSizeCompact(isForTx bool) int { // SerializeSizeCompact returns the number of bytes it would take to serialize the // UData using the compact UData serialization format. -func (ud *UData) SerializeSizeCompact(isForTx bool) int { +func (ud *UData) SerializeSizeCompact() int { // Accumulator proof size. size := BatchProofSerializeSize(&ud.AccProof) // Leaf data size - size += ud.SerializeUxtoDataSizeCompact(isForTx) + size += ud.SerializeUxtoDataSizeCompact() // Remember indexes size. return size + ud.SerializeRememberIdxSize() @@ -218,7 +215,7 @@ func (ud *UData) SerializeSizeCompact(isForTx bool) int { // serialization format. It follows the normal UData serialization format with // the exception that compact leaf data serialization is used. Everything else // remains the same. -func (ud *UData) SerializeCompact(w io.Writer, isForTx bool) error { +func (ud *UData) SerializeCompact(w io.Writer) error { err := SerializeRemembers(w, ud.RememberIdx) if err != nil { return err @@ -230,18 +227,14 @@ func (ud *UData) SerializeCompact(w io.Writer, isForTx bool) error { return returnErr } - // Since transactions are given explicit leaf data count through - // the txIn count, we do not serialize the leaf data count. - if !isForTx { - err = WriteVarInt(w, 0, uint64(len(ud.LeafDatas))) - if err != nil { - return err - } + err = WriteVarInt(w, 0, uint64(len(ud.LeafDatas))) + if err != nil { + return err } // Write all the leafDatas. for _, ld := range ud.LeafDatas { - err = ld.SerializeCompact(w, isForTx) + err = ld.SerializeCompact(w) if err != nil { return err } @@ -256,7 +249,7 @@ func (ud *UData) SerializeCompact(w io.Writer, isForTx bool) error { // NOTE if deserializing for a transaction, a non zero txInCount MUST be passed // in as a correct txCount is critical for deserializing correctly. When // deserializing a block, txInCount does not matter. -func (ud *UData) DeserializeCompact(r io.Reader, isForTx bool, txInCount int) error { +func (ud *UData) DeserializeCompact(r io.Reader) error { remembers, err := DeserializeRemembers(r) if err != nil { return err @@ -270,21 +263,15 @@ func (ud *UData) DeserializeCompact(r io.Reader, isForTx bool, txInCount int) er } ud.AccProof = *proof - // NOTE there may be more leafDatas vs targets for txs as unconfirmed - // txs will be included as leaf datas but not as targets. For blocks, - // the leaf data count need to be explicitly read. - if isForTx { - ud.LeafDatas = make([]LeafData, txInCount) - } else { - // Grab the count for the udatas - udCount, err := ReadVarInt(r, 0) - if err != nil { - return err - } - ud.LeafDatas = make([]LeafData, udCount) + // Grab the count for the udatas + udCount, err := ReadVarInt(r, 0) + if err != nil { + return err } + ud.LeafDatas = make([]LeafData, udCount) + for i := range ud.LeafDatas { - err = ud.LeafDatas[i].DeserializeCompact(r, isForTx) + err = ud.LeafDatas[i].DeserializeCompact(r) if err != nil { str := fmt.Sprintf("rememberCount %d, targetCount:%d, LeafDatas[%d], err:%s\n", len(remembers), len(ud.AccProof.Targets), i, err.Error()) @@ -304,7 +291,7 @@ func (ud *UData) SerializeSizeCompactNoAccProof() int { size += VarIntSerializeSize(target) } - return size + ud.SerializeUxtoDataSizeCompact(false) + return size + ud.SerializeUxtoDataSizeCompact() } // SerializeCompactNoAccProof will serialize the utreexo data with the compact @@ -330,7 +317,7 @@ func (ud *UData) SerializeCompactNoAccProof(w io.Writer) error { return err } for _, ld := range ud.LeafDatas { - err := ld.SerializeCompact(w, false) + err := ld.SerializeCompact(w) if err != nil { return err } @@ -368,7 +355,7 @@ func (ud *UData) DeserializeCompactNoAccProof(r io.Reader) error { } ud.LeafDatas = make([]LeafData, udCount) for i := range ud.LeafDatas { - err := ud.LeafDatas[i].DeserializeCompact(r, false) + err := ud.LeafDatas[i].DeserializeCompact(r) if err != nil { str := fmt.Sprintf("targetCount:%d, LeafDatas[%d], err:%s\n", len(ud.AccProof.Targets), i, err.Error()) diff --git a/wire/udata_test.go b/wire/udata_test.go index 27e7ac61..c5a60326 100644 --- a/wire/udata_test.go +++ b/wire/udata_test.go @@ -25,7 +25,6 @@ type testData struct { size int sizeCompact int - sizeCompactTx int sizeCompactNoAcc int } @@ -63,7 +62,6 @@ var mainNetBlock104773 = testData{ rememberIdx: []uint32{2, 3}, size: 220, sizeCompact: 86, - sizeCompactTx: 87, sizeCompactNoAcc: 82, } @@ -119,7 +117,6 @@ var testNetBlock383 = testData{ rememberIdx: []uint32{1, 2, 3}, size: 465, sizeCompact: 197, - sizeCompactTx: 200, sizeCompactNoAcc: 192, } @@ -219,7 +216,6 @@ func TestUDataSerializeSize(t *testing.T) { ud UData size int sizeCompact int - sizeCompactTx int sizeCompactNoAcc int } @@ -259,7 +255,6 @@ func TestUDataSerializeSize(t *testing.T) { ud: *ud, size: testData.size, sizeCompact: testData.sizeCompact, - sizeCompactTx: testData.sizeCompactTx, sizeCompactNoAcc: testData.sizeCompactNoAcc, }) } @@ -286,10 +281,10 @@ func TestUDataSerializeSize(t *testing.T) { continue } - gotSize = test.ud.SerializeSizeCompact(false) + gotSize = test.ud.SerializeSizeCompact() if gotSize != test.sizeCompact { var buf bytes.Buffer - err := test.ud.SerializeCompact(&buf, false) + err := test.ud.SerializeCompact(&buf) if err != nil { t.Fatal(err) } @@ -303,7 +298,7 @@ func TestUDataSerializeSize(t *testing.T) { // Sanity check. Actually serialize the data and compare against our hardcoded number. buf.Reset() - err = test.ud.SerializeCompact(&buf, false) + err = test.ud.SerializeCompact(&buf) if err != nil { t.Fatal(err) } @@ -314,26 +309,12 @@ func TestUDataSerializeSize(t *testing.T) { continue } - gotSize = test.ud.SerializeSizeCompact(true) - if gotSize != test.sizeCompactTx { - t.Errorf("%s: UData serialize size compact (true) fail. "+ - "expect %d, got %d", test.name, - test.sizeCompactTx, gotSize) - continue - } - // Sanity check. Actually serialize the data and compare against our hardcoded number. buf.Reset() - err = test.ud.SerializeCompact(&buf, true) + err = test.ud.SerializeCompact(&buf) if err != nil { t.Fatal(err) } - if len(buf.Bytes()) != test.sizeCompactTx { - t.Errorf("%s: UData serialize size compact(true) fail. "+ - "serialized %d, hardcoded %d", test.name, - len(buf.Bytes()), test.sizeCompactTx) - continue - } gotSize = test.ud.SerializeSizeCompactNoAccProof() if gotSize != test.sizeCompactNoAcc { @@ -358,12 +339,12 @@ func TestUDataSerializeSize(t *testing.T) { // Test that SerializeUxtoDataSizeCompact and SerializeUxtoDataSizeCompact // sums up to the entire thing. - totals := test.ud.SerializeUxtoDataSizeCompact(true) + test.ud.SerializeAccSizeCompact() + totals := test.ud.SerializeUxtoDataSizeCompact() + test.ud.SerializeAccSizeCompact() totals += test.ud.SerializeRememberIdxSize() - if totals != test.ud.SerializeSizeCompact(true) { + if totals != test.ud.SerializeSizeCompact() { t.Errorf("%s: expected %d for but got %d as the sum of utxodata, accumulator data, and the remember idxs", - test.name, test.ud.SerializeSizeCompact(true), totals) + test.name, test.ud.SerializeSizeCompact(), totals) } } } @@ -443,12 +424,10 @@ func TestUDataSerializeCompact(t *testing.T) { t.Parallel() type test struct { - name string - isForTx bool - leafCount int - ud UData - before []byte - after []byte + name string + ud UData + before []byte + after []byte } testDatas := getTestDatas() @@ -481,46 +460,32 @@ func TestUDataSerializeCompact(t *testing.T) { // Append to the tests. tests = append(tests, test{ - name: testData.name, - isForTx: false, - ud: *ud, - }) - tests = append(tests, test{ - name: testData.name + " + isForTx", - isForTx: true, - leafCount: len(ud.LeafDatas), - ud: *ud, + name: testData.name, + ud: *ud, }) } for _, test := range tests { // Serialize writer := &bytes.Buffer{} - test.ud.SerializeCompact(writer, test.isForTx) + test.ud.SerializeCompact(writer) test.before = writer.Bytes() // Deserialize checkUData := new(UData) - if test.isForTx { - err := checkUData.DeserializeCompact(writer, test.isForTx, test.leafCount) - if err != nil { - t.Fatal(err) - } - } else { - err := checkUData.DeserializeCompact(writer, test.isForTx, 0) - if err != nil { - t.Fatal(err) - } + err := checkUData.DeserializeCompact(writer) + if err != nil { + t.Fatal(err) } - err := checkUDEqual(&test.ud, checkUData, true, test.name) + err = checkUDEqual(&test.ud, checkUData, true, test.name) if err != nil { t.Error(err) } // Re-serialize afterWriter := &bytes.Buffer{} - checkUData.SerializeCompact(afterWriter, test.isForTx) + checkUData.SerializeCompact(afterWriter) test.after = afterWriter.Bytes() // Check if before and after match. From 24f29d8c5d69d154f80970703a0b14c6481d22f8 Mon Sep 17 00:00:00 2001 From: Calvin Kim Date: Mon, 24 Jun 2024 18:57:59 +0900 Subject: [PATCH 2/2] wire: remove unnecessary variable --- wire/udata.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wire/udata.go b/wire/udata.go index a153f1f2..eccceb2d 100644 --- a/wire/udata.go +++ b/wire/udata.go @@ -419,14 +419,8 @@ func DeserializeRemembers(r io.Reader) ([]uint32, error) { // leaf data is compact as you can't generate the correct hash. func HashesFromLeafDatas(leafDatas []LeafData) ([]utreexo.Hash, error) { // make slice of hashes from leafdata - var unconfirmedCount int delHashes := make([]utreexo.Hash, 0, len(leafDatas)) for _, ld := range leafDatas { - if ld.IsUnconfirmed() { - unconfirmedCount++ - continue - } - // We can't calculate the correct hash if the leaf data is in // the compact state. if ld.IsCompact() {