Skip to content
This repository was archived by the owner on Jun 19, 2023. It is now read-only.

Commit a6eb015

Browse files
committed
refactor: BlockPutSettings.CidPrefix
Removes duplicated fields and replaces them with cid.Prefix Codec, MhType and MhLength were already in prefix, and we already return prefix. A lot of duplicated values and code responsible for syncing them did not really need to exist.
1 parent 16bad39 commit a6eb015

File tree

2 files changed

+154
-80
lines changed

2 files changed

+154
-80
lines changed

options/block.go

+80-71
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ package options
22

33
import (
44
"fmt"
5+
56
cid "github.com/ipfs/go-cid"
67
mc "github.com/multiformats/go-multicodec"
78
mh "github.com/multiformats/go-multihash"
89
)
910

1011
type BlockPutSettings struct {
11-
StoreCodec string
12-
// FIXME: Rename to Format (and possibly mark as deprecated).
13-
Codec string
14-
MhType uint64
15-
MhLength int
16-
Pin bool
12+
CidPrefix cid.Prefix
13+
Pin bool
1714
}
1815

1916
type BlockRmSettings struct {
@@ -23,70 +20,29 @@ type BlockRmSettings struct {
2320
type BlockPutOption func(*BlockPutSettings) error
2421
type BlockRmOption func(*BlockRmSettings) error
2522

26-
func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, error) {
23+
func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, error) {
24+
var cidPrefix cid.Prefix
25+
26+
// Baseline is CIDv1 raw sha2-255-32 (can be tweaked later via opts)
27+
cidPrefix.Version = 1
28+
cidPrefix.Codec = uint64(mc.Raw)
29+
cidPrefix.MhType = mh.SHA2_256
30+
cidPrefix.MhLength = -1 // -1 means len is to be calculated during mh.Sum()
31+
2732
options := &BlockPutSettings{
28-
Codec: "",
29-
StoreCodec: "",
30-
MhType: mh.SHA2_256,
31-
MhLength: -1,
32-
Pin: false,
33+
CidPrefix: cidPrefix,
34+
Pin: false,
3335
}
3436

37+
// Apply any overrides
3538
for _, opt := range opts {
3639
err := opt(options)
3740
if err != nil {
38-
return nil, cid.Prefix{}, err
39-
}
40-
}
41-
42-
if options.Codec != "" && options.StoreCodec != "" {
43-
return nil, cid.Prefix{}, fmt.Errorf("incompatible format (%s) and store-codec options set (%s)",
44-
options.Codec, options.StoreCodec)
45-
}
46-
47-
if options.Codec == "" && options.StoreCodec == "" {
48-
// FIXME(BLOCKING): Do we keep the old default v0 here?
49-
options.Codec = "v0"
50-
// FIXME(BLOCKING): Review how to handle "protobuf". For now we simplify the code only with "v0".
51-
}
52-
53-
var pref cid.Prefix
54-
pref.Version = 1
55-
56-
// Old format option.
57-
if options.Codec != "" {
58-
if options.Codec == "v0" {
59-
if options.MhType != mh.SHA2_256 || (options.MhLength != -1 && options.MhLength != 32) {
60-
return nil, cid.Prefix{}, fmt.Errorf("only sha2-255-32 is allowed with CIDv0")
61-
}
62-
pref.Version = 0
63-
}
64-
65-
// FIXME(BLOCKING): Do we actually want to consult the CID codecs table
66-
// even with the old --format options? Or do we always want to check
67-
// the multicodec one?
68-
cidCodec, ok := cid.Codecs[options.Codec]
69-
if !ok {
70-
return nil, cid.Prefix{}, fmt.Errorf("unrecognized format: %s", options.Codec)
71-
}
72-
pref.Codec = cidCodec
73-
} else {
74-
// New store-codec options. We handle it as it's done for `ipfs dag put`.
75-
var storeCodec mc.Code
76-
if err := storeCodec.Set(options.StoreCodec); err != nil {
77-
return nil, cid.Prefix{}, err
41+
return nil, err
7842
}
79-
pref.Codec = uint64(storeCodec)
8043
}
8144

82-
// FIXME: The entire codec manipulation/validation needs to be encapsulated
83-
// outside this funtion to clearly demark that it is the only option we are
84-
// overwriting here.
85-
86-
pref.MhType = options.MhType
87-
pref.MhLength = options.MhLength
88-
89-
return options, pref, nil
45+
return options, nil
9046
}
9147

9248
func BlockRmOptions(opts ...BlockRmOption) (*BlockRmSettings, error) {
@@ -107,31 +63,84 @@ type blockOpts struct{}
10763

10864
var Block blockOpts
10965

110-
// Format is an option for Block.Put which specifies the multicodec to use to
111-
// serialize the object. Default is "v0"
112-
func (blockOpts) Format(codec string) BlockPutOption {
66+
// CidCodec is the modern option for Block.Put which specifies the multicodec to use
67+
// in the CID returned by the Block.Put operation.
68+
// It uses correct codes from go-multicodec and replaces the old Format now with CIDv1 as the default.
69+
func (blockOpts) CidCodec(codecName string) BlockPutOption {
11370
return func(settings *BlockPutSettings) error {
114-
settings.Codec = codec
71+
if codecName == "" {
72+
return nil
73+
}
74+
code, err := codeFromName(codecName)
75+
if err != nil {
76+
return err
77+
}
78+
settings.CidPrefix.Codec = uint64(code)
11579
return nil
11680
}
11781
}
11882

119-
// StoreCodec is an option for Block.Put which specifies the multicodec to use to
120-
// serialize the object. It replaces the old Format now with CIDv1 as the default.
121-
func (blockOpts) StoreCodec(storeCodec string) BlockPutOption {
83+
// Map string to code from go-multicodec
84+
func codeFromName(codecName string) (mc.Code, error) {
85+
var cidCodec mc.Code
86+
err := cidCodec.Set(codecName)
87+
return cidCodec, err
88+
}
89+
90+
// Format is a legacy option for Block.Put which specifies the multicodec to
91+
// use to serialize the object.
92+
// Provided for backward-compatibility only. Use CidCodec instead.
93+
func (blockOpts) Format(format string) BlockPutOption {
12294
return func(settings *BlockPutSettings) error {
123-
settings.StoreCodec = storeCodec
95+
if format == "" {
96+
return nil
97+
}
98+
// Opt-in CIDv0 support for backward-compatibility
99+
if format == "v0" {
100+
settings.CidPrefix.Version = 0
101+
}
102+
103+
// Fixup a legacy (invalid) names for dag-pb (0x70)
104+
if format == "v0" || format == "protobuf" {
105+
format = "dag-pb"
106+
}
107+
108+
// Fixup invalid name for dag-cbor (0x71)
109+
if format == "cbor" {
110+
format = "dag-cbor"
111+
}
112+
113+
// Set code based on name passed as "format"
114+
code, err := codeFromName(format)
115+
if err != nil {
116+
return err
117+
}
118+
settings.CidPrefix.Codec = uint64(code)
119+
120+
// If CIDv0, ensure all parameters are compatible
121+
// (in theory go-cid would validate this anyway, but we want to provide better errors)
122+
pref := settings.CidPrefix
123+
if pref.Version == 0 {
124+
if pref.Codec != uint64(mc.DagPb) {
125+
return fmt.Errorf("only dag-pb is allowed with CIDv0")
126+
}
127+
if pref.MhType != mh.SHA2_256 || (pref.MhLength != -1 && pref.MhLength != 32) {
128+
return fmt.Errorf("only sha2-255-32 is allowed with CIDv0")
129+
}
130+
}
131+
124132
return nil
125133
}
134+
126135
}
127136

128137
// Hash is an option for Block.Put which specifies the multihash settings to use
129138
// when hashing the object. Default is mh.SHA2_256 (0x12).
130139
// If mhLen is set to -1, default length for the hash will be used
131140
func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption {
132141
return func(settings *BlockPutSettings) error {
133-
settings.MhType = mhType
134-
settings.MhLength = mhLen
142+
settings.CidPrefix.MhType = mhType
143+
settings.CidPrefix.MhLength = mhLen
135144
return nil
136145
}
137146
}

tests/block.go

+74-9
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ import (
1717
)
1818

1919
var (
20-
pbCid = "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN"
21-
cborCid = "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm"
22-
cborKCid = "bafyr2qgsohbwdlk7ajmmbb4lhoytmest4wdbe5xnexfvtxeatuyqqmwv3fgxp3pmhpc27gwey2cct56gloqefoqwcf3yqiqzsaqb7p4jefhcw"
20+
pbCidV0 = "QmZULkCELmmk5XNfCgTnCyFgAVxBRBXyDHGGMVoLFLiXEN" // dag-pb
21+
pbCid = "bafybeiffndsajwhk3lwjewwdxqntmjm4b5wxaaanokonsggenkbw6slwk4" // dag-pb
22+
cborCid = "bafyreicnga62zhxnmnlt6ymq5hcbsg7gdhqdu6z4ehu3wpjhvqnflfy6nm" // dag-cbor
23+
cborKCid = "bafyr2qgsohbwdlk7ajmmbb4lhoytmest4wdbe5xnexfvtxeatuyqqmwv3fgxp3pmhpc27gwey2cct56gloqefoqwcf3yqiqzsaqb7p4jefhcw" // dag-cbor keccak-512
2324
)
2425

26+
// dag-pb
2527
func pbBlock() io.Reader {
2628
return bytes.NewReader([]byte{10, 12, 8, 2, 18, 6, 104, 101, 108, 108, 111, 10, 24, 6})
2729
}
2830

31+
// dag-cbor
2932
func cborBlock() io.Reader {
3033
return bytes.NewReader([]byte{101, 72, 101, 108, 108, 111})
3134
}
@@ -39,8 +42,10 @@ func (tp *TestSuite) TestBlock(t *testing.T) {
3942
})
4043

4144
t.Run("TestBlockPut", tp.TestBlockPut)
42-
t.Run("TestBlockPutFormat", tp.TestBlockPutFormat)
43-
t.Run("TestBlockPutStoreCodec", tp.TestBlockPutStoreCodec)
45+
t.Run("TestBlockPutCidCodec: dag-cbor", tp.TestBlockPutCidCodecDagCbor)
46+
t.Run("TestBlockPutFormat (legacy): cbor → dag-cbor", tp.TestBlockPutFormatDagCbor)
47+
t.Run("TestBlockPutFormat (legacy): protobuf → dag-pb", tp.TestBlockPutFormatDagPb)
48+
t.Run("TestBlockPutFormat (legacy): v0 → CIDv0", tp.TestBlockPutFormatV0)
4449
t.Run("TestBlockPutHash", tp.TestBlockPutHash)
4550
t.Run("TestBlockGet", tp.TestBlockGet)
4651
t.Run("TestBlockRm", tp.TestBlockRm)
@@ -66,7 +71,9 @@ func (tp *TestSuite) TestBlockPut(t *testing.T) {
6671
}
6772
}
6873

69-
func (tp *TestSuite) TestBlockPutFormat(t *testing.T) {
74+
// Format is deprecated, it used invalid codec names.
75+
// Confirm 'cbor' gets fixed to 'dag-cbor'
76+
func (tp *TestSuite) TestBlockPutFormatDagCbor(t *testing.T) {
7077
ctx, cancel := context.WithCancel(context.Background())
7178
defer cancel()
7279
api, err := tp.makeAPI(ctx)
@@ -84,15 +91,55 @@ func (tp *TestSuite) TestBlockPutFormat(t *testing.T) {
8491
}
8592
}
8693

87-
func (tp *TestSuite) TestBlockPutStoreCodec(t *testing.T) {
94+
// Format is deprecated, it used invalid codec names.
95+
// Confirm 'protobuf' got fixed to 'dag-pb'
96+
func (tp *TestSuite) TestBlockPutFormatDagPb(t *testing.T) {
8897
ctx, cancel := context.WithCancel(context.Background())
8998
defer cancel()
9099
api, err := tp.makeAPI(ctx)
91100
if err != nil {
92101
t.Fatal(err)
93102
}
94103

95-
res, err := api.Block().Put(ctx, cborBlock(), opt.Block.StoreCodec("dag-cbor"))
104+
res, err := api.Block().Put(ctx, pbBlock(), opt.Block.Format("protobuf"))
105+
if err != nil {
106+
t.Fatal(err)
107+
}
108+
109+
if res.Path().Cid().String() != pbCid {
110+
t.Errorf("got wrong cid: %s", res.Path().Cid().String())
111+
}
112+
}
113+
114+
// Format is deprecated, it used invalid codec names.
115+
// Confirm fake codec 'v0' got fixed to CIDv0 (with implicit dag-pb codec)
116+
func (tp *TestSuite) TestBlockPutFormatV0(t *testing.T) {
117+
ctx, cancel := context.WithCancel(context.Background())
118+
defer cancel()
119+
api, err := tp.makeAPI(ctx)
120+
if err != nil {
121+
t.Fatal(err)
122+
}
123+
124+
res, err := api.Block().Put(ctx, pbBlock(), opt.Block.Format("v0"))
125+
if err != nil {
126+
t.Fatal(err)
127+
}
128+
129+
if res.Path().Cid().String() != pbCidV0 {
130+
t.Errorf("got wrong cid: %s", res.Path().Cid().String())
131+
}
132+
}
133+
134+
func (tp *TestSuite) TestBlockPutCidCodecDagCbor(t *testing.T) {
135+
ctx, cancel := context.WithCancel(context.Background())
136+
defer cancel()
137+
api, err := tp.makeAPI(ctx)
138+
if err != nil {
139+
t.Fatal(err)
140+
}
141+
142+
res, err := api.Block().Put(ctx, cborBlock(), opt.Block.CidCodec("dag-cbor"))
96143
if err != nil {
97144
t.Fatal(err)
98145
}
@@ -102,6 +149,24 @@ func (tp *TestSuite) TestBlockPutStoreCodec(t *testing.T) {
102149
}
103150
}
104151

152+
func (tp *TestSuite) TestBlockPutCidCodecDagPb(t *testing.T) {
153+
ctx, cancel := context.WithCancel(context.Background())
154+
defer cancel()
155+
api, err := tp.makeAPI(ctx)
156+
if err != nil {
157+
t.Fatal(err)
158+
}
159+
160+
res, err := api.Block().Put(ctx, pbBlock(), opt.Block.CidCodec("dag-pb"))
161+
if err != nil {
162+
t.Fatal(err)
163+
}
164+
165+
if res.Path().Cid().String() != pbCid {
166+
t.Errorf("got wrong cid: %s", res.Path().Cid().String())
167+
}
168+
}
169+
105170
func (tp *TestSuite) TestBlockPutHash(t *testing.T) {
106171
ctx, cancel := context.WithCancel(context.Background())
107172
defer cancel()
@@ -114,7 +179,7 @@ func (tp *TestSuite) TestBlockPutHash(t *testing.T) {
114179
ctx,
115180
cborBlock(),
116181
opt.Block.Hash(mh.KECCAK_512, -1),
117-
opt.Block.Format("cbor"),
182+
opt.Block.CidCodec("dag-cbor"),
118183
)
119184
if err != nil {
120185
t.Fatal(err)

0 commit comments

Comments
 (0)