@@ -2,18 +2,15 @@ package options
2
2
3
3
import (
4
4
"fmt"
5
+
5
6
cid "github.com/ipfs/go-cid"
6
7
mc "github.com/multiformats/go-multicodec"
7
8
mh "github.com/multiformats/go-multihash"
8
9
)
9
10
10
11
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
17
14
}
18
15
19
16
type BlockRmSettings struct {
@@ -23,70 +20,29 @@ type BlockRmSettings struct {
23
20
type BlockPutOption func (* BlockPutSettings ) error
24
21
type BlockRmOption func (* BlockRmSettings ) error
25
22
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
+
27
32
options := & BlockPutSettings {
28
- Codec : "" ,
29
- StoreCodec : "" ,
30
- MhType : mh .SHA2_256 ,
31
- MhLength : - 1 ,
32
- Pin : false ,
33
+ CidPrefix : cidPrefix ,
34
+ Pin : false ,
33
35
}
34
36
37
+ // Apply any overrides
35
38
for _ , opt := range opts {
36
39
err := opt (options )
37
40
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
78
42
}
79
- pref .Codec = uint64 (storeCodec )
80
43
}
81
44
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
90
46
}
91
47
92
48
func BlockRmOptions (opts ... BlockRmOption ) (* BlockRmSettings , error ) {
@@ -107,31 +63,84 @@ type blockOpts struct{}
107
63
108
64
var Block blockOpts
109
65
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 {
113
70
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 )
115
79
return nil
116
80
}
117
81
}
118
82
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 {
122
94
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
+
124
132
return nil
125
133
}
134
+
126
135
}
127
136
128
137
// Hash is an option for Block.Put which specifies the multihash settings to use
129
138
// when hashing the object. Default is mh.SHA2_256 (0x12).
130
139
// If mhLen is set to -1, default length for the hash will be used
131
140
func (blockOpts ) Hash (mhType uint64 , mhLen int ) BlockPutOption {
132
141
return func (settings * BlockPutSettings ) error {
133
- settings .MhType = mhType
134
- settings .MhLength = mhLen
142
+ settings .CidPrefix . MhType = mhType
143
+ settings .CidPrefix . MhLength = mhLen
135
144
return nil
136
145
}
137
146
}
0 commit comments