Compare commits

...

53 Commits

Author SHA1 Message Date
Kevin Atkinson
afcde25c66 gx publish 0.8.0 2018-08-21 15:15:34 -04:00
Kevin Atkinson
fb85ebd768 Merge pull request #69 from ipfs/kevina/extract
Extract non-core functionality from go-cid into go-cidutil
2018-08-21 15:11:14 -04:00
Kevin Atkinson
870aa9e7de Extract non-core functionality from go-cid into go-cidutil. 2018-08-16 21:51:31 -04:00
Steven Allen
73e5246a65 gx publish 0.7.25 2018-08-15 08:24:56 -07:00
Steven Allen
83a7594d41 Merge pull request #67 from ipfs/feat/streaming-set
add a streaming CID set
2018-08-11 01:06:53 +00:00
Łukasz Magiera
3655c1cdd4 add a streaming CID set
used in https://github.com/ipfs/go-ipfs/pull/4804
2018-08-10 17:32:43 -07:00
Steven Allen
1543f4a136 Merge pull request #44 from ipfs/feat/bench
add String benchmark
2018-08-10 23:55:30 +00:00
Steven Allen
d6e0b4e5a7 add String benchmark
We call String all over the place so we should make sure it remains fast.
2018-08-10 16:23:25 -07:00
Kevin Atkinson
5eff744da0 gx publish 0.7.24 2018-08-10 17:40:00 -04:00
Kevin Atkinson
a8ae38caae Merge pull request #61 from ipfs/kevina/cid-fmt-enhan
cid-fmt Enhancments
2018-08-10 17:35:25 -04:00
Kevin Atkinson
23f03cb301 Merge pull request #53 from ipfs/kevina/format
Create new Builder interface for creating CIDs.
2018-08-10 17:34:56 -04:00
Kevin Atkinson
1c907dba61 Allocate bytes.Buffer directly on the stack. 2018-08-10 17:27:58 -04:00
Kevin Atkinson
86805e711c Change field names in V1Builder to match Prefix. 2018-08-10 00:13:49 -04:00
Kevin Atkinson
f868375825 Enhance Tests. 2018-08-09 23:55:45 -04:00
Kevin Atkinson
8f7ba15bfb Documentation Cleanups. 2018-08-09 23:55:33 -04:00
Kevin Atkinson
ae25e25d1a Remove PrefixToBuilder as it is needed right now. 2018-08-09 23:14:37 -04:00
Kevin Atkinson
0f09109d9f Replace DecodeV2 with ExtractEncoding 2018-08-09 02:37:09 -04:00
Kevin Atkinson
67951e2c09 Move deprecated function to there own file. 2018-08-09 00:15:04 -04:00
Kevin Atkinson
ad88cb11c5 Rename Format to Builder. 2018-08-09 00:15:04 -04:00
Steven Allen
10944c9d86 Merge pull request #63 from ipfs/tests/set
Add tests for Set type
2018-08-02 19:25:20 +00:00
Hector Sanjuan
b340dd202e Add tests for Set type
License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
2018-08-02 11:51:05 +02:00
Kevin Atkinson
c4bfcd0671 Extract most of cid-fmt logic so it can be used as a library. 2018-08-01 04:21:32 -04:00
Kevin Atkinson
36bab4873c Clean up cid-fmt util code. 2018-07-31 22:10:47 -04:00
Kevin Atkinson
056eac16ae Fix fmtRef string. 2018-07-31 17:12:16 -04:00
Kevin Atkinson
038b7f7cc9 Use new Encoder in multibase package.
This allows multibase codes to be specified by the name rather than just
the prefix char.
2018-07-31 17:07:49 -04:00
Kevin Atkinson
019d945bf5 Use lookup table in go-multibase now that it is supported. 2018-07-31 16:33:41 -04:00
Kevin Atkinson
799731b9e5 gx update go-multibase to 0.2.7 2018-07-31 16:33:41 -04:00
Hector Sanjuan
06f861b665 Merge pull request #59 from ipfs/0.7.23
gx publish 0.7.23
2018-07-28 00:44:12 +02:00
Kevin Atkinson
88cd5dcebf Add WithCodec and GetCodec methods to format interface. 2018-07-24 22:28:19 -04:00
Hector Sanjuan
9949dd29e5 gx publish 0.7.23
License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
2018-07-24 11:09:24 +02:00
Steven Allen
75d3ffe549 Merge pull request #58 from ipfs/feat/decred-codec
Add Decred codecs
2018-07-23 18:57:13 +00:00
Hector Sanjuan
8028fee095 Add Decred codecs
0xe0 and 0xe1 have been assigned to Decred block and tx in the
multicodecs table. https://github.com/multiformats/multicodec/pull/78

License: MIT
Signed-off-by: Hector Sanjuan <hector@protocol.ai>
2018-07-23 19:28:53 +02:00
Steven Allen
bd441bb43e gx publish 0.7.22 2018-07-12 10:21:27 +02:00
Steven Allen
10a4d040b4 Merge pull request #55 from ipfs/bug/marshal
Use value receiver for MarshalJSON so we can marshal values
2018-07-12 08:19:51 +00:00
Fritz Schneider
d204c18f7a make test a little more clear 2018-07-11 11:24:59 -10:00
Fritz Schneider
b41162260a fix typo 2018-07-11 11:21:16 -10:00
Fritz Schneider
9cb0b7bcae use value receiver 2018-07-11 11:20:53 -10:00
Kevin Atkinson
6f951560f5 Update deprecated note to reflect code review. 2018-06-28 23:08:17 -04:00
Kevin Atkinson
5d8ad3eb9c Create new Format interface for creating CIDs. 2018-06-28 22:48:56 -04:00
Steven Allen
5b04f30433 gx publish 0.7.21 2018-06-08 20:25:20 -07:00
Steven Allen
078355866b gx publish 0.7.20 2018-01-19 20:51:37 -08:00
Steven Allen
1805dd530f gx publish 0.7.19 2017-12-05 00:06:03 +00:00
Steven Allen
2055d2e652 Merge pull request #36 from ipfs/feat/cid-prefix-constructors
Add CID Prefix constructors.
2017-09-07 11:35:56 -07:00
Steven Allen
63d4b33fcf Add CID Prefix constructors.
One can now generate a CID by calling:

```go
cid.NewPrefixV1(cid.DagCBOR, mh.SHA_256).Sum(data)
```

Lots of code was already doing this by manually constructing CID Prefixes but
that tends to be a bit verbose and error prone.
2017-08-30 12:42:46 -07:00
Steven Allen
19c1c0e32e gx publish 0.7.18 2017-08-28 20:25:09 -07:00
Steven Allen
088f141a17 Merge pull request #33 from ipfs/gx/update-multibase
gx: update multibase
2017-08-28 20:22:53 -07:00
Steven Allen
758714796c gx: update multibase
And fix test case.
2017-08-28 20:17:55 -07:00
Steven Allen
ed3563b69e Merge pull request #31 from ipfs/kevina/cid-fmt
Implement 'cid-fmt' utility.
2017-08-28 16:56:05 -07:00
Kevin Atkinson
db11d7248a Use an exit code of 1 on non-fatal errors and 2 on fatal errors. 2017-08-15 17:23:44 -04:00
Kevin Atkinson
68abb41a9b Add ability to change CID version. 2017-08-15 15:34:15 -04:00
Kevin Atkinson
7333c60a00 Implement 'cid-fmt' utility. 2017-08-15 14:26:24 -04:00
Kevin Atkinson
f62e35b87a Implement basic 'cid-fmt' utility.
Currently only implements printing the Cid prefix.
2017-08-15 03:46:48 -04:00
Jeromy Johnson
5652e6f751 Merge pull request #29 from Stebalien/gx/publish-0.7.17
gx publish 0.7.17
2017-07-10 12:45:42 -07:00
9 changed files with 448 additions and 7 deletions

View File

@@ -1 +1 @@
0.7.17: QmTprEaAA2A9bst5XH7exuyi5KzNMK3SEDNN8rBDnKWcUS
0.8.0: QmZFbDTY9jfSBms2MchvYM9oYRbAF19K7Pby47yDBfpPrb

74
builder.go Normal file
View File

@@ -0,0 +1,74 @@
package cid
import (
mh "github.com/multiformats/go-multihash"
)
type Builder interface {
Sum(data []byte) (*Cid, error)
GetCodec() uint64
WithCodec(uint64) Builder
}
type V0Builder struct{}
type V1Builder struct {
Codec uint64
MhType uint64
MhLength int // MhLength <= 0 means the default length
}
func (p Prefix) GetCodec() uint64 {
return p.Codec
}
func (p Prefix) WithCodec(c uint64) Builder {
if c == p.Codec {
return p
}
p.Codec = c
if c != DagProtobuf {
p.Version = 1
}
return p
}
func (p V0Builder) Sum(data []byte) (*Cid, error) {
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
return nil, err
}
return NewCidV0(hash), nil
}
func (p V0Builder) GetCodec() uint64 {
return DagProtobuf
}
func (p V0Builder) WithCodec(c uint64) Builder {
if c == DagProtobuf {
return p
}
return V1Builder{Codec: c, MhType: mh.SHA2_256}
}
func (p V1Builder) Sum(data []byte) (*Cid, error) {
mhLen := p.MhLength
if mhLen <= 0 {
mhLen = -1
}
hash, err := mh.Sum(data, p.MhType, mhLen)
if err != nil {
return nil, err
}
return NewCidV1(p.Codec, hash), nil
}
func (p V1Builder) GetCodec() uint64 {
return p.Codec
}
func (p V1Builder) WithCodec(c uint64) Builder {
p.Codec = c
return p
}

92
builder_test.go Normal file
View File

@@ -0,0 +1,92 @@
package cid
import (
"testing"
mh "github.com/multiformats/go-multihash"
)
func TestV0Builder(t *testing.T) {
data := []byte("this is some test content")
// Construct c1
format := V0Builder{}
c1, err := format.Sum(data)
if err != nil {
t.Fatal(err)
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
t.Fatal(err)
}
c2 := NewCidV0(hash)
if !c1.Equals(c2) {
t.Fatal("cids mismatch")
}
if c1.Prefix() != c2.Prefix() {
t.Fatal("prefixes mismatch")
}
}
func TestV1Builder(t *testing.T) {
data := []byte("this is some test content")
// Construct c1
format := V1Builder{Codec: DagCBOR, MhType: mh.SHA2_256}
c1, err := format.Sum(data)
if err != nil {
t.Fatal(err)
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
t.Fatal(err)
}
c2 := NewCidV1(DagCBOR, hash)
if !c1.Equals(c2) {
t.Fatal("cids mismatch")
}
if c1.Prefix() != c2.Prefix() {
t.Fatal("prefixes mismatch")
}
}
func TestCodecChange(t *testing.T) {
t.Run("Prefix-CidV0", func(t *testing.T) {
p := Prefix{Version: 0, Codec: DagProtobuf, MhType: mh.SHA2_256, MhLength: mh.DefaultLengths[mh.SHA2_256]}
testCodecChange(t, p)
})
t.Run("Prefix-CidV1", func(t *testing.T) {
p := Prefix{Version: 1, Codec: DagProtobuf, MhType: mh.SHA2_256, MhLength: mh.DefaultLengths[mh.SHA2_256]}
testCodecChange(t, p)
})
t.Run("V0Builder", func(t *testing.T) {
testCodecChange(t, V0Builder{})
})
t.Run("V1Builder", func(t *testing.T) {
testCodecChange(t, V1Builder{Codec: DagProtobuf, MhType: mh.SHA2_256})
})
}
func testCodecChange(t *testing.T, b Builder) {
data := []byte("this is some test content")
if b.GetCodec() != DagProtobuf {
t.Fatal("original builder not using Protobuf codec")
}
b = b.WithCodec(Raw)
c, err := b.Sum(data)
if err != nil {
t.Fatal(err)
}
if c.Type() != Raw {
t.Fatal("new cid codec did not change to Raw")
}
}

53
cid.go
View File

@@ -77,6 +77,8 @@ const (
BitcoinTx = 0xb1
ZcashBlock = 0xc0
ZcashTx = 0xc1
DecredBlock = 0xe0
DecredTx = 0xe1
)
// Codecs maps the name of a codec to its type
@@ -99,6 +101,31 @@ var Codecs = map[string]uint64{
"bitcoin-tx": BitcoinTx,
"zcash-block": ZcashBlock,
"zcash-tx": ZcashTx,
"decred-block": DecredBlock,
"decred-tx": DecredTx,
}
// CodecToStr maps the numeric codec to its name
var CodecToStr = map[uint64]string{
Raw: "raw",
DagProtobuf: "protobuf",
DagCBOR: "cbor",
GitRaw: "git-raw",
EthBlock: "eth-block",
EthBlockList: "eth-block-list",
EthTxTrie: "eth-tx-trie",
EthTx: "eth-tx",
EthTxReceiptTrie: "eth-tx-receipt-trie",
EthTxReceipt: "eth-tx-receipt",
EthStateTrie: "eth-state-trie",
EthAccountSnapshot: "eth-account-snapshot",
EthStorageTrie: "eth-storage-trie",
BitcoinBlock: "bitcoin-block",
BitcoinTx: "bitcoin-tx",
ZcashBlock: "zcash-block",
ZcashTx: "zcash-tx",
DecredBlock: "decred-block",
DecredTx: "decred-tx",
}
// NewCidV0 returns a Cid-wrapped multihash.
@@ -186,6 +213,28 @@ func Decode(v string) (*Cid, error) {
return Cast(data)
}
// Extract the encoding from a Cid. If Decode on the same string did
// not return an error neither will this function.
func ExtractEncoding(v string) (mbase.Encoding, error) {
if len(v) < 2 {
return -1, ErrCidTooShort
}
if len(v) == 46 && v[:2] == "Qm" {
return mbase.Base58BTC, nil
}
encoding := mbase.Encoding(v[0])
// check encoding is valid
_, err := mbase.NewEncoder(encoding)
if err != nil {
return -1, err
}
return encoding, nil
}
func uvError(read int) error {
switch {
case read == 0:
@@ -368,7 +417,7 @@ func (c *Cid) UnmarshalJSON(b []byte) error {
//
// Note that this formatting comes from the IPLD specification
// (https://github.com/ipld/specs/tree/master/ipld)
func (c *Cid) MarshalJSON() ([]byte, error) {
func (c Cid) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("{\"/\":\"%s\"}", c.String())), nil
}
@@ -400,6 +449,8 @@ func (c *Cid) Prefix() Prefix {
// that is, the Version, the Codec, the Multihash type
// and the Multihash length. It does not contains
// any actual content information.
// NOTE: The use -1 in MhLength to mean default length is deprecated,
// use the V0Builder or V1Builder structures instead
type Prefix struct {
Version uint64
Codec uint64

View File

@@ -33,6 +33,8 @@ var tCodecs = map[uint64]string{
BitcoinTx: "bitcoin-tx",
ZcashBlock: "zcash-block",
ZcashTx: "zcash-tx",
DecredBlock: "decred-block",
DecredTx: "decred-tx",
}
func assertEqual(t *testing.T, a, b *Cid) {
@@ -189,6 +191,64 @@ func TestV0ErrorCases(t *testing.T) {
}
}
func TestNewPrefixV1(t *testing.T) {
data := []byte("this is some test content")
// Construct c1
prefix := NewPrefixV1(DagCBOR, mh.SHA2_256)
c1, err := prefix.Sum(data)
if err != nil {
t.Fatal(err)
}
if c1.Prefix() != prefix {
t.Fatal("prefix not preserved")
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
t.Fatal(err)
}
c2 := NewCidV1(DagCBOR, hash)
if !c1.Equals(c2) {
t.Fatal("cids mismatch")
}
if c1.Prefix() != c2.Prefix() {
t.Fatal("prefixes mismatch")
}
}
func TestNewPrefixV0(t *testing.T) {
data := []byte("this is some test content")
// Construct c1
prefix := NewPrefixV0(mh.SHA2_256)
c1, err := prefix.Sum(data)
if err != nil {
t.Fatal(err)
}
if c1.Prefix() != prefix {
t.Fatal("prefix not preserved")
}
// Construct c2
hash, err := mh.Sum(data, mh.SHA2_256, -1)
if err != nil {
t.Fatal(err)
}
c2 := NewCidV0(hash)
if !c1.Equals(c2) {
t.Fatal("cids mismatch")
}
if c1.Prefix() != c2.Prefix() {
t.Fatal("prefixes mismatch")
}
}
func TestPrefixRoundtrip(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
@@ -325,3 +385,46 @@ func TestFromJson(t *testing.T) {
t.Fatal("json parsing failed")
}
}
func TestJsonRoundTrip(t *testing.T) {
exp, err := Decode("zb2rhhFAEMepUBbGyP1k8tGfz7BSciKXP6GHuUeUsJBaK6cqG")
if err != nil {
t.Fatal(err)
}
// Verify it works for a *Cid.
enc, err := json.Marshal(exp)
if err != nil {
t.Fatal(err)
}
var actual Cid
err = json.Unmarshal(enc, &actual)
if !exp.Equals(&actual) {
t.Fatal("cids not equal for *Cid")
}
// Verify it works for a Cid.
enc, err = json.Marshal(*exp)
if err != nil {
t.Fatal(err)
}
var actual2 Cid
err = json.Unmarshal(enc, &actual2)
if !exp.Equals(&actual2) {
t.Fatal("cids not equal for Cid")
}
}
func BenchmarkStringV1(b *testing.B) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
cid := NewCidV1(Raw, hash)
b.ResetTimer()
count := 0
for i := 0; i < b.N; i++ {
count += len(cid.String())
}
if count != 49*b.N {
b.FailNow()
}
}

28
deprecated.go Normal file
View File

@@ -0,0 +1,28 @@
package cid
import (
mh "github.com/multiformats/go-multihash"
)
// NewPrefixV0 returns a CIDv0 prefix with the specified multihash type.
// DEPRECATED: Use V0Builder
func NewPrefixV0(mhType uint64) Prefix {
return Prefix{
MhType: mhType,
MhLength: mh.DefaultLengths[mhType],
Version: 0,
Codec: DagProtobuf,
}
}
// NewPrefixV1 returns a CIDv1 prefix with the specified codec and multihash
// type.
// DEPRECATED: Use V1Builder
func NewPrefixV1(codecType uint64, mhType uint64) Prefix {
return Prefix{
MhType: mhType,
MhLength: mh.DefaultLengths[mhType],
Version: 1,
Codec: codecType,
}
}

View File

@@ -9,15 +9,15 @@
"gxDependencies": [
{
"author": "whyrusleeping",
"hash": "QmU9a9NV9RdPNwZQDYd5uKsm6N6LJLSvLbywDDYFbaaC6P",
"hash": "QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8",
"name": "go-multihash",
"version": "1.0.5"
"version": "1.0.8"
},
{
"author": "whyrusleeping",
"hash": "Qme4T6BE4sQxg7ZouamF5M7Tx1ZFTqzcns7BkyQPXpoT99",
"hash": "QmSbvata2WqNkqGtZNg8MR3SKwnB8iQ7vTPJgWqB8bC5kR",
"name": "go-multibase",
"version": "0.2.4"
"version": "0.2.7"
}
],
"gxVersion": "0.8.0",
@@ -25,6 +25,6 @@
"license": "MIT",
"name": "go-cid",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.7.17"
"version": "0.8.0"
}

1
set.go
View File

@@ -65,3 +65,4 @@ func (s *Set) ForEach(f func(c *Cid) error) error {
}
return nil
}

92
set_test.go Normal file
View File

@@ -0,0 +1,92 @@
package cid
import (
"crypto/rand"
"errors"
"testing"
mh "github.com/multiformats/go-multihash"
)
func makeRandomCid(t *testing.T) *Cid {
p := make([]byte, 256)
_, err := rand.Read(p)
if err != nil {
t.Fatal(err)
}
h, err := mh.Sum(p, mh.SHA3, 4)
if err != nil {
t.Fatal(err)
}
cid := &Cid{
codec: 7,
version: 1,
hash: h,
}
return cid
}
func TestSet(t *testing.T) {
cid := makeRandomCid(t)
cid2 := makeRandomCid(t)
s := NewSet()
s.Add(cid)
if !s.Has(cid) {
t.Error("should have the CID")
}
if s.Len() != 1 {
t.Error("should report 1 element")
}
keys := s.Keys()
if len(keys) != 1 || !keys[0].Equals(cid) {
t.Error("key should correspond to Cid")
}
if s.Visit(cid) {
t.Error("visit should return false")
}
foreach := []*Cid{}
foreachF := func(c *Cid) error {
foreach = append(foreach, c)
return nil
}
if err := s.ForEach(foreachF); err != nil {
t.Error(err)
}
if len(foreach) != 1 {
t.Error("ForEach should have visited 1 element")
}
foreachErr := func(c *Cid) error {
return errors.New("test")
}
if err := s.ForEach(foreachErr); err == nil {
t.Error("Should have returned an error")
}
if !s.Visit(cid2) {
t.Error("should have visited a new Cid")
}
if s.Len() != 2 {
t.Error("len should be 2 now")
}
s.Remove(cid2)
if s.Len() != 1 {
t.Error("len should be 1 now")
}
}