Skip to content

Commit

Permalink
Merge pull request #170 from SiaFoundation/generic-encoder
Browse files Browse the repository at this point in the history
types: Implement generic encoder functions
  • Loading branch information
n8maninger committed Jun 11, 2024
2 parents eb021a0 + f64b216 commit 36ea9c7
Show file tree
Hide file tree
Showing 11 changed files with 455 additions and 792 deletions.
78 changes: 21 additions & 57 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,41 +435,41 @@ func (s State) WholeSigHash(txn types.Transaction, parentID types.Hash256, pubke
defer hasherPool.Put(h)
h.Reset()

h.E.WritePrefix(len((txn.SiacoinInputs)))
h.E.WriteUint64(uint64(len((txn.SiacoinInputs))))
for i := range txn.SiacoinInputs {
h.E.Write(s.replayPrefix())
txn.SiacoinInputs[i].EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.SiacoinOutputs)))
h.E.WriteUint64(uint64(len((txn.SiacoinOutputs))))
for i := range txn.SiacoinOutputs {
types.V1SiacoinOutput(txn.SiacoinOutputs[i]).EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.FileContracts)))
h.E.WriteUint64(uint64(len((txn.FileContracts))))
for i := range txn.FileContracts {
txn.FileContracts[i].EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.FileContractRevisions)))
h.E.WriteUint64(uint64(len((txn.FileContractRevisions))))
for i := range txn.FileContractRevisions {
txn.FileContractRevisions[i].EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.StorageProofs)))
h.E.WriteUint64(uint64(len((txn.StorageProofs))))
for i := range txn.StorageProofs {
txn.StorageProofs[i].EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.SiafundInputs)))
h.E.WriteUint64(uint64(len((txn.SiafundInputs))))
for i := range txn.SiafundInputs {
h.E.Write(s.replayPrefix())
txn.SiafundInputs[i].EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.SiafundOutputs)))
h.E.WriteUint64(uint64(len((txn.SiafundOutputs))))
for i := range txn.SiafundOutputs {
types.V1SiafundOutput(txn.SiafundOutputs[i]).EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.MinerFees)))
h.E.WriteUint64(uint64(len((txn.MinerFees))))
for i := range txn.MinerFees {
types.V1Currency(txn.MinerFees[i]).EncodeTo(h.E)
}
h.E.WritePrefix(len((txn.ArbitraryData)))
h.E.WriteUint64(uint64(len((txn.ArbitraryData))))
for i := range txn.ArbitraryData {
h.E.WriteBytes(txn.ArbitraryData[i])
}
Expand Down Expand Up @@ -693,42 +693,18 @@ type V1TransactionSupplement struct {

// EncodeTo implements types.EncoderTo.
func (ts V1TransactionSupplement) EncodeTo(e *types.Encoder) {
e.WritePrefix(len(ts.SiacoinInputs))
for i := range ts.SiacoinInputs {
ts.SiacoinInputs[i].EncodeTo(e)
}
e.WritePrefix(len(ts.SiafundInputs))
for i := range ts.SiafundInputs {
ts.SiafundInputs[i].EncodeTo(e)
}
e.WritePrefix(len(ts.RevisedFileContracts))
for i := range ts.RevisedFileContracts {
ts.RevisedFileContracts[i].EncodeTo(e)
}
e.WritePrefix(len(ts.ValidFileContracts))
for i := range ts.ValidFileContracts {
ts.ValidFileContracts[i].EncodeTo(e)
}
types.EncodeSlice(e, ts.SiacoinInputs)
types.EncodeSlice(e, ts.SiafundInputs)
types.EncodeSlice(e, ts.RevisedFileContracts)
types.EncodeSlice(e, ts.ValidFileContracts)
}

// DecodeFrom implements types.DecoderFrom.
func (ts *V1TransactionSupplement) DecodeFrom(d *types.Decoder) {
ts.SiacoinInputs = make([]types.SiacoinElement, d.ReadPrefix())
for i := range ts.SiacoinInputs {
ts.SiacoinInputs[i].DecodeFrom(d)
}
ts.SiafundInputs = make([]types.SiafundElement, d.ReadPrefix())
for i := range ts.SiafundInputs {
ts.SiafundInputs[i].DecodeFrom(d)
}
ts.RevisedFileContracts = make([]types.FileContractElement, d.ReadPrefix())
for i := range ts.RevisedFileContracts {
ts.RevisedFileContracts[i].DecodeFrom(d)
}
ts.ValidFileContracts = make([]types.FileContractElement, d.ReadPrefix())
for i := range ts.ValidFileContracts {
ts.ValidFileContracts[i].DecodeFrom(d)
}
types.DecodeSlice(d, &ts.SiacoinInputs)
types.DecodeSlice(d, &ts.SiafundInputs)
types.DecodeSlice(d, &ts.RevisedFileContracts)
types.DecodeSlice(d, &ts.ValidFileContracts)
}

func (ts V1TransactionSupplement) siacoinElement(id types.SiacoinOutputID) (sce types.SiacoinElement, ok bool) {
Expand Down Expand Up @@ -783,24 +759,12 @@ type V1BlockSupplement struct {

// EncodeTo implements types.EncoderTo.
func (bs V1BlockSupplement) EncodeTo(e *types.Encoder) {
e.WritePrefix(len(bs.Transactions))
for i := range bs.Transactions {
bs.Transactions[i].EncodeTo(e)
}
e.WritePrefix(len(bs.ExpiringFileContracts))
for i := range bs.ExpiringFileContracts {
bs.ExpiringFileContracts[i].EncodeTo(e)
}
types.EncodeSlice(e, bs.Transactions)
types.EncodeSlice(e, bs.ExpiringFileContracts)
}

// DecodeFrom implements types.DecoderFrom.
func (bs *V1BlockSupplement) DecodeFrom(d *types.Decoder) {
bs.Transactions = make([]V1TransactionSupplement, d.ReadPrefix())
for i := range bs.Transactions {
bs.Transactions[i].DecodeFrom(d)
}
bs.ExpiringFileContracts = make([]types.FileContractElement, d.ReadPrefix())
for i := range bs.ExpiringFileContracts {
bs.ExpiringFileContracts[i].DecodeFrom(d)
}
types.DecodeSlice(d, &bs.Transactions)
types.DecodeSlice(d, &bs.ExpiringFileContracts)
}
116 changes: 26 additions & 90 deletions gateway/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func withV1Encoder(w io.Writer, fn func(*types.Encoder)) error {
var buf bytes.Buffer
e := types.NewEncoder(&buf)
e.WritePrefix(0) // placeholder
e.WriteUint64(0) // placeholder
fn(e)
e.Flush()
b := buf.Bytes()
Expand All @@ -24,7 +24,7 @@ func withV1Encoder(w io.Writer, fn func(*types.Encoder)) error {

func withV1Decoder(r io.Reader, maxLen int, fn func(*types.Decoder)) error {
d := types.NewDecoder(io.LimitedReader{R: r, N: int64(8 + maxLen)})
d.ReadPrefix() // ignored
d.ReadUint64() // prefix, ignored
fn(d)
return d.Err()
}
Expand Down Expand Up @@ -107,15 +107,9 @@ func (ob *V2BlockOutline) encodeTo(e *types.Encoder) {
kinds = append(kinds, 2)
}
}
e.WritePrefix(len(txns))
for i := range txns {
txns[i].EncodeTo(e)
}
types.EncodeSlice(e, txns)
types.V2TransactionsMultiproof(v2txns).EncodeTo(e)
e.WritePrefix(len(hashes))
for i := range hashes {
hashes[i].EncodeTo(e)
}
types.EncodeSlice(e, hashes)
for i := range kinds {
e.WriteUint8(kinds[i])
}
Expand All @@ -128,16 +122,12 @@ func (ob *V2BlockOutline) decodeFrom(d *types.Decoder) {
ob.Timestamp = d.ReadTime()
ob.MinerAddress.DecodeFrom(d)

txns := make([]types.Transaction, d.ReadPrefix())
for i := range txns {
txns[i].DecodeFrom(d)
}
var txns []types.Transaction
var v2txns types.V2TransactionsMultiproof
var hashes []types.Hash256
types.DecodeSlice(d, &txns)
v2txns.DecodeFrom(d)
hashes := make([]types.Hash256, d.ReadPrefix())
for i := range hashes {
hashes[i].DecodeFrom(d)
}
types.DecodeSlice(d, &hashes)
kinds := make([]uint8, len(txns)+len(v2txns)+len(hashes))
var counts [3]int
for i := range kinds {
Expand Down Expand Up @@ -199,16 +189,10 @@ type RPCShareNodes struct {
}

func (r *RPCShareNodes) encodeResponse(e *types.Encoder) {
e.WritePrefix(len(r.Peers))
for i := range r.Peers {
e.WriteString(r.Peers[i])
}
types.EncodeSliceFn(e, r.Peers, (*types.Encoder).WriteString)
}
func (r *RPCShareNodes) decodeResponse(d *types.Decoder) {
r.Peers = make([]string, d.ReadPrefix())
for i := range r.Peers {
r.Peers[i] = d.ReadString()
}
types.DecodeSliceFn(d, &r.Peers, (*types.Decoder).ReadString)
}
func (r *RPCShareNodes) maxResponseLen() int { return 100 * 128 }

Expand Down Expand Up @@ -241,16 +225,10 @@ func (r *RPCSendBlocks) decodeRequest(d *types.Decoder) {
func (r *RPCSendBlocks) maxRequestLen() int { return 32 * 32 }

func (r *RPCSendBlocks) encodeResponse(e *types.Encoder) {
e.WritePrefix(len(r.Blocks))
for i := range r.Blocks {
types.V1Block(r.Blocks[i]).EncodeTo(e)
}
types.EncodeSliceCast[types.V1Block](e, r.Blocks)
}
func (r *RPCSendBlocks) decodeResponse(d *types.Decoder) {
r.Blocks = make([]types.Block, d.ReadPrefix())
for i := range r.Blocks {
(*types.V1Block)(&r.Blocks[i]).DecodeFrom(d)
}
types.DecodeSliceCast[types.V1Block](d, &r.Blocks)
}
func (r *RPCSendBlocks) maxResponseLen() int { return 10 * 5e6 }

Expand Down Expand Up @@ -298,16 +276,10 @@ type RPCRelayTransactionSet struct {
}

func (r *RPCRelayTransactionSet) encodeRequest(e *types.Encoder) {
e.WritePrefix(len(r.Transactions))
for i := range r.Transactions {
r.Transactions[i].EncodeTo(e)
}
types.EncodeSlice(e, r.Transactions)
}
func (r *RPCRelayTransactionSet) decodeRequest(d *types.Decoder) {
r.Transactions = make([]types.Transaction, d.ReadPrefix())
for i := range r.Transactions {
r.Transactions[i].DecodeFrom(d)
}
types.DecodeSlice(d, &r.Transactions)
}
func (r *RPCRelayTransactionSet) maxRequestLen() int { return 5e6 }

Expand All @@ -320,33 +292,21 @@ type RPCSendV2Blocks struct {
}

func (r *RPCSendV2Blocks) encodeRequest(e *types.Encoder) {
e.WritePrefix(len(r.History))
for i := range r.History {
r.History[i].EncodeTo(e)
}
types.EncodeSlice(e, r.History)
e.WriteUint64(r.Max)
}
func (r *RPCSendV2Blocks) decodeRequest(d *types.Decoder) {
r.History = make([]types.BlockID, d.ReadPrefix())
for i := range r.History {
r.History[i].DecodeFrom(d)
}
types.DecodeSlice(d, &r.History)
r.Max = d.ReadUint64()
}
func (r *RPCSendV2Blocks) maxRequestLen() int { return 8 + 32*32 + 8 }

func (r *RPCSendV2Blocks) encodeResponse(e *types.Encoder) {
e.WritePrefix(len(r.Blocks))
for i := range r.Blocks {
types.V2Block(r.Blocks[i]).EncodeTo(e)
}
types.EncodeSliceCast[types.V2Block](e, r.Blocks)
e.WriteUint64(r.Remaining)
}
func (r *RPCSendV2Blocks) decodeResponse(d *types.Decoder) {
r.Blocks = make([]types.Block, d.ReadPrefix())
for i := range r.Blocks {
(*types.V2Block)(&r.Blocks[i]).DecodeFrom(d)
}
types.DecodeSliceCast[types.V2Block](d, &r.Blocks)
r.Remaining = d.ReadUint64()
}
func (r *RPCSendV2Blocks) maxResponseLen() int { return int(r.Max) * 5e6 }
Expand All @@ -362,39 +322,21 @@ type RPCSendTransactions struct {

func (r *RPCSendTransactions) encodeRequest(e *types.Encoder) {
r.Index.EncodeTo(e)
e.WritePrefix(len(r.Hashes))
for i := range r.Hashes {
r.Hashes[i].EncodeTo(e)
}
types.EncodeSlice(e, r.Hashes)
}
func (r *RPCSendTransactions) decodeRequest(d *types.Decoder) {
r.Index.DecodeFrom(d)
r.Hashes = make([]types.Hash256, d.ReadPrefix())
for i := range r.Hashes {
r.Hashes[i].DecodeFrom(d)
}
types.DecodeSlice(d, &r.Hashes)
}
func (r *RPCSendTransactions) maxRequestLen() int { return 8 + 32 + 8 + 100*32 }

func (r *RPCSendTransactions) encodeResponse(e *types.Encoder) {
e.WritePrefix(len(r.Transactions))
for i := range r.Transactions {
r.Transactions[i].EncodeTo(e)
}
e.WritePrefix(len(r.V2Transactions))
for i := range r.V2Transactions {
r.V2Transactions[i].EncodeTo(e)
}
types.EncodeSlice(e, r.Transactions)
types.EncodeSlice(e, r.V2Transactions)
}
func (r *RPCSendTransactions) decodeResponse(d *types.Decoder) {
r.Transactions = make([]types.Transaction, d.ReadPrefix())
for i := range r.Transactions {
r.Transactions[i].DecodeFrom(d)
}
r.V2Transactions = make([]types.V2Transaction, d.ReadPrefix())
for i := range r.V2Transactions {
r.V2Transactions[i].DecodeFrom(d)
}
types.DecodeSlice(d, &r.Transactions)
types.DecodeSlice(d, &r.V2Transactions)
}
func (r *RPCSendTransactions) maxResponseLen() int { return 5e6 }

Expand Down Expand Up @@ -449,17 +391,11 @@ type RPCRelayV2TransactionSet struct {

func (r *RPCRelayV2TransactionSet) encodeRequest(e *types.Encoder) {
r.Index.EncodeTo(e)
e.WritePrefix(len(r.Transactions))
for i := range r.Transactions {
r.Transactions[i].EncodeTo(e)
}
types.EncodeSlice(e, r.Transactions)
}
func (r *RPCRelayV2TransactionSet) decodeRequest(d *types.Decoder) {
r.Index.DecodeFrom(d)
r.Transactions = make([]types.V2Transaction, d.ReadPrefix())
for i := range r.Transactions {
r.Transactions[i].DecodeFrom(d)
}
types.DecodeSlice(d, &r.Transactions)
}
func (r *RPCRelayV2TransactionSet) maxRequestLen() int { return 5e6 }

Expand Down
Loading

0 comments on commit 36ea9c7

Please sign in to comment.