From 1fc47eb7d861921032e89fcd850170bbc954ad54 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 17 Jul 2023 10:25:18 -0700 Subject: [PATCH] feat: vm: allow raw "cbor" in state and use the new go-multicodec 1. Switch to go-multicodec as the source of multicodec code information. This gives us a central, generated source of multicodec codes. 2. Use this library inside the VM and shapshot logic to consistently allow CBOR, in addition to DagCBOR. 3. Remove the hard-coded CBOR constant. --- chain/store/snapshot.go | 26 ++++++++++++++------------ chain/vm/vm.go | 24 +++++++++++++----------- go.mod | 2 +- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/chain/store/snapshot.go b/chain/store/snapshot.go index 92bc238a6..5e218fa36 100644 --- a/chain/store/snapshot.go +++ b/chain/store/snapshot.go @@ -15,7 +15,7 @@ import ( "github.com/ipld/go-car" carutil "github.com/ipld/go-car/util" carv2 "github.com/ipld/go-car/v2" - mh "github.com/multiformats/go-multihash" + "github.com/multiformats/go-multicodec" cbg "github.com/whyrusleeping/cbor-gen" "go.uber.org/atomic" "golang.org/x/sync/errgroup" @@ -369,14 +369,16 @@ func (s *walkScheduler) Wait() error { } func (s *walkScheduler) enqueueIfNew(task walkTask) { - if task.c.Prefix().MhType == mh.IDENTITY { + if multicodec.Code(task.c.Prefix().MhType) == multicodec.Identity { //log.Infow("ignored", "cid", todo.c.String()) return } - // This lets through RAW and CBOR blocks, the only two types that we - // end up writing to the exported CAR. - if task.c.Prefix().Codec != cid.Raw && task.c.Prefix().Codec != cid.DagCBOR { + // This lets through RAW, CBOR, and DagCBOR blocks, the only types that we end up writing to + // the exported CAR. + switch multicodec.Code(task.c.Prefix().Codec) { + case multicodec.Cbor, multicodec.DagCbor, multicodec.Raw: + default: //log.Infow("ignored", "cid", todo.c.String()) return } @@ -450,7 +452,8 @@ func (s *walkScheduler) processTask(t walkTask, workerN int) error { // We exported the ipld block. If it wasn't a CBOR block, there's nothing // else to do and we can bail out early as it won't have any links // etc. - if t.c.Prefix().Codec != cid.DagCBOR || t.c.Prefix().MhType == mh.IDENTITY { + if multicodec.Code(t.c.Prefix().Codec) != multicodec.DagCbor || + multicodec.Code(t.c.Prefix().MhType) == multicodec.Identity { return nil } @@ -683,14 +686,13 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe prefix := c.Prefix() // Don't include identity CIDs. - if prefix.MhType == mh.IDENTITY { + if multicodec.Code(prefix.MhType) == multicodec.Identity { continue } - // We only include raw and dagcbor, for now. - // Raw for "code" CIDs. - switch prefix.Codec { - case cid.Raw, cid.DagCBOR: + // We only include raw, cbor, and dagcbor, for now. + switch multicodec.Code(prefix.Codec) { + case multicodec.Cbor, multicodec.DagCbor, multicodec.Raw: default: continue } @@ -722,7 +724,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe } func recurseLinks(ctx context.Context, bs bstore.Blockstore, walked *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) { - if root.Prefix().Codec != cid.DagCBOR { + if multicodec.Code(root.Prefix().Codec) != multicodec.DagCbor { return in, nil } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 58afc14bc..d6973210c 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -11,7 +11,7 @@ import ( "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" logging "github.com/ipfs/go-log/v2" - mh "github.com/multiformats/go-multihash" + "github.com/multiformats/go-multicodec" cbg "github.com/whyrusleeping/cbor-gen" "go.opencensus.io/stats" "go.opencensus.io/trace" @@ -38,7 +38,6 @@ import ( ) const MaxCallDepth = 4096 -const CborCodec = 0x51 var ( log = logging.Logger("vm") @@ -128,7 +127,7 @@ func (bs *gasChargingBlocks) Put(ctx context.Context, blk block.Block) error { func (vm *LegacyVM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runtime) *Runtime { paramsCodec := uint64(0) if len(msg.Params) > 0 { - paramsCodec = CborCodec + paramsCodec = uint64(multicodec.Cbor) } rt := &Runtime{ ctx: ctx, @@ -385,7 +384,7 @@ func (vm *LegacyVM) send(ctx context.Context, msg *types.Message, parent *Runtim retCodec := uint64(0) if len(ret) > 0 { - retCodec = CborCodec + retCodec = uint64(multicodec.Cbor) } rt.executionTrace.MsgRct = types.ReturnTrace{ ExitCode: aerrors.RetCode(err), @@ -700,15 +699,15 @@ func (vm *LegacyVM) ActorStore(ctx context.Context) adt.Store { } func linksForObj(blk block.Block, cb func(cid.Cid)) error { - switch blk.Cid().Prefix().Codec { - case cid.DagCBOR: + switch multicodec.Code(blk.Cid().Prefix().Codec) { + case multicodec.DagCbor: err := cbg.ScanForLinks(bytes.NewReader(blk.RawData()), cb) if err != nil { return xerrors.Errorf("cbg.ScanForLinks: %w", err) } return nil - case cid.Raw: - // We implicitly have all children of raw blocks. + case multicodec.Raw, multicodec.Cbor: + // We implicitly have all children of raw/cbor blocks. return nil default: return xerrors.Errorf("vm flush copy method only supports dag cbor") @@ -808,14 +807,17 @@ func copyRec(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid, } prefix := link.Prefix() - if prefix.Codec == cid.FilCommitmentSealed || prefix.Codec == cid.FilCommitmentUnsealed { + codec := multicodec.Code(prefix.Codec) + switch codec { + case multicodec.FilCommitmentSealed, cid.FilCommitmentUnsealed: return } // We always have blocks inlined into CIDs, but we may not have their children. - if prefix.MhType == mh.IDENTITY { + if multicodec.Code(prefix.MhType) == multicodec.Identity { // Unless the inlined block has no children. - if prefix.Codec == cid.Raw { + switch codec { + case multicodec.Raw, multicodec.Cbor: return } } else { diff --git a/go.mod b/go.mod index 4ffd2d545..0ffacb94c 100644 --- a/go.mod +++ b/go.mod @@ -123,6 +123,7 @@ require ( github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.2.0 + github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 github.com/multiformats/go-varint v0.0.7 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 @@ -278,7 +279,6 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multicodec v0.9.0 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/nikkolasg/hexjson v0.1.0 // indirect github.com/nkovacs/streamquote v1.0.0 // indirect