From 83868d3eedf7bf57fcd347c1bed98ccbcbe6bc6f Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Mon, 4 Nov 2019 11:03:11 -0800 Subject: [PATCH] fix serialization of paych vouchers --- chain/types/cbor_gen.go | 2 +- cli/client.go | 9 +- gen/main.go | 10 ++ go.mod | 2 +- go.sum | 4 +- node/impl/paych/paych.go | 4 +- paych/cbor_gen.go | 231 +++++++++++++++++++++++++++++++++++++++ paych/store.go | 19 ++-- 8 files changed, 259 insertions(+), 22 deletions(-) create mode 100644 paych/cbor_gen.go diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 9cf6ec913..ab63b28a1 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -5,7 +5,7 @@ import ( "io" "math" - "github.com/ipfs/go-cid" + cid "github.com/ipfs/go-cid" cbg "github.com/whyrusleeping/cbor-gen" xerrors "golang.org/x/xerrors" ) diff --git a/cli/client.go b/cli/client.go index 7f9771a3d..2ac4b3db3 100644 --- a/cli/client.go +++ b/cli/client.go @@ -229,11 +229,12 @@ var clientRetrieveCmd = &cli.Command{ order := offers[0].Order() order.Client = payer - err = api.ClientRetrieve(ctx, order, cctx.Args().Get(1)) - if err == nil { - fmt.Println("Success") + if err := api.ClientRetrieve(ctx, order, cctx.Args().Get(1)); err != nil { + return err } - return err + + fmt.Println("Success") + return nil }, } diff --git a/gen/main.go b/gen/main.go index 127336a0b..f7b4c68ef 100644 --- a/gen/main.go +++ b/gen/main.go @@ -9,6 +9,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/deals" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/paych" ) func main() { @@ -32,6 +33,15 @@ func main() { os.Exit(1) } + err = gen.WriteTupleEncodersToFile("./paych/cbor_gen.go", "paych", + paych.VoucherInfo{}, + paych.ChannelInfo{}, + ) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + /* err = gen.WriteTupleEncodersToFile("./chain/cbor_gen.go", "chain", chain.BlockSyncRequest{}, diff --git a/go.mod b/go.mod index 67f47edc4..4ad2e0779 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a github.com/stretchr/testify v1.4.0 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba - github.com/whyrusleeping/cbor-gen v0.0.0-20191001154818-b4b5288fcb86 + github.com/whyrusleeping/cbor-gen v0.0.0-20191104184210-9aa3672a465c github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/whyrusleeping/pubsub v0.0.0-20131020042734-02de8aa2db3d go.opencensus.io v0.22.0 diff --git a/go.sum b/go.sum index fd9e20aa9..518e5e1eb 100644 --- a/go.sum +++ b/go.sum @@ -628,8 +628,8 @@ github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba h1:X4n8JG2e2 github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba/go.mod h1:CHQnYnQUEPydYCwuy8lmTHfGmdw9TKrhWV0xLx8l0oM= github.com/whyrusleeping/cbor-gen v0.0.0-20190910031516-c1cbffdb01bb/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/cbor-gen v0.0.0-20190917003517-d78d67427694/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= -github.com/whyrusleeping/cbor-gen v0.0.0-20191001154818-b4b5288fcb86 h1:cE8mRdI9JQAheSlIAkjJIpdAOPjYOzxSADaro6LNHnY= -github.com/whyrusleeping/cbor-gen v0.0.0-20191001154818-b4b5288fcb86/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= +github.com/whyrusleeping/cbor-gen v0.0.0-20191104184210-9aa3672a465c h1:P3leakVQLSvS0b953QG0BcuoCul79KTNpHbE04Bxhmc= +github.com/whyrusleeping/cbor-gen v0.0.0-20191104184210-9aa3672a465c/go.mod h1:xdlJQaiqipF0HW+Mzpg7XRM3fWbGvfgFlcppuvlkIvY= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= diff --git a/node/impl/paych/paych.go b/node/impl/paych/paych.go index b89980a00..e4ae9e23f 100644 --- a/node/impl/paych/paych.go +++ b/node/impl/paych/paych.go @@ -162,12 +162,12 @@ func (a *PaychAPI) PaychVoucherCreate(ctx context.Context, pch address.Address, func (a *PaychAPI) paychVoucherCreate(ctx context.Context, pch address.Address, voucher types.SignedVoucher) (*types.SignedVoucher, error) { ci, err := a.PaychMgr.GetChannelInfo(pch) if err != nil { - return nil, err + return nil, xerrors.Errorf("get channel info: %w", err) } nonce, err := a.PaychMgr.NextNonceForLane(ctx, pch, voucher.Lane) if err != nil { - return nil, err + return nil, xerrors.Errorf("getting next nonce for lane: %w", err) } sv := &voucher diff --git a/paych/cbor_gen.go b/paych/cbor_gen.go new file mode 100644 index 000000000..5eac7c08e --- /dev/null +++ b/paych/cbor_gen.go @@ -0,0 +1,231 @@ +package paych + +import ( + "fmt" + "io" + + "github.com/filecoin-project/lotus/chain/types" + cbg "github.com/whyrusleeping/cbor-gen" + xerrors "golang.org/x/xerrors" +) + +/* This file was generated by github.com/whyrusleeping/cbor-gen */ + +var _ = xerrors.Errorf + +func (t *VoucherInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{130}); err != nil { + return err + } + + // t.t.Voucher (types.SignedVoucher) + if err := t.Voucher.MarshalCBOR(w); err != nil { + return err + } + + // t.t.Proof ([]uint8) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.Proof)))); err != nil { + return err + } + if _, err := w.Write(t.Proof); err != nil { + return err + } + return nil +} + +func (t *VoucherInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Voucher (types.SignedVoucher) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + t.Voucher = new(types.SignedVoucher) + if err := t.Voucher.UnmarshalCBOR(br); err != nil { + return err + } + } + + } + // t.t.Proof ([]uint8) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Proof: array too large (%d)", extra) + } + + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + t.Proof = make([]byte, extra) + if _, err := io.ReadFull(br, t.Proof); err != nil { + return err + } + return nil +} + +func (t *ChannelInfo) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write([]byte{134}); err != nil { + return err + } + + // t.t.Channel (address.Address) + if err := t.Channel.MarshalCBOR(w); err != nil { + return err + } + + // t.t.Control (address.Address) + if err := t.Control.MarshalCBOR(w); err != nil { + return err + } + + // t.t.Target (address.Address) + if err := t.Target.MarshalCBOR(w); err != nil { + return err + } + + // t.t.Direction (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.Direction)); err != nil { + return err + } + + // t.t.Vouchers ([]*paych.VoucherInfo) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajArray, uint64(len(t.Vouchers)))); err != nil { + return err + } + for _, v := range t.Vouchers { + if err := v.MarshalCBOR(w); err != nil { + return err + } + } + + // t.t.NextLane (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.NextLane)); err != nil { + return err + } + return nil +} + +func (t *ChannelInfo) UnmarshalCBOR(r io.Reader) error { + br := cbg.GetPeeker(r) + + maj, extra, err := cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 6 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.t.Channel (address.Address) + + { + + if err := t.Channel.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.Control (address.Address) + + { + + if err := t.Control.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.Target (address.Address) + + { + + if err := t.Target.UnmarshalCBOR(br); err != nil { + return err + } + + } + // t.t.Direction (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Direction = extra + // t.t.Vouchers ([]*paych.VoucherInfo) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if extra > 8192 { + return fmt.Errorf("t.Vouchers: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + if extra > 0 { + t.Vouchers = make([]*VoucherInfo, extra) + } + for i := 0; i < int(extra); i++ { + + var v VoucherInfo + if err := v.UnmarshalCBOR(br); err != nil { + return err + } + + t.Vouchers[i] = &v + } + + // t.t.NextLane (uint64) + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.NextLane = extra + return nil +} diff --git a/paych/store.go b/paych/store.go index cc78b4b5b..2b2c1e00d 100644 --- a/paych/store.go +++ b/paych/store.go @@ -1,6 +1,7 @@ package paych import ( + "bytes" "errors" "fmt" "strings" @@ -9,7 +10,6 @@ import ( "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" dsq "github.com/ipfs/go-datastore/query" - cbor "github.com/ipfs/go-ipld-cbor" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/address" @@ -19,11 +19,6 @@ import ( var ErrChannelNotTracked = errors.New("channel not tracked") -func init() { - cbor.RegisterCborType(VoucherInfo{}) - cbor.RegisterCborType(ChannelInfo{}) -} - type Store struct { lk sync.Mutex // TODO: this can be split per paych @@ -52,7 +47,7 @@ type ChannelInfo struct { Control address.Address Target address.Address - Direction int + Direction uint64 Vouchers []*VoucherInfo NextLane uint64 } @@ -64,12 +59,12 @@ func dskeyForChannel(addr address.Address) datastore.Key { func (ps *Store) putChannelInfo(ci *ChannelInfo) error { k := dskeyForChannel(ci.Channel) - b, err := cbor.DumpObject(ci) - if err != nil { + buf := new(bytes.Buffer) + if err := ci.MarshalCBOR(buf); err != nil { return err } - return ps.ds.Put(k, b) + return ps.ds.Put(k, buf.Bytes()) } func (ps *Store) getChannelInfo(addr address.Address) (*ChannelInfo, error) { @@ -84,7 +79,7 @@ func (ps *Store) getChannelInfo(addr address.Address) (*ChannelInfo, error) { } var ci ChannelInfo - if err := cbor.DecodeInto(b, &ci); err != nil { + if err := ci.UnmarshalCBOR(bytes.NewReader(b)); err != nil { return nil, err } @@ -161,7 +156,7 @@ func (ps *Store) findChan(filter func(*ChannelInfo) bool) (address.Address, erro return address.Undef, err } - if err := cbor.DecodeInto(res.Value, &ci); err != nil { + if err := ci.UnmarshalCBOR(bytes.NewReader(res.Value)); err != nil { return address.Undef, err }