Compare commits

..

11 Commits

Author SHA1 Message Date
Jeromy
177ab398cc gx publish 0.7.3 2016-10-24 17:31:04 -07:00
Jeromy
02ce4e9b23 fix decoding of empty strings 2016-10-24 17:30:53 -07:00
Jeromy
460554fb6e gx publish 0.7.2 2016-10-24 09:16:05 -07:00
Jeromy
5d17ab8c70 add bitcoin tx value 2016-10-24 09:10:06 -07:00
Jeromy
ed8d621d9a gx publish 0.7.0 2016-10-19 17:54:06 -07:00
Jeromy
9a43493ca7 add codes for bitcoin and ethereum 2016-10-19 17:53:39 -07:00
Jeromy
8677934d48 add small test to fuzz cid creation routines 2016-10-09 12:19:14 -07:00
Jeromy
5f11b062c3 gx publish 0.6.0 2016-10-08 21:18:24 -07:00
Jeromy
961f0fe7a8 add 'Prefix' object and some more helper routines 2016-10-08 21:17:59 -07:00
Jeromy
6c7d9e3de2 gx publish 0.5.2 2016-10-05 12:08:42 -07:00
Jeromy
e5a96152bd gx publish 0.5.1 2016-10-05 11:37:05 -07:00
5 changed files with 152 additions and 13 deletions

View File

@@ -1 +1 @@
0.5.0: QmcW7CcRA5kMdqNBRpif7e8y9yvVRmJG1uurMvea8TY2SM
0.7.3: QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY

92
cid.go
View File

@@ -5,17 +5,22 @@ import (
"encoding/binary"
"fmt"
mh "github.com/jbenet/go-multihash"
mbase "github.com/multiformats/go-multibase"
mh "github.com/multiformats/go-multihash"
)
const UnsupportedVersionString = "<unsupported cid version>"
const (
Protobuf = iota
Raw
JSON
CBOR
Protobuf = 0x70
CBOR = 0x71
Raw = 0x72
JSON = 0x73
EthereumBlock = 0x90
EthereumTx = 0x91
BitcoinBlock = 0xb0
BitcoinTx = 0xb1
)
func NewCidV0(h mh.Multihash) *Cid {
@@ -41,6 +46,10 @@ type Cid struct {
}
func Decode(v string) (*Cid, error) {
if len(v) < 2 {
return nil, fmt.Errorf("cid too short")
}
if len(v) == 46 && v[:2] == "Qm" {
hash, err := mh.FromB58String(v)
if err != nil {
@@ -174,3 +183,76 @@ func (c *Cid) Loggable() map[string]interface{} {
"cid": c,
}
}
func (c *Cid) Prefix() Prefix {
dec, _ := mh.Decode(c.hash) // assuming we got a valid multiaddr, this will not error
return Prefix{
MhType: dec.Code,
MhLength: dec.Length,
Version: c.version,
Codec: c.codec,
}
}
// Prefix represents all the metadata of a cid, minus any actual content information
type Prefix struct {
Version uint64
Codec uint64
MhType int
MhLength int
}
func (p Prefix) Sum(data []byte) (*Cid, error) {
hash, err := mh.Sum(data, p.MhType, p.MhLength)
if err != nil {
return nil, err
}
switch p.Version {
case 0:
return NewCidV0(hash), nil
case 1:
return NewCidV1(p.Codec, hash), nil
default:
return nil, fmt.Errorf("invalid cid version")
}
}
func (p Prefix) Bytes() []byte {
buf := make([]byte, 16)
n := binary.PutUvarint(buf, p.Version)
n += binary.PutUvarint(buf[n:], p.Codec)
n += binary.PutUvarint(buf[n:], uint64(p.MhType))
n += binary.PutUvarint(buf[n:], uint64(p.MhLength))
return buf[:n]
}
func PrefixFromBytes(buf []byte) (Prefix, error) {
r := bytes.NewReader(buf)
vers, err := binary.ReadUvarint(r)
if err != nil {
return Prefix{}, err
}
codec, err := binary.ReadUvarint(r)
if err != nil {
return Prefix{}, err
}
mhtype, err := binary.ReadUvarint(r)
if err != nil {
return Prefix{}, err
}
mhlen, err := binary.ReadUvarint(r)
if err != nil {
return Prefix{}, err
}
return Prefix{
Version: vers,
Codec: codec,
MhType: int(mhtype),
MhLength: int(mhlen),
}, nil
}

View File

@@ -2,9 +2,10 @@ package cid
import (
"bytes"
"math/rand"
"testing"
mh "github.com/jbenet/go-multihash"
mh "github.com/multiformats/go-multihash"
)
func assertEqual(t *testing.T, a, b *Cid) {
@@ -51,6 +52,13 @@ func TestBasicMarshaling(t *testing.T) {
assertEqual(t, cid, out2)
}
func TestEmptyString(t *testing.T) {
_, err := Decode("")
if err == nil {
t.Fatal("shouldnt be able to parse an empty cid")
}
}
func TestV0Handling(t *testing.T) {
old := "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"
@@ -79,3 +87,41 @@ func TestV0ErrorCases(t *testing.T) {
t.Fatal("should have failed to decode that ref")
}
}
func TestPrefixRoundtrip(t *testing.T) {
data := []byte("this is some test content")
hash, _ := mh.Sum(data, mh.SHA2_256, -1)
c := NewCidV1(CBOR, hash)
pref := c.Prefix()
c2, err := pref.Sum(data)
if err != nil {
t.Fatal(err)
}
if !c.Equals(c2) {
t.Fatal("output didnt match original")
}
pb := pref.Bytes()
pref2, err := PrefixFromBytes(pb)
if err != nil {
t.Fatal(err)
}
if pref.Version != pref2.Version || pref.Codec != pref2.Codec ||
pref.MhType != pref2.MhType || pref.MhLength != pref2.MhLength {
t.Fatal("input prefix didnt match output")
}
}
func TestFuzzCid(t *testing.T) {
buf := make([]byte, 128)
for i := 0; i < 200; i++ {
s := rand.Intn(128)
rand.Read(buf[:s])
_, _ = Cast(buf[:s])
}
}

View File

@@ -9,15 +9,15 @@
"gxDependencies": [
{
"author": "whyrusleeping",
"hash": "QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku",
"hash": "QmYDds3421prZgqKbLpEK7T9Aa2eVdQ7o3YarX1LVLdP2J",
"name": "go-multihash",
"version": "0.0.0"
"version": "1.0.0"
},
{
"author": "whyrusleeping",
"hash": "QmYiTi9mKBMjfiup7na7PhJK7QEZPdMTJenLdgFYVQ2NUv",
"hash": "QmUq3H9YpcPphbRj6ct6rBgBE377A8wANP8zPMRqe1WYbf",
"name": "go-multibase",
"version": "0.2.0"
"version": "0.2.1"
}
],
"gxVersion": "0.8.0",
@@ -25,6 +25,6 @@
"license": "",
"name": "go-cid",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.5.0"
"version": "0.7.3"
}

13
set.go
View File

@@ -26,7 +26,7 @@ func (s *Set) Len() int {
}
func (s *Set) Keys() []*Cid {
var out []*Cid
out := make([]*Cid, 0, len(s.set))
for k, _ := range s.set {
c, _ := Cast([]byte(k))
out = append(out, c)
@@ -42,3 +42,14 @@ func (s *Set) Visit(c *Cid) bool {
return false
}
func (s *Set) ForEach(f func(c *Cid) error) error {
for cs, _ := range s.set {
c, _ := Cast([]byte(cs))
err := f(c)
if err != nil {
return err
}
}
return nil
}