diff --git a/go.mod b/go.mod index bff3e0b..df2638a 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ toolchain go1.22.3 require ( github.com/mattn/go-sqlite3 v1.14.22 - go.sia.tech/core v0.2.6 - go.sia.tech/coreutils v0.0.5 + go.sia.tech/core v0.2.7 + go.sia.tech/coreutils v0.0.6 go.sia.tech/jape v0.11.2-0.20240124024603-93559895d640 go.sia.tech/web/walletd v0.21.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index 12e50b3..16492a2 100644 --- a/go.sum +++ b/go.sum @@ -12,10 +12,10 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= -go.sia.tech/core v0.2.6 h1:JrbZwW4cPHCB2Q6TeqCsAj2GAFXrRqLq0q/GNevtnPU= -go.sia.tech/core v0.2.6/go.mod h1:B7ooFH3F6cLjxQz6IX33kgjOY392Ava7pzpPeccagac= -go.sia.tech/coreutils v0.0.5 h1:Jj03VrqAayYHgA9fwV13+X88WB+Wr1p8wuLw2B8d2FI= -go.sia.tech/coreutils v0.0.5/go.mod h1:SkSpHeq3tBh2ff4HXuBk2WtlhkYQQtdcvU4Yv1Rd2bU= +go.sia.tech/core v0.2.7 h1:9Q/3BHL6ziAMPeiko863hhTD/Zs2s7OqEUiPKouDny8= +go.sia.tech/core v0.2.7/go.mod h1:BMgT/reXtgv6XbDgUYTCPY7wSMbspDRDs7KMi1vL6Iw= +go.sia.tech/coreutils v0.0.6 h1:xLpv3JyvbOoXcX3gC6a6Y3zQ/MZn/fyFvuPIzv/e/Eg= +go.sia.tech/coreutils v0.0.6/go.mod h1:EiDcQk2qLuP32Qoj/XphY9fbjTXphJhJZMERoC4LF0c= go.sia.tech/jape v0.11.2-0.20240124024603-93559895d640 h1:mSaJ622P7T/M97dAK8iPV+IRIC9M5vV28NHeceoWO3M= go.sia.tech/jape v0.11.2-0.20240124024603-93559895d640/go.mod h1:4QqmBB+t3W7cNplXPj++ZqpoUb2PeiS66RLpXmEGap4= go.sia.tech/mux v1.2.0 h1:ofa1Us9mdymBbGMY2XH/lSpY8itFsKIo/Aq8zwe+GHU= diff --git a/persist/sqlite/consensus.go b/persist/sqlite/consensus.go index 8701c6f..048d03b 100644 --- a/persist/sqlite/consensus.go +++ b/persist/sqlite/consensus.go @@ -66,7 +66,7 @@ func (ut *updateTx) UpdateSiacoinStateElements(elements []types.StateElement) er for _, se := range elements { var dummy types.Hash256 - err := stmt.QueryRow(encodeSlice(se.MerkleProof), se.LeafIndex, encode(se.ID)).Scan(decode(&dummy)) + err := stmt.QueryRow(encode(se.MerkleProof), se.LeafIndex, encode(se.ID)).Scan(decode(&dummy)) if err != nil { return fmt.Errorf("failed to execute statement: %w", err) } @@ -112,7 +112,7 @@ func (ut *updateTx) UpdateSiafundStateElements(elements []types.StateElement) er for _, se := range elements { var dummy types.Hash256 - err := stmt.QueryRow(encodeSlice(se.MerkleProof), se.LeafIndex, encode(se.ID)).Scan(decode(&dummy)) + err := stmt.QueryRow(encode(se.MerkleProof), se.LeafIndex, encode(se.ID)).Scan(decode(&dummy)) if err != nil { return fmt.Errorf("failed to execute statement: %w", err) } @@ -320,7 +320,7 @@ func (s *Store) SetIndexMode(mode wallet.IndexMode) error { } func scanStateElement(s scanner) (se types.StateElement, err error) { - err = s.Scan(decode(&se.ID), &se.LeafIndex, decodeSlice(&se.MerkleProof)) + err = s.Scan(decode(&se.ID), &se.LeafIndex, decode(&se.MerkleProof)) return } @@ -534,7 +534,7 @@ func addSiacoinElements(tx *txn, elements []types.SiacoinElement, indexID int64, se.MerkleProof = nil } - _, err = insertStmt.Exec(encode(se.ID), encode(se.SiacoinOutput.Value), encodeSlice(se.MerkleProof), se.LeafIndex, se.MaturityHeight, addrRef.ID, se.MaturityHeight == 0, indexID) + _, err = insertStmt.Exec(encode(se.ID), encode(se.SiacoinOutput.Value), encode(se.MerkleProof), se.LeafIndex, se.MaturityHeight, addrRef.ID, se.MaturityHeight == 0, indexID) if err != nil { return fmt.Errorf("failed to execute statement: %w", err) } @@ -808,7 +808,7 @@ func addSiafundElements(tx *txn, elements []types.SiafundElement, indexID int64, se.MerkleProof = nil } - _, err = insertStmt.Exec(encode(se.ID), se.SiafundOutput.Value, encodeSlice(se.MerkleProof), se.LeafIndex, encode(se.ClaimStart), addrRef.ID, indexID) + _, err = insertStmt.Exec(encode(se.ID), se.SiafundOutput.Value, encode(se.MerkleProof), se.LeafIndex, encode(se.ClaimStart), addrRef.ID, indexID) if err != nil { return fmt.Errorf("failed to execute statement: %w", err) } else if exists { diff --git a/persist/sqlite/encoding.go b/persist/sqlite/encoding.go index 966c6b0..abe5ab9 100644 --- a/persist/sqlite/encoding.go +++ b/persist/sqlite/encoding.go @@ -19,6 +19,12 @@ func encode(obj any) any { binary.BigEndian.PutUint64(buf, obj.Hi) binary.BigEndian.PutUint64(buf[8:], obj.Lo) return buf + case []types.Hash256: + var buf bytes.Buffer + e := types.NewEncoder(&buf) + types.EncodeSlice(e, obj) + e.Flush() + return buf.Bytes() case types.EncoderTo: var buf bytes.Buffer e := types.NewEncoder(&buf) @@ -61,6 +67,9 @@ func (d *decodable) Scan(src any) error { return dec.Err() case *uint64: *v = binary.LittleEndian.Uint64(src) + case *[]types.Hash256: + dec := types.NewBufDecoder(src) + types.DecodeSlice(dec, v) default: return fmt.Errorf("cannot scan %T to %T", src, d.v) } @@ -83,46 +92,3 @@ func (d *decodable) Scan(src any) error { func decode(obj any) sql.Scanner { return &decodable{obj} } - -type decodableSlice[T any] struct { - v *[]T -} - -func (d *decodableSlice[T]) Scan(src any) error { - switch src := src.(type) { - case []byte: - dec := types.NewBufDecoder(src) - s := make([]T, dec.ReadPrefix()) - for i := range s { - dv, ok := any(&s[i]).(types.DecoderFrom) - if !ok { - panic(fmt.Errorf("cannot decode %T", s[i])) - } - dv.DecodeFrom(dec) - } - if err := dec.Err(); err != nil { - return err - } - *d.v = s - return nil - default: - return fmt.Errorf("cannot scan %T to []byte", src) - } -} - -func decodeSlice[T any](v *[]T) sql.Scanner { - return &decodableSlice[T]{v: v} -} - -func encodeSlice[T types.EncoderTo](v []T) []byte { - var buf bytes.Buffer - enc := types.NewEncoder(&buf) - enc.WritePrefix(len(v)) - for _, e := range v { - e.EncodeTo(enc) - } - if err := enc.Flush(); err != nil { - panic(err) - } - return buf.Bytes() -} diff --git a/persist/sqlite/wallet.go b/persist/sqlite/wallet.go index d596578..e78045f 100644 --- a/persist/sqlite/wallet.go +++ b/persist/sqlite/wallet.go @@ -578,12 +578,12 @@ func (s *Store) WalletUnconfirmedEvents(id wallet.ID, index types.ChainIndex, ti } func scanSiacoinElement(s scanner) (se types.SiacoinElement, err error) { - err = s.Scan(decode(&se.ID), decode(&se.SiacoinOutput.Value), decodeSlice(&se.MerkleProof), &se.LeafIndex, &se.MaturityHeight, decode(&se.SiacoinOutput.Address)) + err = s.Scan(decode(&se.ID), decode(&se.SiacoinOutput.Value), decode(&se.MerkleProof), &se.LeafIndex, &se.MaturityHeight, decode(&se.SiacoinOutput.Address)) return } func scanSiafundElement(s scanner) (se types.SiafundElement, err error) { - err = s.Scan(decode(&se.ID), &se.LeafIndex, decodeSlice(&se.MerkleProof), &se.SiafundOutput.Value, decode(&se.ClaimStart), decode(&se.SiafundOutput.Address)) + err = s.Scan(decode(&se.ID), &se.LeafIndex, decode(&se.MerkleProof), &se.SiafundOutput.Value, decode(&se.ClaimStart), decode(&se.SiafundOutput.Address)) return }