From 05a2a0a857606d73b5ea4aca2089db08e150719d Mon Sep 17 00:00:00 2001 From: Guillaume Louvigny Date: Tue, 18 Jun 2019 14:37:46 +0200 Subject: [PATCH] chore: improved documentation --- accesscontroller/default.go | 3 + doc.go | 1 - entry/entry.go | 144 ++++----- entry/entry_io.go | 12 +- entry/{entry_ordermap.go => entry_map.go} | 19 +- {utils/lamportclock => entry}/lamportclock.go | 45 ++- {log => entry/sorting}/sorting.go | 30 +- entry/utils.go | 159 ++++++---- errmsg/errmsg.go | 3 +- example/example_log_append_test.go | 6 +- identityprovider/identities.go | 34 +- identityprovider/identity.go | 27 +- identityprovider/interface.go | 12 +- identityprovider/orbitdb.go | 6 + io/io.go | 3 + io/service.go | 1 + keystore/keystore.go | 16 +- log/log.go => log.go | 294 ++++++++---------- log/log_io.go => log_io.go | 90 ++++-- test/entry_io_test.go | 57 ++-- test/entry_test.go | 14 +- test/log_append_test.go | 12 +- test/log_heads_tails_test.go | 73 ++--- test/log_join_test.go | 47 ++- test/log_load_test.go | 159 +++++----- test/log_test.go | 27 +- test/logcreator/logcreator.go | 23 +- test/signed_log_test.go | 40 +-- test/utils.go | 4 +- 29 files changed, 733 insertions(+), 628 deletions(-) delete mode 100644 doc.go rename entry/{entry_ordermap.go => entry_map.go} (69%) rename {utils/lamportclock => entry}/lamportclock.go (53%) rename {log => entry/sorting}/sorting.go (68%) rename log/log.go => log.go (71%) rename log/log_io.go => log_io.go (66%) diff --git a/accesscontroller/default.go b/accesscontroller/default.go index b36ea24..e91fd11 100644 --- a/accesscontroller/default.go +++ b/accesscontroller/default.go @@ -1,3 +1,4 @@ +// Package accesscontroller defines a default access controller for IPFS Log, it won't actually check anything. package accesscontroller // import "berty.tech/go-ipfs-log/accesscontroller" import ( @@ -8,6 +9,8 @@ import ( type Default struct { } +// CanAppend Checks whether a given identity can append an entry to the log. +// This implementation allows anyone to write to the log. func (d *Default) CanAppend(*entry.Entry, *identityprovider.Identity) error { return nil } diff --git a/doc.go b/doc.go deleted file mode 100644 index 01c1c39..0000000 --- a/doc.go +++ /dev/null @@ -1 +0,0 @@ -package ipfslog // import "berty.tech/go-ipfs-log" diff --git a/entry/entry.go b/entry/entry.go index a02389f..90a22b0 100644 --- a/entry/entry.go +++ b/entry/entry.go @@ -1,18 +1,17 @@ +// Package entry defines the Entry structure for IPFS Log and its associated methods. package entry // import "berty.tech/go-ipfs-log/entry" import ( "context" "encoding/hex" "encoding/json" - "fmt" "math" "sort" "time" "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/io" - "berty.tech/go-ipfs-log/utils/lamportclock" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" cbornode "github.com/ipfs/go-ipld-cbor" ic "github.com/libp2p/go-libp2p-crypto" "github.com/pkg/errors" @@ -28,7 +27,7 @@ type Entry struct { Sig []byte Identity *identityprovider.Identity Hash cid.Cid - Clock *lamportclock.LamportClock + Clock *LamportClock } type Hashable struct { @@ -37,11 +36,11 @@ type Hashable struct { Payload []byte Next []string V uint64 - Clock *lamportclock.LamportClock + Clock *LamportClock Key []byte } -var AtlasHashable = atlas.BuildEntry(Hashable{}). +var _ = atlas.BuildEntry(Hashable{}). StructMap(). AddField("Hash", atlas.StructMapEntry{SerialName: "hash"}). AddField("ID", atlas.StructMapEntry{SerialName: "id"}). @@ -51,19 +50,19 @@ var AtlasHashable = atlas.BuildEntry(Hashable{}). AddField("Clock", atlas.StructMapEntry{SerialName: "clock"}). Complete() -type CborEntry struct { +type cborEntry struct { V uint64 LogID string Key string Sig string Hash interface{} Next []cid.Cid - Clock *lamportclock.CborLamportClock + Clock *cborLamportClock Payload string Identity *identityprovider.CborIdentity } -func (c *CborEntry) ToEntry(provider identityprovider.Interface) (*Entry, error) { +func (c *cborEntry) toEntry(provider identityprovider.Interface) (*Entry, error) { key, err := hex.DecodeString(c.Key) if err != nil { return nil, err @@ -74,7 +73,7 @@ func (c *CborEntry) ToEntry(provider identityprovider.Interface) (*Entry, error) return nil, err } - clock, err := c.Clock.ToLamportClock() + clock, err := c.Clock.toLamportClock() if err != nil { return nil, err } @@ -96,22 +95,22 @@ func (c *CborEntry) ToEntry(provider identityprovider.Interface) (*Entry, error) }, nil } -func (e *Entry) ToCborEntry() *CborEntry { - return &CborEntry{ +func (e *Entry) toCborEntry() *cborEntry { + return &cborEntry{ V: e.V, LogID: e.LogID, Key: hex.EncodeToString(e.Key), Sig: hex.EncodeToString(e.Sig), Hash: nil, Next: e.Next, - Clock: e.Clock.ToCborLamportClock(), + Clock: e.Clock.toCborLamportClock(), Payload: string(e.Payload), Identity: e.Identity.ToCborIdentity(), } } func init() { - AtlasEntry := atlas.BuildEntry(CborEntry{}). + AtlasEntry := atlas.BuildEntry(cborEntry{}). StructMap(). AddField("V", atlas.StructMapEntry{SerialName: "v"}). AddField("LogID", atlas.StructMapEntry{SerialName: "id"}). @@ -127,7 +126,8 @@ func init() { cbornode.RegisterCborType(AtlasEntry) } -func CreateEntry(ipfsInstance io.IpfsServices, identity *identityprovider.Identity, data *Entry, clock *lamportclock.LamportClock) (*Entry, error) { +// CreateEntry creates an Entry. +func CreateEntry(ipfsInstance io.IpfsServices, identity *identityprovider.Identity, data *Entry, clock *LamportClock) (*Entry, error) { if ipfsInstance == nil { return nil, errors.New("ipfs instance not defined") } @@ -145,14 +145,14 @@ func CreateEntry(ipfsInstance io.IpfsServices, identity *identityprovider.Identi } if clock == nil { - clock = lamportclock.New(identity.PublicKey, 0) + clock = NewLamportClock(identity.PublicKey, 0) } - data = data.Copy() + data = data.copy() data.Clock = clock data.V = 1 - jsonBytes, err := ToBuffer(data.ToHashable()) + jsonBytes, err := toBuffer(data.toHashable()) if err != nil { return nil, err } @@ -167,12 +167,12 @@ func CreateEntry(ipfsInstance io.IpfsServices, identity *identityprovider.Identi data.Sig = signature data.Identity = identity.Filtered() - data.Hash, err = ToMultihash(ipfsInstance, data) + data.Hash, err = data.ToMultihash(ipfsInstance) if err != nil { return nil, err } - nd, err := cbornode.WrapObject(data.ToCborEntry(), math.MaxUint64, -1) + nd, err := cbornode.WrapObject(data.toCborEntry(), math.MaxUint64, -1) if err != nil { return nil, err } @@ -186,7 +186,8 @@ func CreateEntry(ipfsInstance io.IpfsServices, identity *identityprovider.Identi return data, nil } -func (e *Entry) Copy() *Entry { +// copy creates a copy of an entry. +func (e *Entry) copy() *Entry { return &Entry{ Payload: e.Payload, LogID: e.LogID, @@ -200,6 +201,7 @@ func (e *Entry) Copy() *Entry { } } +// uniqueCIDs returns uniques CIDs from a given list. func uniqueCIDs(cids []cid.Cid) []cid.Cid { foundCids := map[string]bool{} out := []cid.Cid{} @@ -216,7 +218,8 @@ func uniqueCIDs(cids []cid.Cid) []cid.Cid { return out } -func ToBuffer(e *Hashable) ([]byte, error) { +// toBuffer converts a hashable entry to bytes. +func toBuffer(e *Hashable) ([]byte, error) { if e == nil { return nil, errors.New("entry is not defined") } @@ -239,7 +242,8 @@ func ToBuffer(e *Hashable) ([]byte, error) { return jsonBytes, nil } -func (e *Entry) ToHashable() *Hashable { +// toHashable Converts an entry to hashable. +func (e *Entry) toHashable() *Hashable { nexts := []string{} for _, n := range e.Next { @@ -257,36 +261,38 @@ func (e *Entry) ToHashable() *Hashable { } } -func (e *Entry) IsValid() bool { +// isValid checks that an entry is valid. +func (e *Entry) isValid() bool { return e.LogID != "" && len(e.Payload) > 0 && e.V <= 1 } -func Verify(identity identityprovider.Interface, entry *Entry) error { - if entry == nil { +// Verify checks the entry's signature. +func (e *Entry) Verify(identity identityprovider.Interface) error { + if e == nil { return errors.New("entry is not defined") } - if len(entry.Key) == 0 { + if len(e.Key) == 0 { return errors.New("entry doesn't have a key") } - if len(entry.Sig) == 0 { + if len(e.Sig) == 0 { return errors.New("entry doesn't have a signature") } // TODO: Check against trusted keys - jsonBytes, err := ToBuffer(entry.ToHashable()) + jsonBytes, err := toBuffer(e.toHashable()) if err != nil { return errors.Wrap(err, "unable to build string buffer") } - pubKey, err := ic.UnmarshalSecp256k1PublicKey(entry.Key) + pubKey, err := ic.UnmarshalSecp256k1PublicKey(e.Key) if err != nil { return errors.Wrap(err, "unable to unmarshal public key") } - ok, err := pubKey.Verify(jsonBytes, entry.Sig) + ok, err := pubKey.Verify(jsonBytes, e.Sig) if err != nil { return errors.Wrap(err, "error whild verifying signature") } @@ -298,8 +304,9 @@ func Verify(identity identityprovider.Interface, entry *Entry) error { return nil } -func ToMultihash(ipfsInstance io.IpfsServices, entry *Entry) (cid.Cid, error) { - if entry == nil { +// ToMultihash gets the multihash of an Entry. +func (e *Entry) ToMultihash(ipfsInstance io.IpfsServices) (cid.Cid, error) { + if e == nil { return cid.Cid{}, errors.New("entry is not defined") } @@ -307,33 +314,34 @@ func ToMultihash(ipfsInstance io.IpfsServices, entry *Entry) (cid.Cid, error) { return cid.Cid{}, errors.New("ipfs instance not defined") } - e := &Entry{ + data := &Entry{ Hash: cid.Cid{}, - LogID: entry.LogID, - Payload: entry.Payload, - Next: entry.Next, - V: entry.V, - Clock: entry.Clock, + LogID: e.LogID, + Payload: e.Payload, + Next: e.Next, + V: e.V, + Clock: e.Clock, } - if entry.Key != nil { - e.Key = entry.Key + if e.Key != nil { + data.Key = e.Key } - if entry.Identity != nil { - e.Identity = entry.Identity + if e.Identity != nil { + data.Identity = e.Identity } - if len(entry.Sig) > 0 { - e.Sig = entry.Sig + if len(e.Sig) > 0 { + data.Sig = e.Sig } - entryCID, err := io.WriteCBOR(ipfsInstance, e.ToCborEntry()) + entryCID, err := io.WriteCBOR(ipfsInstance, data.toCborEntry()) return entryCID, err } -func FromMultihash(ipfs io.IpfsServices, hash cid.Cid, provider identityprovider.Interface) (*Entry, error) { +// fromMultihash creates an Entry from a hash. +func fromMultihash(ipfs io.IpfsServices, hash cid.Cid, provider identityprovider.Interface) (*Entry, error) { if ipfs == nil { return nil, errors.New("ipfs instance not defined") } @@ -343,7 +351,7 @@ func FromMultihash(ipfs io.IpfsServices, hash cid.Cid, provider identityprovider return nil, err } - obj := &CborEntry{} + obj := &cborEntry{} err = cbornode.DecodeInto(result.RawData(), obj) if err != nil { return nil, err @@ -351,7 +359,7 @@ func FromMultihash(ipfs io.IpfsServices, hash cid.Cid, provider identityprovider obj.Hash = hash - entry, err := obj.ToEntry(provider) + entry, err := obj.toEntry(provider) if err != nil { return nil, err } @@ -359,33 +367,14 @@ func FromMultihash(ipfs io.IpfsServices, hash cid.Cid, provider identityprovider return entry, nil } -func Sort(compFunc func(a, b *Entry) (int, error), values []*Entry) { - sort.SliceStable(values, func(i, j int) bool { - ret, err := compFunc(values[i], values[j]) - if err != nil { - fmt.Printf("error while comparing: %v\n", err) - return false - } - return ret < 0 - }) -} - -func Compare(a, b *Entry) (int, error) { - // TODO: Make it a Golang slice-compatible sort function - if a == nil || b == nil { - return 0, errors.New("entry is not defined") - } - - return lamportclock.Compare(a.Clock, b.Clock), nil -} - -func IsEqual(a, b *Entry) bool { - return a.Hash.String() == b.Hash.String() +// Equals checks that two entries are identical. +func (e *Entry) Equals(b *Entry) bool { + return e.Hash.String() == b.Hash.String() } -func IsParent(entry1, entry2 *Entry) bool { - for _, next := range entry2.Next { - if next.String() == entry1.Hash.String() { +func (e *Entry) IsParent(b *Entry) bool { + for _, next := range b.Next { + if next.String() == e.Hash.String() { return true } } @@ -393,12 +382,15 @@ func IsParent(entry1, entry2 *Entry) bool { return false } +// FindChildren finds an entry's children from an Array of entries. +// +// Returns entry's children as an Array up to the last know child. func FindChildren(entry *Entry, values []*Entry) []*Entry { stack := []*Entry{} var parent *Entry for _, e := range values { - if IsParent(entry, e) { + if entry.IsParent(e) { parent = e break } @@ -409,7 +401,7 @@ func FindChildren(entry *Entry, values []*Entry) []*Entry { prev := parent for _, e := range values { - if IsParent(prev, e) { + if prev.IsParent(e) { parent = e break } diff --git a/entry/entry_io.go b/entry/entry_io.go index d301fe3..c2de3b5 100644 --- a/entry/entry_io.go +++ b/entry/entry_io.go @@ -6,7 +6,7 @@ import ( "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/io" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" ) type FetchOptions struct { @@ -18,6 +18,7 @@ type FetchOptions struct { Provider identityprovider.Interface } +// FetchParallel retrieves IPFS log entries. func FetchParallel(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []*Entry { var entries []*Entry @@ -31,6 +32,7 @@ func FetchParallel(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions return NewOrderedMapFromEntries(entries).Slice() } +// FetchAll gets entries from their CIDs. func FetchAll(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []*Entry { result := []*Entry{} cache := NewOrderedMap() @@ -41,7 +43,7 @@ func FetchAll(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []* } addToResults := func(entry *Entry) { - if entry.IsValid() { + if entry.isValid() { loadingQueue = append(loadingQueue, entry.Next...) result = append(result, entry) cache.Set(entry.Hash.String(), entry) @@ -53,7 +55,7 @@ func FetchAll(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []* } for _, e := range options.Exclude { - if e.IsValid() { + if e.isValid() { result = append(result, e) cache.Set(e.Hash.String(), e) } @@ -71,7 +73,7 @@ func FetchAll(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []* return } - entry, err := FromMultihash(ipfs, hash, options.Provider) + entry, err := fromMultihash(ipfs, hash, options.Provider) if err != nil { fmt.Printf("unable to fetch entry %s, %+v\n", hash, err) return @@ -79,7 +81,7 @@ func FetchAll(ipfs io.IpfsServices, hashes []cid.Cid, options *FetchOptions) []* entry.Hash = hash - if entry.IsValid() { + if entry.isValid() { addToResults(entry) } } diff --git a/entry/entry_ordermap.go b/entry/entry_map.go similarity index 69% rename from entry/entry_ordermap.go rename to entry/entry_map.go index 440fd88..7b396ae 100644 --- a/entry/entry_ordermap.go +++ b/entry/entry_map.go @@ -1,19 +1,22 @@ -package entry // import "berty.tech/go-ipfs-log/entry" +package entry import ( "github.com/iancoleman/orderedmap" ) +// OrderedMap is an ordered map of entries. type OrderedMap struct { orderedMap *orderedmap.OrderedMap } +// NewOrderedMap creates a new OrderedMap of entries. func NewOrderedMap() *OrderedMap { return &OrderedMap{ orderedMap: orderedmap.New(), } } +// NewOrderedMapFromEntries creates a new OrderedMap of entries from a slice. func NewOrderedMapFromEntries(entries []*Entry) *OrderedMap { orderedMap := NewOrderedMap() @@ -28,6 +31,7 @@ func NewOrderedMapFromEntries(entries []*Entry) *OrderedMap { return orderedMap } +// Merge will fusion two OrderedMap of entries. func (o *OrderedMap) Merge(other *OrderedMap) *OrderedMap { newMap := o.Copy() @@ -40,6 +44,7 @@ func (o *OrderedMap) Merge(other *OrderedMap) *OrderedMap { return newMap } +// Copy creates a copy of an OrderedMap. func (o *OrderedMap) Copy() *OrderedMap { newMap := NewOrderedMap() keys := o.Keys() @@ -52,6 +57,7 @@ func (o *OrderedMap) Copy() *OrderedMap { return newMap } +// Get retrieves an Entry using its key. func (o *OrderedMap) Get(key string) (*Entry, bool) { val, exists := o.orderedMap.Get(key) entry, ok := val.(*Entry) @@ -62,16 +68,19 @@ func (o *OrderedMap) Get(key string) (*Entry, bool) { return entry, exists } +// UnsafeGet retrieves an Entry using its key, returns nil if not found. func (o *OrderedMap) UnsafeGet(key string) *Entry { val, _ := o.Get(key) return val } +// Set defines an Entry in the map for a given key. func (o *OrderedMap) Set(key string, value *Entry) { o.orderedMap.Set(key, value) } +// Slice returns an ordered slice of the values existing in the map. func (o *OrderedMap) Slice() []*Entry { out := []*Entry{} @@ -83,28 +92,32 @@ func (o *OrderedMap) Slice() []*Entry { return out } +// Delete removes an Entry from the map for a given key. func (o *OrderedMap) Delete(key string) { o.orderedMap.Delete(key) } +// Keys retrieves the ordered list of keys in the map. func (o *OrderedMap) Keys() []string { return o.orderedMap.Keys() } -// SortKeys Sort the map keys using your sort func +// SortKeys orders the map keys using your sort func. func (o *OrderedMap) SortKeys(sortFunc func(keys []string)) { o.orderedMap.SortKeys(sortFunc) } -// Sort Sort the map using your sort func +// Sort orders the map using your sort func. func (o *OrderedMap) Sort(lessFunc func(a *orderedmap.Pair, b *orderedmap.Pair) bool) { o.orderedMap.Sort(lessFunc) } +// Len gets the length of the map. func (o *OrderedMap) Len() int { return len(o.orderedMap.Keys()) } +// At gets an item at the given index in the map, returns nil if not found. func (o *OrderedMap) At(index uint) *Entry { keys := o.Keys() diff --git a/utils/lamportclock/lamportclock.go b/entry/lamportclock.go similarity index 53% rename from utils/lamportclock/lamportclock.go rename to entry/lamportclock.go index 38ffa9e..2c45cf8 100644 --- a/utils/lamportclock/lamportclock.go +++ b/entry/lamportclock.go @@ -1,12 +1,13 @@ -package lamportclock // import "berty.tech/go-ipfs-log/utils/lamportclock" +package entry // import "berty.tech/go-ipfs-log/entry" import ( "bytes" "encoding/hex" "math" - cbornode "github.com/ipfs/go-ipld-cbor" "github.com/polydawn/refmt/obj/atlas" + + cbornode "github.com/ipfs/go-ipld-cbor" ) type LamportClock struct { @@ -14,6 +15,7 @@ type LamportClock struct { Time int } +// Tick increments the time value, returns a new instance of LamportClock. func (l *LamportClock) Tick() *LamportClock { l.Time++ @@ -23,6 +25,7 @@ func (l *LamportClock) Tick() *LamportClock { } } +// Merge fusion two LamportClocks. func (l *LamportClock) Merge(clock *LamportClock) *LamportClock { l.Time = int(math.Max(float64(l.Time), float64(clock.Time))) @@ -32,47 +35,41 @@ func (l *LamportClock) Merge(clock *LamportClock) *LamportClock { } } -func (l *LamportClock) Clone() *LamportClock { - return &LamportClock{ - ID: l.ID, - Time: l.Time, - } -} - -// Compare Calculate the "distance" based on the clock, ie. lower or greater -func Compare(a *LamportClock, b *LamportClock) int { +// Compare calculate the "distance" based on the clock, ie. lower or greater. +func (l *LamportClock) Compare(b *LamportClock) int { // TODO: Make it a Golang slice-compatible sort function - dist := a.Time - b.Time + dist := l.Time - b.Time // If the sequence number is the same (concurrent events), // return the comparison between IDs if dist == 0 { - return bytes.Compare(a.ID, b.ID) + return bytes.Compare(l.ID, b.ID) } return dist } -func New(identity []byte, time int) *LamportClock { +// NewLamportClock creates a new LamportClock instance. +func NewLamportClock(identity []byte, time int) *LamportClock { return &LamportClock{ ID: identity, Time: time, } } -type CborLamportClock struct { +type cborLamportClock struct { ID string Time int } -func (l *LamportClock) ToCborLamportClock() *CborLamportClock { - return &CborLamportClock{ +func (l *LamportClock) toCborLamportClock() *cborLamportClock { + return &cborLamportClock{ ID: hex.EncodeToString(l.ID), Time: l.Time, } } -func (c *CborLamportClock) ToLamportClock() (*LamportClock, error) { +func (c *cborLamportClock) toLamportClock() (*LamportClock, error) { id, err := hex.DecodeString(c.ID) if err != nil { return nil, err @@ -84,12 +81,12 @@ func (c *CborLamportClock) ToLamportClock() (*LamportClock, error) { }, nil } -var AtlasLamportClock = atlas.BuildEntry(CborLamportClock{}). - StructMap(). - AddField("ID", atlas.StructMapEntry{SerialName: "id"}). - AddField("Time", atlas.StructMapEntry{SerialName: "time"}). - Complete() - func init() { + var AtlasLamportClock = atlas.BuildEntry(cborLamportClock{}). + StructMap(). + AddField("ID", atlas.StructMapEntry{SerialName: "id"}). + AddField("Time", atlas.StructMapEntry{SerialName: "time"}). + Complete() + cbornode.RegisterCborType(AtlasLamportClock) } diff --git a/log/sorting.go b/entry/sorting/sorting.go similarity index 68% rename from log/sorting.go rename to entry/sorting/sorting.go index 3156df7..3dca49d 100644 --- a/log/sorting.go +++ b/entry/sorting/sorting.go @@ -1,15 +1,19 @@ -package log // import "berty.tech/go-ipfs-log/log" +// Package sorting includes utilities for ordering slices of Entries. +package sorting import ( "bytes" "errors" + "fmt" + "sort" + + errors2 "github.com/pkg/errors" "berty.tech/go-ipfs-log/entry" - "berty.tech/go-ipfs-log/utils/lamportclock" ) func SortByClocks(a, b *entry.Entry, resolveConflict func(a *entry.Entry, b *entry.Entry) (int, error)) (int, error) { - diff := lamportclock.Compare(a.Clock, b.Clock) + diff := a.Clock.Compare(b.Clock) if diff == 0 { return resolveConflict(a, b) @@ -70,3 +74,23 @@ func Reverse(a []*entry.Entry) { a[i], a[opp] = a[opp], a[i] } } + +func Compare(a, b *entry.Entry) (int, error) { + // TODO: Make it a Golang slice-compatible sort function + if a == nil || b == nil { + return 0, errors2.New("entry is not defined") + } + + return a.Clock.Compare(b.Clock), nil +} + +func Sort(compFunc func(a, b *entry.Entry) (int, error), values []*entry.Entry) { + sort.SliceStable(values, func(i, j int) bool { + ret, err := compFunc(values[i], values[j]) + if err != nil { + fmt.Printf("error while comparing: %v\n", err) + return false + } + return ret < 0 + }) +} diff --git a/entry/utils.go b/entry/utils.go index 422f487..b6f0ebc 100644 --- a/entry/utils.go +++ b/entry/utils.go @@ -1,72 +1,13 @@ package entry // import "berty.tech/go-ipfs-log/entry" import ( + "bytes" "sort" -) - -func EntriesAsStrings(entries []*Entry) []string { - var values []string - - for _, e := range entries { - values = append(values, string(e.Payload)) - } - - sort.Strings(values) - - return values -} - -func Slice(entries []*Entry, index int) []*Entry { - if len(entries) == 0 || index >= len(entries) { - return []*Entry{} - } - if index == 0 || (index < 0 && -index >= len(entries)) { - return entries - } - - if index > 0 { - return entries[index:] - } - - return entries[(len(entries) + index):] -} - -func SliceRange(entries []*Entry, from int, to int) []*Entry { - if len(entries) == 0 { - return []*Entry{} - } - - if from < 0 { - from = len(entries) + from - if from < 0 { - from = 0 - } - } - - if to < 0 { - to = len(entries) + to - } - - if from >= len(entries) { - return []*Entry{} - } - - if to > len(entries) { - to = len(entries) - } - - if from >= to { - return []*Entry{} - } - - if from == to { - return entries - } - - return entries[from:to] -} + "github.com/iancoleman/orderedmap" +) +// Difference gets the list of values not present in both entries sets. func Difference(a []*Entry, b []*Entry) []*Entry { existing := map[string]bool{} processed := map[string]bool{} @@ -87,3 +28,95 @@ func Difference(a []*Entry, b []*Entry) []*Entry { return diff } + +//func FindTails(entries []*Entry) []*Entry { +// // Reverse index { next -> entry } +// reverseIndex := map[string][]*Entry{} +// // Null index containing entries that have no parents (nexts) +// nullIndex := []*Entry{} +// // Hashes for all entries for quick lookups +// hashes := map[string]bool{} +// // Hashes of all next entries +// nexts := []cid.Cid{} +// +// for _, e := range entries { +// if len(e.Next) == 0 { +// nullIndex = append(nullIndex, e) +// } +// +// for _, nextE := range e.Next { +// reverseIndex[nextE.String()] = append(reverseIndex[nextE.String()], e) +// } +// +// nexts = append(nexts, e.Next...) +// +// hashes[e.Hash.String()] = true +// } +// +// tails := []*Entry{} +// +// for _, n := range nexts { +// if _, ok := hashes[n.String()]; !ok { +// continue +// } +// +// tails = append(tails, reverseIndex[n.String()]...) +// } +// +// tails = append(tails, nullIndex...) +// +// return NewOrderedMapFromEntries(tails).Slice() +//} +// +//func FindTailHashes(entries []*Entry) []string { +// res := []string{} +// hashes := map[string]bool{} +// for _, e := range entries { +// hashes[e.Hash.String()] = true +// } +// +// for _, e := range entries { +// nextLength := len(e.Next) +// +// for i := range e.Next { +// next := e.Next[nextLength-i] +// if _, ok := hashes[next.String()]; !ok { +// res = append([]string{e.Hash.String()}, res...) +// } +// } +// } +// +// return res +//} + +// FindHeads search entries heads in an OrderedMap. +func FindHeads(entries *OrderedMap) []*Entry { + if entries == nil { + return nil + } + + result := []*Entry{} + items := orderedmap.New() + + for _, k := range entries.Keys() { + e := entries.UnsafeGet(k) + for _, n := range e.Next { + items.Set(n.String(), e.Hash.String()) + } + } + + for _, h := range entries.Keys() { + e, ok := items.Get(h) + if ok || e != nil { + continue + } + + result = append(result, entries.UnsafeGet(h)) + } + + sort.SliceStable(result, func(a, b int) bool { + return bytes.Compare(result[a].Clock.ID, result[b].Clock.ID) < 0 + }) + + return result +} diff --git a/errmsg/errmsg.go b/errmsg/errmsg.go index 586a216..08951ba 100644 --- a/errmsg/errmsg.go +++ b/errmsg/errmsg.go @@ -1,6 +1,7 @@ +// Package errmsg defines error messages used by the Go version of IPFS Log. package errmsg // import "berty.tech/go-ipfs-log/errmsg" - // https://dave.cheney.net/2016/04/07/constant-errors + type Error string func (e Error) Error() string { return string(e) } diff --git a/example/example_log_append_test.go b/example/example_log_append_test.go index a4e973b..48db1a5 100644 --- a/example/example_log_append_test.go +++ b/example/example_log_append_test.go @@ -5,9 +5,9 @@ import ( "fmt" "io/ioutil" + log "berty.tech/go-ipfs-log" idp "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" config "github.com/ipfs/go-ipfs-config" @@ -126,7 +126,7 @@ func Example_logAppend() { } // creating log - logA, err := log.NewLog(serviceA, identityA, &log.NewLogOptions{ID: "A"}) + logA, err := log.NewLog(serviceA, identityA, &log.LogOptions{ID: "A"}) if err != nil { panic(err) } @@ -142,7 +142,7 @@ func Example_logAppend() { panic(fmt.Errorf("ToMultihash error: %s", err)) } - res, err := log.NewFromMultihash(serviceB, identityB, h, &log.NewLogOptions{}, &log.FetchOptions{}) + res, err := log.NewFromMultihash(serviceB, identityB, h, &log.LogOptions{}, &log.FetchOptions{}) if err != nil { panic(fmt.Errorf("NewFromMultihash error: %s", err)) } diff --git a/identityprovider/identities.go b/identityprovider/identities.go index 4a15b92..c50dd34 100644 --- a/identityprovider/identities.go +++ b/identityprovider/identities.go @@ -18,7 +18,7 @@ type Identities struct { keyStore keystore.Interface } -func GetHandlerFor(typeName string) (func(*CreateIdentityOptions) Interface, error) { +func getHandlerFor(typeName string) (func(*CreateIdentityOptions) Interface, error) { if !IsSupported(typeName) { return nil, errors.New(fmt.Sprintf("IdentityProvider type '%s' is not supported", typeName)) } @@ -26,7 +26,7 @@ func GetHandlerFor(typeName string) (func(*CreateIdentityOptions) Interface, err return supportedTypes[typeName], nil } -func NewIdentities(keyStore keystore.Interface) *Identities { +func newIdentities(keyStore keystore.Interface) *Identities { return &Identities{ keyStore: keyStore, } @@ -46,14 +46,16 @@ func (i *Identities) Sign(identity *Identity, data []byte) ([]byte, error) { return sig, nil } +// Verify checks a signature. func (i *Identities) Verify(signature []byte, publicKey crypto.PubKey, data []byte) (bool, error) { + // TODO: Check why this is related to an identity return publicKey.Verify(data, signature) } -type MigrateOptions struct { - TargetPath string - TargetID string -} +//type MigrateOptions struct { +// TargetPath string +// TargetID string +//} func compressedToUncompressedS256Key(pubKeyBytes []byte) ([]byte, error) { pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256()) @@ -68,8 +70,9 @@ func compressedToUncompressedS256Key(pubKeyBytes []byte) ([]byte, error) { return pubKey.SerializeUncompressed(), nil } +// CreateIdentity creates a new Identity. func (i *Identities) CreateIdentity(options *CreateIdentityOptions) (*Identity, error) { - NewIdentityProvider, err := GetHandlerFor(options.Type) + NewIdentityProvider, err := getHandlerFor(options.Type) if err != nil { return nil, err } @@ -87,7 +90,7 @@ func (i *Identities) CreateIdentity(options *CreateIdentityOptions) (*Identity, // } //} - publicKey, idSignature, err := i.SignID(id) + publicKey, idSignature, err := i.signID(id) if err != nil { return nil, err } @@ -119,7 +122,7 @@ func (i *Identities) CreateIdentity(options *CreateIdentityOptions) (*Identity, }, nil } -func (i *Identities) SignID(id string) (crypto.PubKey, []byte, error) { +func (i *Identities) signID(id string) (crypto.PubKey, []byte, error) { privKey, err := i.keyStore.GetKey(id) if err != nil { privKey, err = i.keyStore.CreateKey(id) @@ -137,6 +140,7 @@ func (i *Identities) SignID(id string) (crypto.PubKey, []byte, error) { return privKey.GetPublic(), idSignature, nil } +// VerifyIdentity checks an identity. func (i *Identities) VerifyIdentity(identity *Identity) error { pubKey, err := identity.GetPublicKey() if err != nil { @@ -157,11 +161,7 @@ func (i *Identities) VerifyIdentity(identity *Identity) error { return err } - return VerifyIdentity(identity) -} - -func VerifyIdentity(identity *Identity) error { - identityProvider, err := GetHandlerFor(identity.Type) + identityProvider, err := getHandlerFor(identity.Type) if err != nil { return err } @@ -169,23 +169,26 @@ func VerifyIdentity(identity *Identity) error { return identityProvider(nil).VerifyIdentity(identity) } +// CreateIdentity creates a new identity. func CreateIdentity(options *CreateIdentityOptions) (*Identity, error) { ks := options.Keystore if ks == nil { return nil, errors.New("a keystore is required") } - identities := NewIdentities(ks) + identities := newIdentities(ks) return identities.CreateIdentity(options) } +// IsSupported checks if an identity type is supported. func IsSupported(typeName string) bool { _, ok := supportedTypes[typeName] return ok } +// AddIdentityProvider registers an new identity provider. func AddIdentityProvider(identityProvider func(*CreateIdentityOptions) Interface) error { if identityProvider == nil { return errors.New("'IdentityProvider' class needs to be given as an option") @@ -196,6 +199,7 @@ func AddIdentityProvider(identityProvider func(*CreateIdentityOptions) Interface return nil } +// RemoveIdentityProvider unregisters an identity provider. func RemoveIdentityProvider(name string) { delete(supportedTypes, name) } diff --git a/identityprovider/identity.go b/identityprovider/identity.go index 7926a19..e965593 100644 --- a/identityprovider/identity.go +++ b/identityprovider/identity.go @@ -1,3 +1,4 @@ +// Package identityprovider defines a default identity provider for IPFS Log and OrbitDB. package identityprovider // import "berty.tech/go-ipfs-log/identityprovider" import ( @@ -35,6 +36,7 @@ type CborIdentity struct { Type string } +// Filtered gets fields that should be present in the CBOR representation of identity. func (i *Identity) Filtered() *Identity { return &Identity{ ID: i.ID, @@ -44,11 +46,12 @@ func (i *Identity) Filtered() *Identity { } } +// GetPublicKey returns the public key of an identity. func (i *Identity) GetPublicKey() (ic.PubKey, error) { return ic.UnmarshalPublicKey(i.PublicKey) } -var AtlasIdentity = atlas.BuildEntry(CborIdentity{}). +var atlasIdentity = atlas.BuildEntry(CborIdentity{}). StructMap(). AddField("ID", atlas.StructMapEntry{SerialName: "id"}). AddField("Type", atlas.StructMapEntry{SerialName: "type"}). @@ -56,13 +59,13 @@ var AtlasIdentity = atlas.BuildEntry(CborIdentity{}). AddField("Signatures", atlas.StructMapEntry{SerialName: "signatures"}). Complete() -var AtlasIdentitySignature = atlas.BuildEntry(CborIdentitySignature{}). +var atlasIdentitySignature = atlas.BuildEntry(CborIdentitySignature{}). StructMap(). AddField("ID", atlas.StructMapEntry{SerialName: "id"}). AddField("PublicKey", atlas.StructMapEntry{SerialName: "publicKey"}). Complete() -var AtlasPubKey = atlas.BuildEntry(ic.Secp256k1PublicKey{}). +var atlasPubKey = atlas.BuildEntry(ic.Secp256k1PublicKey{}). Transform(). TransformMarshal(atlas.MakeMarshalTransformFunc( func(x ic.Secp256k1PublicKey) (string, error) { @@ -94,27 +97,29 @@ var AtlasPubKey = atlas.BuildEntry(ic.Secp256k1PublicKey{}). Complete() func init() { - cbornode.RegisterCborType(AtlasIdentity) - cbornode.RegisterCborType(AtlasIdentitySignature) - cbornode.RegisterCborType(AtlasPubKey) + cbornode.RegisterCborType(atlasIdentity) + cbornode.RegisterCborType(atlasIdentitySignature) + cbornode.RegisterCborType(atlasPubKey) } +// ToCborIdentity converts an identity to a CBOR serializable identity. func (i *Identity) ToCborIdentity() *CborIdentity { return &CborIdentity{ ID: i.ID, PublicKey: hex.EncodeToString(i.PublicKey), Type: i.Type, - Signatures: i.Signatures.ToCborIdentitySignatures(), + Signatures: i.Signatures.ToCborIdentitySignature(), } } +// ToIdentity converts a CBOR serializable to a plain Identity object. func (c *CborIdentity) ToIdentity(provider Interface) (*Identity, error) { publicKey, err := hex.DecodeString(c.PublicKey) if err != nil { return nil, err } - idSignatures, err := c.Signatures.ToIdentitySignatures() + idSignatures, err := c.Signatures.ToIdentitySignature() if err != nil { return nil, err } @@ -128,14 +133,16 @@ func (c *CborIdentity) ToIdentity(provider Interface) (*Identity, error) { }, nil } -func (i *IdentitySignature) ToCborIdentitySignatures() *CborIdentitySignature { +// ToCborIdentitySignature converts to a CBOR serialized identity signature a plain IdentitySignature. +func (i *IdentitySignature) ToCborIdentitySignature() *CborIdentitySignature { return &CborIdentitySignature{ ID: hex.EncodeToString(i.ID), PublicKey: hex.EncodeToString(i.PublicKey), } } -func (c *CborIdentitySignature) ToIdentitySignatures() (*IdentitySignature, error) { +// ToIdentitySignature converts a CBOR serializable identity signature to a plain IdentitySignature. +func (c *CborIdentitySignature) ToIdentitySignature() (*IdentitySignature, error) { publicKey, err := hex.DecodeString(c.PublicKey) if err != nil { return nil, err diff --git a/identityprovider/interface.go b/identityprovider/interface.go index 0817f4e..fb75299 100644 --- a/identityprovider/interface.go +++ b/identityprovider/interface.go @@ -6,21 +6,23 @@ type CreateIdentityOptions struct { IdentityKeysPath string Type string Keystore keystore.Interface - Migrate func(*MigrateOptions) error - ID string + //Migrate func(*MigrateOptions) error + ID string } type Interface interface { - /* GetID Return id of identity (to be signed by orbit-db public key) */ + // GetID returns id of identity (to be signed by orbit-db public key). GetID(*CreateIdentityOptions) (string, error) - /* SignIdentity Return signature of OrbitDB public key signature */ + // SignIdentity returns signature of OrbitDB public key signature. SignIdentity(data []byte, id string) ([]byte, error) - /* GetType Return the type for this identity provider */ + // GetType returns the type for this identity provider. GetType() string + // VerifyIdentity checks an identity. VerifyIdentity(identity *Identity) error + // Sign will sign a value. Sign(identity *Identity, bytes []byte) ([]byte, error) } diff --git a/identityprovider/orbitdb.go b/identityprovider/orbitdb.go index 70b5a9e..b49e6cb 100644 --- a/identityprovider/orbitdb.go +++ b/identityprovider/orbitdb.go @@ -12,16 +12,19 @@ type OrbitDBIdentityProvider struct { keystore keystore.Interface } +// VerifyIdentity checks an OrbitDB identity. func (p *OrbitDBIdentityProvider) VerifyIdentity(identity *Identity) error { panic("implement me") } +// NewOrbitDBIdentityProvider creates a new identity for use with OrbitDB. func NewOrbitDBIdentityProvider(options *CreateIdentityOptions) Interface { return &OrbitDBIdentityProvider{ keystore: options.Keystore, } } +// GetID returns the identity's ID. func (p *OrbitDBIdentityProvider) GetID(options *CreateIdentityOptions) (string, error) { private, err := p.keystore.GetKey(options.ID) if err != nil || private == nil { @@ -39,6 +42,7 @@ func (p *OrbitDBIdentityProvider) GetID(options *CreateIdentityOptions) (string, return hex.EncodeToString(pubBytes), nil } +// SignIdentity signs an OrbitDB identity. func (p *OrbitDBIdentityProvider) SignIdentity(data []byte, id string) ([]byte, error) { key, err := p.keystore.GetKey(id) if err != nil { @@ -58,6 +62,7 @@ func (p *OrbitDBIdentityProvider) SignIdentity(data []byte, id string) ([]byte, return signature, nil } +// Sign signs a value using the current. func (p *OrbitDBIdentityProvider) Sign(identity *Identity, data []byte) ([]byte, error) { key, err := p.keystore.GetKey(identity.ID) if err != nil { @@ -72,6 +77,7 @@ func (p *OrbitDBIdentityProvider) Sign(identity *Identity, data []byte) ([]byte, return sig, nil } +// GetType returns the current identity type. func (*OrbitDBIdentityProvider) GetType() string { return "orbitdb" } diff --git a/io/io.go b/io/io.go index ba4c7ec..021525f 100644 --- a/io/io.go +++ b/io/io.go @@ -1,3 +1,4 @@ +// Package io defines helpers used within IPFS Log and OrbitDB. package io // import "berty.tech/go-ipfs-log/io" import ( @@ -16,6 +17,7 @@ func SetDebug(val bool) { debug = val } +// WriteCBOR writes a CBOR representation of a given object in IPFS' DAG. func WriteCBOR(ipfs IpfsServices, obj interface{}) (cid.Cid, error) { cborNode, err := cbornode.WrapObject(obj, math.MaxUint64, -1) if err != nil { @@ -34,6 +36,7 @@ func WriteCBOR(ipfs IpfsServices, obj interface{}) (cid.Cid, error) { return cborNode.Cid(), nil } +// ReadCBOR reads a CBOR representation of a given object from IPFS' DAG. func ReadCBOR(ipfs IpfsServices, contentIdentifier cid.Cid) (format.Node, error) { return ipfs.Dag().Get(context.Background(), contentIdentifier) } diff --git a/io/service.go b/io/service.go index 9d9de09..74ece84 100644 --- a/io/service.go +++ b/io/service.go @@ -4,6 +4,7 @@ import ( core_iface "github.com/ipfs/interface-go-ipfs-core" ) +// The IpfsServices interface with required IPFS services. type IpfsServices interface { Dag() core_iface.APIDagService } diff --git a/keystore/keystore.go b/keystore/keystore.go index 90260d6..99290a4 100644 --- a/keystore/keystore.go +++ b/keystore/keystore.go @@ -1,3 +1,4 @@ +// Package keystore defines a local key manager for OrbitDB and IPFS Log. package keystore // import "berty.tech/go-ipfs-log/keystore" import ( @@ -15,10 +16,12 @@ type Keystore struct { cache *lru.Cache } -func (k *Keystore) Sign(pubKey crypto.PrivKey, bytes []byte) ([]byte, error) { - return pubKey.Sign(bytes) +// Sign signs a value using a given private key. +func (k *Keystore) Sign(privKey crypto.PrivKey, bytes []byte) ([]byte, error) { + return privKey.Sign(bytes) } +// Verify verifies a signature. func (k *Keystore) Verify(signature []byte, publicKey crypto.PubKey, data []byte) error { ok, err := publicKey.Verify(data, signature) if err != nil { @@ -32,6 +35,7 @@ func (k *Keystore) Verify(signature []byte, publicKey crypto.PubKey, data []byte return nil } +// NewKeystore creates a new keystore. func NewKeystore(store datastore.Datastore) (*Keystore, error) { cache, err := lru.New(128) if err != nil { @@ -44,8 +48,8 @@ func NewKeystore(store datastore.Datastore) (*Keystore, error) { }, nil } +// HasKey checks whether a given key ID exist in the keystore. func (k *Keystore) HasKey(id string) (bool, error) { - hasKey := false storedKey, ok := k.cache.Peek(id) if ok == false { @@ -59,11 +63,10 @@ func (k *Keystore) HasKey(id string) (bool, error) { } } - hasKey = storedKey != nil - - return hasKey, nil + return storedKey != nil, nil } +// CreateKey creates a new key in the key store. func (k *Keystore) CreateKey(id string) (crypto.PrivKey, error) { // FIXME: I kept Secp256k1 for compatibility with OrbitDB, should we change this? priv, _, err := crypto.GenerateSecp256k1Key(rand.Reader) @@ -85,6 +88,7 @@ func (k *Keystore) CreateKey(id string) (crypto.PrivKey, error) { return priv, nil } +// GetKey retrieves a key from the keystore. func (k *Keystore) GetKey(id string) (crypto.PrivKey, error) { var err error var keyBytes []byte diff --git a/log/log.go b/log.go similarity index 71% rename from log/log.go rename to log.go index c8c5372..25a1de0 100644 --- a/log/log.go +++ b/log.go @@ -1,21 +1,20 @@ -package log // import "berty.tech/go-ipfs-log/log" +// Package ipfslog implements an append-only log CRDT on IPFS +package ipfslog // import "berty.tech/go-ipfs-log" import ( - "bytes" - "encoding/json" - "sort" "strconv" "strings" "time" + "berty.tech/go-ipfs-log/entry/sorting" + "berty.tech/go-ipfs-log/accesscontroller" "berty.tech/go-ipfs-log/entry" "berty.tech/go-ipfs-log/errmsg" "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/io" - "berty.tech/go-ipfs-log/utils/lamportclock" "github.com/iancoleman/orderedmap" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" cbornode "github.com/ipfs/go-ipld-cbor" "github.com/pkg/errors" "github.com/polydawn/refmt/obj/atlas" @@ -35,26 +34,26 @@ type Log struct { Entries *entry.OrderedMap heads *entry.OrderedMap Next *entry.OrderedMap - Clock *lamportclock.LamportClock + Clock *entry.LamportClock } -type NewLogOptions struct { +type LogOptions struct { ID string AccessController accesscontroller.Interface Entries *entry.OrderedMap Heads []*entry.Entry - Clock *lamportclock.LamportClock + Clock *entry.LamportClock SortFn func(a *entry.Entry, b *entry.Entry) (int, error) } -type Snapshot struct { +type snapshot struct { ID string Heads []cid.Cid Values []*entry.Entry - Clock *lamportclock.LamportClock + Clock *entry.LamportClock } -// max returns the larger of x or y. +// maxInt Returns the larger of x or y func maxInt(x, y int) int { if x < y { return y @@ -71,7 +70,20 @@ func maxClockTimeForEntries(entries []*entry.Entry, defValue int) int { return max } -func NewLog(services io.IpfsServices, identity *identityprovider.Identity, options *NewLogOptions) (*Log, error) { +// NewLog Creates creates a new Log for a given identity +// +// Each Log gets a unique ID, which can be passed in the options as ID. +// +// Returns a log instance. +// +// ipfs is an instance of IPFS. +// +// identity is an instance of Identity and will be used to sign entries +// Usually this should be a user id or similar. +// +// options.AccessController is an instance of accesscontroller.Interface, +// which by default allows anyone to append to the Log. +func NewLog(services io.IpfsServices, identity *identityprovider.Identity, options *LogOptions) (*Log, error) { if services == nil { return nil, errmsg.IPFSNotDefined } @@ -81,7 +93,7 @@ func NewLog(services io.IpfsServices, identity *identityprovider.Identity, optio } if options == nil { - options = &NewLogOptions{} + options = &LogOptions{} } if options.ID == "" { @@ -89,7 +101,7 @@ func NewLog(services io.IpfsServices, identity *identityprovider.Identity, optio } if options.SortFn == nil { - options.SortFn = LastWriteWins + options.SortFn = sorting.LastWriteWins } maxTime := 0 @@ -107,7 +119,7 @@ func NewLog(services io.IpfsServices, identity *identityprovider.Identity, optio } if len(options.Heads) == 0 && len(options.Entries.Keys()) > 0 { - options.Heads = FindHeads(options.Entries) + options.Heads = entry.FindHeads(options.Entries) } next := entry.NewOrderedMap() @@ -123,11 +135,11 @@ func NewLog(services io.IpfsServices, identity *identityprovider.Identity, optio ID: options.ID, Identity: identity, AccessController: options.AccessController, - SortFn: NoZeroes(options.SortFn), + SortFn: sorting.NoZeroes(options.SortFn), Entries: options.Entries.Copy(), heads: entry.NewOrderedMapFromEntries(options.Heads), Next: next, - Clock: lamportclock.New(identity.PublicKey, maxTime), + Clock: entry.NewLamportClock(identity.PublicKey, maxTime), }, nil } @@ -140,8 +152,8 @@ func (l *Log) addToStack(e *entry.Entry, stack []*entry.Entry, traversed *ordere // Add the entry in front of the stack and sort stack = append([]*entry.Entry{e}, stack...) - entry.Sort(l.SortFn, stack) - Reverse(stack) + sorting.Sort(l.SortFn, stack) + sorting.Reverse(stack) // Add to the cache of processed entries traversed.Set(e.Hash.String(), true) @@ -149,7 +161,7 @@ func (l *Log) addToStack(e *entry.Entry, stack []*entry.Entry, traversed *ordere return stack, traversed } -func (l *Log) Traverse(rootEntries *entry.OrderedMap, amount int, endHash string) ([]*entry.Entry, error) { +func (l *Log) traverse(rootEntries *entry.OrderedMap, amount int, endHash string) ([]*entry.Entry, error) { if rootEntries == nil { return nil, errmsg.EntriesNotDefined } @@ -157,8 +169,8 @@ func (l *Log) Traverse(rootEntries *entry.OrderedMap, amount int, endHash string // Sort the given given root entries and use as the starting stack stack := rootEntries.Slice() - entry.Sort(l.SortFn, stack) - Reverse(stack) + sorting.Sort(l.SortFn, stack) + sorting.Reverse(stack) // Cache for checking if we've processed an entry already traversed := orderedmap.New() @@ -199,16 +211,19 @@ func (l *Log) Traverse(rootEntries *entry.OrderedMap, amount int, endHash string return result, nil } +// Append Appends an entry to the log Returns the latest Entry +// +// payload is the data that will be in the Entry func (l *Log) Append(payload []byte, pointerCount int) (*entry.Entry, error) { // INFO: JS default value for pointerCount is 1 // Update the clock (find the latest clock) newTime := maxClockTimeForEntries(l.heads.Slice(), 0) newTime = maxInt(l.Clock.Time, newTime) + 1 - l.Clock = lamportclock.New(l.Clock.ID, newTime) + l.Clock = entry.NewLamportClock(l.Clock.ID, newTime) // Get the required amount of hashes to next entries (as per current state of the log) - references, err := l.Traverse(l.heads, maxInt(pointerCount, l.heads.Len()), "") + references, err := l.traverse(l.heads, maxInt(pointerCount, l.heads.Len()), "") if err != nil { return nil, errors.Wrap(err, "append failed") } @@ -290,7 +305,7 @@ func (l *Log) Iterator(options IteratorOptions, output chan<- *entry.Entry) erro count = amount } - entries, err := l.Traverse(entry.NewOrderedMapFromEntries(start), count, endHash) + entries, err := l.traverse(entry.NewOrderedMapFromEntries(start), count, endHash) if err != nil { return errors.Wrap(err, "iterator failed") } @@ -311,6 +326,11 @@ func (l *Log) Iterator(options IteratorOptions, output chan<- *entry.Entry) erro return nil } +// Join Joins the log with another log +// +// Returns a log instance. +// +// The size of the joined log can be specified by specifying the size argument, to include all values use -1 func (l *Log) Join(otherLog *Log, size int) (*Log, error) { // INFO: JS default size is -1 if otherLog == nil { @@ -321,7 +341,7 @@ func (l *Log) Join(otherLog *Log, size int) (*Log, error) { return l, nil } - newItems := Difference(otherLog, l) + newItems := difference(otherLog, l) for _, k := range newItems.Keys() { e := newItems.UnsafeGet(k) @@ -329,7 +349,7 @@ func (l *Log) Join(otherLog *Log, size int) (*Log, error) { return nil, errors.Wrap(err, "join failed") } - if err := entry.Verify(l.Identity.Provider, e); err != nil { + if err := e.Verify(l.Identity.Provider); err != nil { return nil, errors.Wrap(err, "unable to check signature") } } @@ -351,7 +371,7 @@ func (l *Log) Join(otherLog *Log, size int) (*Log, error) { } } - mergedHeads := FindHeads(l.heads.Merge(otherLog.heads)) + mergedHeads := entry.FindHeads(l.heads.Merge(otherLog.heads)) for idx, e := range mergedHeads { // notReferencedByNewItems if _, ok := nextsFromNewItems.Get(e.Hash.String()); ok { @@ -370,17 +390,17 @@ func (l *Log) Join(otherLog *Log, size int) (*Log, error) { tmp := l.Values().Slice() tmp = tmp[len(tmp)-size:] l.Entries = entry.NewOrderedMapFromEntries(tmp) - l.heads = entry.NewOrderedMapFromEntries(FindHeads(entry.NewOrderedMapFromEntries(tmp))) + l.heads = entry.NewOrderedMapFromEntries(entry.FindHeads(entry.NewOrderedMapFromEntries(tmp))) } // Find the latest clock from the heads maxClock := maxClockTimeForEntries(l.heads.Slice(), 0) - l.Clock = lamportclock.New(l.Clock.ID, maxInt(l.Clock.Time, maxClock)) + l.Clock = entry.NewLamportClock(l.Clock.ID, maxInt(l.Clock.Time, maxClock)) return l, nil } -func Difference(logA, logB *Log) *entry.OrderedMap { +func difference(logA, logB *Log) *entry.OrderedMap { if logA == nil || logA.Entries == nil || logA.Entries.Len() == 0 || logB == nil { return entry.NewOrderedMap() } @@ -421,9 +441,13 @@ func Difference(logA, logB *Log) *entry.OrderedMap { return res } +// ToString Returns the log values as a nicely formatted string +// +// payloadMapper is a function to customize text representation, +// use nil to use the default mapper which convert the payload as a string func (l *Log) ToString(payloadMapper func(*entry.Entry) string) string { values := l.Values().Slice() - Reverse(values) + sorting.Reverse(values) lines := []string{} @@ -448,33 +472,42 @@ func (l *Log) ToString(payloadMapper func(*entry.Entry) string) string { return strings.Join(lines, "\n") } -func (l *Log) ToSnapshot() *Snapshot { - return &Snapshot{ - ID: l.ID, - Heads: entrySliceToCids(l.heads.Slice()), - Values: l.Values().Slice(), - } -} - -func entrySliceToCids(slice []*entry.Entry) []cid.Cid { - cids := []cid.Cid{} - - for _, e := range slice { - cids = append(cids, e.Hash) - } - - return cids -} - -func (l *Log) ToBuffer() ([]byte, error) { - return json.Marshal(l.ToJSON()) -} - +//func (l *Log) toSnapshot() *snapshot { +// return &snapshot{ +// ID: l.ID, +// Heads: entrySliceToCids(l.heads.Slice()), +// Values: l.Values().Slice(), +// } +//} +// +//func entrySliceToCids(slice []*entry.Entry) []cid.Cid { +// cids := []cid.Cid{} +// +// for _, e := range slice { +// cids = append(cids, e.Hash) +// } +// +// return cids +//} +// +//func (l *Log) toBuffer() ([]byte, error) { +// return json.Marshal(l.ToJSON()) +//} + +// ToMultihash Returns the multihash of the log +// +// Converting the log to a multihash will persist the contents of +// log.toJSON to IPFS, thus causing side effects +// +// The only supported format is dag-cbor and a CIDv1 is returned func (l *Log) ToMultihash() (cid.Cid, error) { - return ToMultihash(l.Storage, l) + return toMultihash(l.Storage, l) } -func NewFromMultihash(services io.IpfsServices, identity *identityprovider.Identity, hash cid.Cid, logOptions *NewLogOptions, fetchOptions *FetchOptions) (*Log, error) { +// NewFromMultihash Creates a Log from a hash +// +// Creating a log from a hash will retrieve entries from IPFS, thus causing side effects +func NewFromMultihash(services io.IpfsServices, identity *identityprovider.Identity, hash cid.Cid, logOptions *LogOptions, fetchOptions *FetchOptions) (*Log, error) { if services == nil { return nil, errmsg.IPFSNotDefined } @@ -491,7 +524,7 @@ func NewFromMultihash(services io.IpfsServices, identity *identityprovider.Ident return nil, errmsg.FetchOptionsNotDefined } - data, err := FromMultihash(services, hash, &FetchOptions{ + data, err := fromMultihash(services, hash, &FetchOptions{ Length: fetchOptions.Length, Exclude: fetchOptions.Exclude, ProgressChan: fetchOptions.ProgressChan, @@ -511,17 +544,20 @@ func NewFromMultihash(services io.IpfsServices, identity *identityprovider.Ident } } - return NewLog(services, identity, &NewLogOptions{ + return NewLog(services, identity, &LogOptions{ ID: data.ID, AccessController: logOptions.AccessController, Entries: entry.NewOrderedMapFromEntries(data.Values), Heads: heads, - Clock: lamportclock.New(data.Clock.ID, data.Clock.Time), + Clock: entry.NewLamportClock(data.Clock.ID, data.Clock.Time), SortFn: logOptions.SortFn, }) } -func NewFromEntryHash(services io.IpfsServices, identity *identityprovider.Identity, hash cid.Cid, logOptions *NewLogOptions, fetchOptions *FetchOptions) (*Log, error) { +// NewFromEntryHash Creates a Log from a hash of an Entry +// +// Creating a log from a hash will retrieve entries from IPFS, thus causing side effects +func NewFromEntryHash(services io.IpfsServices, identity *identityprovider.Identity, hash cid.Cid, logOptions *LogOptions, fetchOptions *FetchOptions) (*Log, error) { if logOptions == nil { return nil, errmsg.LogOptionsNotDefined } @@ -531,7 +567,7 @@ func NewFromEntryHash(services io.IpfsServices, identity *identityprovider.Ident } // TODO: need to verify the entries with 'key' - entries, err := FromEntryHash(services, []cid.Cid{hash}, &FetchOptions{ + entries, err := fromEntryHash(services, []cid.Cid{hash}, &FetchOptions{ Length: fetchOptions.Length, Exclude: fetchOptions.Exclude, ProgressChan: fetchOptions.ProgressChan, @@ -540,7 +576,7 @@ func NewFromEntryHash(services io.IpfsServices, identity *identityprovider.Ident return nil, errors.Wrap(err, "newfromentryhash failed") } - return NewLog(services, identity, &NewLogOptions{ + return NewLog(services, identity, &LogOptions{ ID: logOptions.ID, AccessController: logOptions.AccessController, Entries: entry.NewOrderedMapFromEntries(entries), @@ -548,7 +584,10 @@ func NewFromEntryHash(services io.IpfsServices, identity *identityprovider.Ident }) } -func NewFromJSON(services io.IpfsServices, identity *identityprovider.Identity, jsonLog *JSONLog, logOptions *NewLogOptions, fetchOptions *entry.FetchOptions) (*Log, error) { +// NewFromJSON Creates a Log from a JSON snapshot +// +// Creating a log from a JSON snapshot will retrieve entries from IPFS, thus causing side effects +func NewFromJSON(services io.IpfsServices, identity *identityprovider.Identity, jsonLog *JSONLog, logOptions *LogOptions, fetchOptions *entry.FetchOptions) (*Log, error) { if logOptions == nil { return nil, errmsg.LogOptionsNotDefined } @@ -559,7 +598,7 @@ func NewFromJSON(services io.IpfsServices, identity *identityprovider.Identity, // TODO: need to verify the entries with 'key' - snapshot, err := FromJSON(services, jsonLog, &entry.FetchOptions{ + snapshot, err := fromJSON(services, jsonLog, &entry.FetchOptions{ Length: fetchOptions.Length, Timeout: fetchOptions.Timeout, ProgressChan: fetchOptions.ProgressChan, @@ -568,7 +607,7 @@ func NewFromJSON(services io.IpfsServices, identity *identityprovider.Identity, return nil, errors.Wrap(err, "newfromjson failed") } - return NewLog(services, identity, &NewLogOptions{ + return NewLog(services, identity, &LogOptions{ ID: snapshot.ID, AccessController: logOptions.AccessController, Entries: entry.NewOrderedMapFromEntries(snapshot.Values), @@ -576,7 +615,10 @@ func NewFromJSON(services io.IpfsServices, identity *identityprovider.Identity, }) } -func NewFromEntry(services io.IpfsServices, identity *identityprovider.Identity, sourceEntries []*entry.Entry, logOptions *NewLogOptions, fetchOptions *entry.FetchOptions) (*Log, error) { +// NewFromEntry Creates a Log from an Entry +// +// Creating a log from an entry will retrieve entries from IPFS, thus causing side effects +func NewFromEntry(services io.IpfsServices, identity *identityprovider.Identity, sourceEntries []*entry.Entry, logOptions *LogOptions, fetchOptions *entry.FetchOptions) (*Log, error) { if logOptions == nil { return nil, errmsg.LogOptionsNotDefined } @@ -586,7 +628,7 @@ func NewFromEntry(services io.IpfsServices, identity *identityprovider.Identity, } // TODO: need to verify the entries with 'key' - snapshot, err := FromEntry(services, sourceEntries, &entry.FetchOptions{ + snapshot, err := fromEntry(services, sourceEntries, &entry.FetchOptions{ Length: fetchOptions.Length, Exclude: fetchOptions.Exclude, ProgressChan: fetchOptions.ProgressChan, @@ -595,7 +637,7 @@ func NewFromEntry(services io.IpfsServices, identity *identityprovider.Identity, return nil, errors.Wrap(err, "newfromentry failed") } - return NewLog(services, identity, &NewLogOptions{ + return NewLog(services, identity, &LogOptions{ ID: snapshot.ID, AccessController: logOptions.AccessController, Entries: entry.NewOrderedMapFromEntries(snapshot.Values), @@ -603,111 +645,24 @@ func NewFromEntry(services io.IpfsServices, identity *identityprovider.Identity, }) } -func FindTails(entries []*entry.Entry) []*entry.Entry { - // Reverse index { next -> entry } - reverseIndex := map[string][]*entry.Entry{} - // Null index containing entries that have no parents (nexts) - nullIndex := []*entry.Entry{} - // Hashes for all entries for quick lookups - hashes := map[string]bool{} - // Hashes of all next entries - nexts := []cid.Cid{} - - for _, e := range entries { - if len(e.Next) == 0 { - nullIndex = append(nullIndex, e) - } - - for _, nextE := range e.Next { - reverseIndex[nextE.String()] = append(reverseIndex[nextE.String()], e) - } - - nexts = append(nexts, e.Next...) - - hashes[e.Hash.String()] = true - } - - tails := []*entry.Entry{} - - for _, n := range nexts { - if _, ok := hashes[n.String()]; !ok { - continue - } - - tails = append(tails, reverseIndex[n.String()]...) - } - - tails = append(tails, nullIndex...) - - return entry.NewOrderedMapFromEntries(tails).Slice() -} - -func FindTailHashes(entries []*entry.Entry) []string { - res := []string{} - hashes := map[string]bool{} - for _, e := range entries { - hashes[e.Hash.String()] = true - } - - for _, e := range entries { - nextLength := len(e.Next) - - for i := range e.Next { - next := e.Next[nextLength-i] - if _, ok := hashes[next.String()]; !ok { - res = append([]string{e.Hash.String()}, res...) - } - } - } - - return res -} - -func FindHeads(entries *entry.OrderedMap) []*entry.Entry { - if entries == nil { - return nil - } - - result := []*entry.Entry{} - items := orderedmap.New() - - for _, k := range entries.Keys() { - e := entries.UnsafeGet(k) - for _, n := range e.Next { - items.Set(n.String(), e.Hash.String()) - } - } - - for _, h := range entries.Keys() { - e, ok := items.Get(h) - if ok || e != nil { - continue - } - - result = append(result, entries.UnsafeGet(h)) - } - - sort.SliceStable(result, func(a, b int) bool { - return bytes.Compare(result[a].Clock.ID, result[b].Clock.ID) < 0 - }) - - return result -} - +// Values Returns an Array of entries in the log +// +// The values are in linearized order according to their Lamport clocks func (l *Log) Values() *entry.OrderedMap { if l.heads == nil { return entry.NewOrderedMap() } - stack, _ := l.Traverse(l.heads, -1, "") - Reverse(stack) + stack, _ := l.traverse(l.heads, -1, "") + sorting.Reverse(stack) return entry.NewOrderedMapFromEntries(stack) } +// ToJSON Returns a log in a JSON serializable structure func (l *Log) ToJSON() *JSONLog { stack := l.heads.Slice() - entry.Sort(l.SortFn, stack) - Reverse(stack) + sorting.Sort(l.SortFn, stack) + sorting.Reverse(stack) hashes := []cid.Cid{} for _, e := range stack { @@ -720,20 +675,23 @@ func (l *Log) ToJSON() *JSONLog { } } +// Heads Returns the heads of the log +// +// Heads are the entries that are not referenced by other entries in the log func (l *Log) Heads() *entry.OrderedMap { heads := l.heads.Slice() - entry.Sort(l.SortFn, heads) - Reverse(heads) + sorting.Sort(l.SortFn, heads) + sorting.Reverse(heads) return entry.NewOrderedMapFromEntries(heads) } -var AtlasJSONLog = atlas.BuildEntry(JSONLog{}). +var atlasJSONLog = atlas.BuildEntry(JSONLog{}). StructMap(). AddField("ID", atlas.StructMapEntry{SerialName: "id"}). AddField("Heads", atlas.StructMapEntry{SerialName: "heads"}). Complete() func init() { - cbornode.RegisterCborType(AtlasJSONLog) + cbornode.RegisterCborType(atlasJSONLog) } diff --git a/log/log_io.go b/log_io.go similarity index 66% rename from log/log_io.go rename to log_io.go index 61fd054..325a96e 100644 --- a/log/log_io.go +++ b/log_io.go @@ -1,15 +1,16 @@ -package log // import "berty.tech/go-ipfs-log/log" +package ipfslog // import "berty.tech/go-ipfs-log" import ( + "errors" "time" + "berty.tech/go-ipfs-log/entry/sorting" + "berty.tech/go-ipfs-log/entry" "berty.tech/go-ipfs-log/errmsg" "berty.tech/go-ipfs-log/io" - "berty.tech/go-ipfs-log/utils/lamportclock" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" cbornode "github.com/ipfs/go-ipld-cbor" - "github.com/pkg/errors" ) type FetchOptions struct { @@ -19,7 +20,7 @@ type FetchOptions struct { Timeout time.Duration } -func ToMultihash(services io.IpfsServices, log *Log) (cid.Cid, error) { +func toMultihash(services io.IpfsServices, log *Log) (cid.Cid, error) { if log.Values().Len() < 1 { return cid.Cid{}, errors.New(`can't serialize an empty log`) } @@ -27,7 +28,7 @@ func ToMultihash(services io.IpfsServices, log *Log) (cid.Cid, error) { return io.WriteCBOR(services, log.ToJSON()) } -func FromMultihash(services io.IpfsServices, hash cid.Cid, options *FetchOptions) (*Snapshot, error) { +func fromMultihash(services io.IpfsServices, hash cid.Cid, options *FetchOptions) (*snapshot, error) { result, err := io.ReadCBOR(services, hash) if err != nil { return nil, err @@ -46,14 +47,14 @@ func FromMultihash(services io.IpfsServices, hash cid.Cid, options *FetchOptions }) // Find latest clock - var clock *lamportclock.LamportClock + var clock *entry.LamportClock for _, e := range entries { if clock == nil || e.Clock.Time > clock.Time { - clock = lamportclock.New(e.Clock.ID, e.Clock.Time) + clock = entry.NewLamportClock(e.Clock.ID, e.Clock.Time) } } - entry.Sort(entry.Compare, entries) + sorting.Sort(sorting.Compare, entries) heads := []*entry.Entry{} for _, e := range entries { @@ -69,7 +70,7 @@ func FromMultihash(services io.IpfsServices, hash cid.Cid, options *FetchOptions headsCids = append(headsCids, head.Hash) } - return &Snapshot{ + return &snapshot{ ID: logData.ID, Values: entries, Heads: headsCids, @@ -77,7 +78,7 @@ func FromMultihash(services io.IpfsServices, hash cid.Cid, options *FetchOptions }, nil } -func FromEntryHash(services io.IpfsServices, hashes []cid.Cid, options *FetchOptions) ([]*entry.Entry, error) { +func fromEntryHash(services io.IpfsServices, hashes []cid.Cid, options *FetchOptions) ([]*entry.Entry, error) { if services == nil { return nil, errmsg.IPFSNotDefined } @@ -106,7 +107,7 @@ func FromEntryHash(services io.IpfsServices, hashes []cid.Cid, options *FetchOpt return sliced, nil } -func FromJSON(services io.IpfsServices, jsonLog *JSONLog, options *entry.FetchOptions) (*Snapshot, error) { +func fromJSON(services io.IpfsServices, jsonLog *JSONLog, options *entry.FetchOptions) (*snapshot, error) { if services == nil { return nil, errmsg.IPFSNotDefined } @@ -123,16 +124,16 @@ func FromJSON(services io.IpfsServices, jsonLog *JSONLog, options *entry.FetchOp Timeout: options.Timeout, }) - entry.Sort(entry.Compare, entries) + sorting.Sort(sorting.Compare, entries) - return &Snapshot{ + return &snapshot{ ID: jsonLog.ID, Heads: jsonLog.Heads, Values: entries, }, nil } -func FromEntry(services io.IpfsServices, sourceEntries []*entry.Entry, options *entry.FetchOptions) (*Snapshot, error) { +func fromEntry(services io.IpfsServices, sourceEntries []*entry.Entry, options *entry.FetchOptions) (*snapshot, error) { if services == nil { return nil, errmsg.IPFSNotDefined } @@ -163,22 +164,73 @@ func FromEntry(services io.IpfsServices, sourceEntries []*entry.Entry, options * // Combine the fetches with the source entries and take only uniques combined := append(sourceEntries, entries...) uniques := entry.NewOrderedMapFromEntries(combined).Slice() - entry.Sort(entry.Compare, uniques) + sorting.Sort(sorting.Compare, uniques) // Cap the result at the right size by taking the last n entries var sliced []*entry.Entry if length > -1 { - sliced = entry.Slice(uniques, -length) + sliced = entrySlice(uniques, -length) } else { sliced = uniques } missingSourceEntries := entry.Difference(sliced, sourceEntries) - result := append(missingSourceEntries, entry.SliceRange(sliced, len(missingSourceEntries), len(sliced))...) + result := append(missingSourceEntries, entrySliceRange(sliced, len(missingSourceEntries), len(sliced))...) - return &Snapshot{ + return &snapshot{ ID: result[len(result)-1].LogID, Values: result, }, nil } + +func entrySlice(entries []*entry.Entry, index int) []*entry.Entry { + if len(entries) == 0 || index >= len(entries) { + return []*entry.Entry{} + } + + if index == 0 || (index < 0 && -index >= len(entries)) { + return entries + } + + if index > 0 { + return entries[index:] + } + + return entries[(len(entries) + index):] +} + +func entrySliceRange(entries []*entry.Entry, from int, to int) []*entry.Entry { + if len(entries) == 0 { + return []*entry.Entry{} + } + + if from < 0 { + from = len(entries) + from + if from < 0 { + from = 0 + } + } + + if to < 0 { + to = len(entries) + to + } + + if from >= len(entries) { + return []*entry.Entry{} + } + + if to > len(entries) { + to = len(entries) + } + + if from >= to { + return []*entry.Entry{} + } + + if from == to { + return entries + } + + return entries[from:to] +} diff --git a/test/entry_io_test.go b/test/entry_io_test.go index c7caa69..358eb8e 100644 --- a/test/entry_io_test.go +++ b/test/entry_io_test.go @@ -7,11 +7,12 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" + "berty.tech/go-ipfs-log/entry" idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -48,7 +49,7 @@ func TestEntryPersistence(t *testing.T) { Convey("Entry - Persistency", t, FailureHalts, func(c C) { c.Convey("log with 1 entry", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) e, err := log1.Append([]byte("one"), 1) c.So(err, ShouldBeNil) @@ -59,7 +60,7 @@ func TestEntryPersistence(t *testing.T) { }) c.Convey("log with 2 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("one"), 1) c.So(err, ShouldBeNil) @@ -72,7 +73,7 @@ func TestEntryPersistence(t *testing.T) { }) c.Convey("loads max 1 entry from a log of 2 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("one"), 1) c.So(err, ShouldBeNil) @@ -88,7 +89,7 @@ func TestEntryPersistence(t *testing.T) { var e *entry.Entry var err error - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 0; i < 100; i++ { e, err = log1.Append([]byte(fmt.Sprintf("hello%d", i)), 1) @@ -101,17 +102,17 @@ func TestEntryPersistence(t *testing.T) { }) c.Convey("load only 42 entries from a log with 100 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 0; i < 100; i++ { _, err := log1.Append([]byte(fmt.Sprintf("hello%d", i)), 1) c.So(err, ShouldBeNil) if i%10 == 0 { - heads := append(log.FindHeads(log2.Entries), log.FindHeads(log1.Entries)...) - log2, err = log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: log2.ID, Entries: log2.Values(), Heads: heads}) + heads := append(entry.FindHeads(log2.Entries), entry.FindHeads(log1.Entries)...) + log2, err = ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: log2.ID, Entries: log2.Values(), Heads: heads}) c.So(err, ShouldBeNil) _, err := log2.Append([]byte(fmt.Sprintf("hi%d", i)), 1) c.So(err, ShouldBeNil) @@ -121,22 +122,22 @@ func TestEntryPersistence(t *testing.T) { hash, err := log1.ToMultihash() c.So(err, ShouldBeNil) - res, err := log.NewFromMultihash(ipfs, identities[0], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(42)}) + res, err := ipfslog.NewFromMultihash(ipfs, identities[0], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(42)}) c.So(err, ShouldBeNil) c.So(res.Entries.Len(), ShouldEqual, 42) }) c.Convey("load only 99 entries from a log with 100 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 0; i < 100; i++ { _, err := log1.Append([]byte(fmt.Sprintf("hello%d", i)), 1) c.So(err, ShouldBeNil) if i%10 == 0 { - log2, err = log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: log2.ID, Entries: log2.Values()}) + log2, err = ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: log2.ID, Entries: log2.Values()}) c.So(err, ShouldBeNil) _, err := log2.Append([]byte(fmt.Sprintf("hi%d", i)), 1) c.So(err, ShouldBeNil) @@ -148,24 +149,24 @@ func TestEntryPersistence(t *testing.T) { hash, err := log2.ToMultihash() c.So(err, ShouldBeNil) - res, err := log.NewFromMultihash(ipfs, identities[0], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(99)}) + res, err := ipfslog.NewFromMultihash(ipfs, identities[0], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(99)}) c.So(err, ShouldBeNil) c.So(res.Entries.Len(), ShouldEqual, 99) }) c.Convey("load only 10 entries from a log with 100 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 0; i < 100; i++ { _, err := log1.Append([]byte(fmt.Sprintf("hello%d", i)), 1) c.So(err, ShouldBeNil) if i%10 == 0 { - log2, err = log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: log2.ID, Entries: log2.Values(), Heads: log.FindHeads(log2.Entries)}) + log2, err = ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: log2.ID, Entries: log2.Values(), Heads: entry.FindHeads(log2.Entries)}) c.So(err, ShouldBeNil) _, err := log2.Append([]byte(fmt.Sprintf("hi%d", i)), 1) c.So(err, ShouldBeNil) @@ -173,8 +174,8 @@ func TestEntryPersistence(t *testing.T) { c.So(err, ShouldBeNil) } if i%25 == 0 { - heads := append(log.FindHeads(log3.Entries), log.FindHeads(log2.Entries)...) - log3, err = log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: log3.ID, Entries: log3.Values(), Heads: heads}) + heads := append(entry.FindHeads(log3.Entries), entry.FindHeads(log2.Entries)...) + log3, err = ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: log3.ID, Entries: log3.Values(), Heads: heads}) c.So(err, ShouldBeNil) _, err := log3.Append([]byte(fmt.Sprintf("--%d", i)), 1) c.So(err, ShouldBeNil) @@ -187,17 +188,17 @@ func TestEntryPersistence(t *testing.T) { hash, err := log3.ToMultihash() c.So(err, ShouldBeNil) - res, err := log.NewFromMultihash(ipfs, identities[0], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(10)}) + res, err := ipfslog.NewFromMultihash(ipfs, identities[0], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(10)}) c.So(err, ShouldBeNil) c.So(res.Entries.Len(), ShouldEqual, 10) }) c.Convey("load only 10 entries and then expand to max from a log with 100 entries", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 0; i < 30; i++ { @@ -210,8 +211,8 @@ func TestEntryPersistence(t *testing.T) { c.So(err, ShouldBeNil) } if i%25 == 0 { - heads := append(log.FindHeads(log3.Entries), log.FindHeads(log2.Entries)...) - log3, err = log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: log3.ID, Entries: log3.Values(), Heads: heads}) + heads := append(entry.FindHeads(log3.Entries), entry.FindHeads(log2.Entries)...) + log3, err = ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: log3.ID, Entries: log3.Values(), Heads: heads}) c.So(err, ShouldBeNil) _, err := log3.Append([]byte(fmt.Sprintf("--%d", i)), 1) c.So(err, ShouldBeNil) @@ -221,7 +222,7 @@ func TestEntryPersistence(t *testing.T) { _, err = log3.Join(log2, -1) c.So(err, ShouldBeNil) - log4, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log4, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) _, err = log4.Join(log2, -1) c.So(err, ShouldBeNil) diff --git a/test/entry_test.go b/test/entry_test.go index 7784205..a44f446 100644 --- a/test/entry_test.go +++ b/test/entry_test.go @@ -123,7 +123,7 @@ func TestEntry(t *testing.T) { expectedHash := "bafyreidbxpymnb357glm2cujnjcfmg7rge4ybpurgllpvp57kvk7xrmf2e" e, err := entry.CreateEntry(ipfs, identity, &entry.Entry{Payload: []byte("hello"), LogID: "A"}, nil) c.So(err, ShouldBeNil) - hash, err := entry.ToMultihash(ipfs, e) + hash, err := e.ToMultihash(ipfs) c.So(err, ShouldBeNil) c.So(e.Hash.String(), ShouldEqual, expectedHash) @@ -150,7 +150,7 @@ func TestEntry(t *testing.T) { e2, err := entry.CreateEntry(ipfs, identity, &entry.Entry{Payload: []byte(payload2), LogID: "A", Next: []cid.Cid{e1.Hash}}, nil) c.So(err, ShouldBeNil) - c.So(entry.IsParent(e1, e2), ShouldBeTrue) + c.So(e1.IsParent(e2), ShouldBeTrue) }) c.Convey("returns false if entry has a child", FailureContinues, func(c C) { @@ -163,9 +163,9 @@ func TestEntry(t *testing.T) { e3, err := entry.CreateEntry(ipfs, identity, &entry.Entry{Payload: []byte(payload2), LogID: "A", Next: []cid.Cid{e2.Hash}}, nil) c.So(err, ShouldBeNil) - c.So(entry.IsParent(e1, e2), ShouldBeFalse) - c.So(entry.IsParent(e1, e3), ShouldBeFalse) - c.So(entry.IsParent(e2, e3), ShouldBeTrue) + c.So(e1.IsParent(e2), ShouldBeFalse) + c.So(e1.IsParent(e3), ShouldBeFalse) + c.So(e2.IsParent(e3), ShouldBeTrue) }) }) @@ -177,7 +177,7 @@ func TestEntry(t *testing.T) { e2, err := entry.CreateEntry(ipfs, identity, &entry.Entry{Payload: []byte(payload1), LogID: "A"}, nil) c.So(err, ShouldBeNil) - c.So(entry.IsEqual(e1, e2), ShouldBeTrue) + c.So(e1.Equals(e2), ShouldBeTrue) }) c.Convey("returns true if entries are not the same", FailureContinues, func(c C) { @@ -188,7 +188,7 @@ func TestEntry(t *testing.T) { e2, err := entry.CreateEntry(ipfs, identity, &entry.Entry{Payload: []byte(payload2), LogID: "A"}, nil) c.So(err, ShouldBeNil) - c.So(entry.IsEqual(e1, e2), ShouldBeFalse) + c.So(e1.Equals(e2), ShouldBeFalse) }) }) diff --git a/test/log_append_test.go b/test/log_append_test.go index ffba68a..c16db57 100644 --- a/test/log_append_test.go +++ b/test/log_append_test.go @@ -6,9 +6,11 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" + "berty.tech/go-ipfs-log/entry" + idp "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -39,7 +41,7 @@ func TestLogAppend(t *testing.T) { Convey("Log - Append", t, FailureHalts, func(c C) { c.Convey("append", FailureHalts, func(c C) { c.Convey("append one", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identity, &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identity, &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("hello1"), 1) c.So(err, ShouldBeNil) @@ -55,13 +57,13 @@ func TestLogAppend(t *testing.T) { c.So(v.Clock.ID, ShouldResemble, identity.PublicKey) c.So(v.Clock.Time, ShouldEqual, 1) } - for _, v := range log.FindHeads(log1.Entries) { + for _, v := range entry.FindHeads(log1.Entries) { c.So(v.Hash.String(), ShouldEqual, values.UnsafeGet(keys[0]).Hash.String()) } }) c.Convey("append 100 items to a log", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identity, &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identity, &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) nextPointerAmount := 64 @@ -71,7 +73,7 @@ func TestLogAppend(t *testing.T) { values := log1.Values() keys := values.Keys() - heads := log.FindHeads(log1.Entries) + heads := entry.FindHeads(log1.Entries) c.So(len(heads), ShouldEqual, 1) c.So(heads[0].Hash.String(), ShouldEqual, values.UnsafeGet(keys[len(keys)-1]).Hash.String()) diff --git a/test/log_heads_tails_test.go b/test/log_heads_tails_test.go index 2e36d9b..c0e3406 100644 --- a/test/log_heads_tails_test.go +++ b/test/log_heads_tails_test.go @@ -6,9 +6,12 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" + + "berty.tech/go-ipfs-log/entry" + idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" @@ -48,29 +51,29 @@ func TestLogHeadsTails(t *testing.T) { Convey("Log - heads and Tails", t, FailureContinues, func(c C) { c.Convey("heads", FailureContinues, func(c C) { c.Convey("finds one head after one entry", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 1) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 1) }) c.Convey("finds one head after two entry", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA2"), 1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 1) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 1) }) c.Convey("finds head after a join and append", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) @@ -87,14 +90,14 @@ func TestLogHeadsTails(t *testing.T) { lastEntry := getLastEntry(log2.Values()) - c.So(len(log.FindHeads(log2.Entries)), ShouldEqual, 1) - c.So(log.FindHeads(log2.Entries)[0].Hash.String(), ShouldEqual, lastEntry.Hash.String()) + c.So(len(entry.FindHeads(log2.Entries)), ShouldEqual, 1) + c.So(entry.FindHeads(log2.Entries)[0].Hash.String(), ShouldEqual, lastEntry.Hash.String()) }) c.Convey("finds two heads after a join", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) @@ -112,15 +115,15 @@ func TestLogHeadsTails(t *testing.T) { _, err = log1.Join(log2, -1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 2) - c.So(log.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) - c.So(log.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 2) + c.So(entry.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) + c.So(entry.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) }) c.Convey("finds two heads after two joins", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) @@ -150,17 +153,17 @@ func TestLogHeadsTails(t *testing.T) { _, err = log1.Join(log2, -1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 2) - c.So(log.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) - c.So(log.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 2) + c.So(entry.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) + c.So(entry.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) }) c.Convey("finds two heads after three joins", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) @@ -190,17 +193,17 @@ func TestLogHeadsTails(t *testing.T) { _, err = log1.Join(log2, -1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 2) - c.So(log.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) - c.So(log.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 2) + c.So(entry.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) + c.So(entry.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) }) c.Convey("finds three heads after three joins", FailureContinues, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = log1.Append([]byte("helloA1"), 1) @@ -231,17 +234,17 @@ func TestLogHeadsTails(t *testing.T) { _, err = log1.Join(log3, -1) c.So(err, ShouldBeNil) - c.So(len(log.FindHeads(log1.Entries)), ShouldEqual, 3) - c.So(log.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) - c.So(log.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) - c.So(log.FindHeads(log1.Entries)[2].Hash.String(), ShouldEqual, lastEntry3.Hash.String()) + c.So(len(entry.FindHeads(log1.Entries)), ShouldEqual, 3) + c.So(entry.FindHeads(log1.Entries)[0].Hash.String(), ShouldEqual, lastEntry1.Hash.String()) + c.So(entry.FindHeads(log1.Entries)[1].Hash.String(), ShouldEqual, lastEntry2.Hash.String()) + c.So(entry.FindHeads(log1.Entries)[2].Hash.String(), ShouldEqual, lastEntry3.Hash.String()) }) }) c.Convey("tails", FailureContinues, func(c C) { // TODO: implements findTails(orderedmap) // c.Convey("returns a tail", FailureContinues, func(c C) { - // log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + // log1, err := log.NewLog(ipfs, identities[0], &log.LogOptions{ID: "A"}) // c.So(err, ShouldBeNil) // _, err = log1.Append([]byte("helloA1"), 1) // c.So(err, ShouldBeNil) @@ -250,9 +253,9 @@ func TestLogHeadsTails(t *testing.T) { // }) // c.Convey("returns tail entries", FailureContinues, func(c C) { - // log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + // log1, err := log.NewLog(ipfs, identities[0], &log.LogOptions{ID: "A"}) // c.So(err, ShouldBeNil) - // log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + // log2, err := log.NewLog(ipfs, identities[0], &log.LogOptions{ID: "A"}) // c.So(err, ShouldBeNil) // _, err = log1.Append([]byte("helloA1"), 1) // c.So(err, ShouldBeNil) diff --git a/test/log_join_test.go b/test/log_join_test.go index a140c15..53dc942 100644 --- a/test/log_join_test.go +++ b/test/log_join_test.go @@ -7,13 +7,13 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" + "berty.tech/go-ipfs-log/entry" "berty.tech/go-ipfs-log/errmsg" idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" - "berty.tech/go-ipfs-log/utils/lamportclock" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -50,10 +50,10 @@ func TestLogJoin(t *testing.T) { Convey("Log - Join", t, FailureHalts, func(c C) { c.Convey("join", FailureHalts, func(c C) { - var logs []*log.Log + var logs []*ipfslog.Log for i := 0; i < 4; i++ { - l, err := log.NewLog(ipfs, identities[i], &log.NewLogOptions{ID: "X"}) + l, err := ipfslog.NewLog(ipfs, identities[i], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) logs = append(logs, l) @@ -91,24 +91,19 @@ func TestLogJoin(t *testing.T) { // Here we're creating a log from entries signed by A and B // but we accept entries from C too - logA, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{items[1][len(items[1])-1]}, &log.NewLogOptions{}, &entry.FetchOptions{}) + logA, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{items[1][len(items[1])-1]}, &ipfslog.LogOptions{}, &entry.FetchOptions{}) c.So(err, ShouldBeNil) // Here we're creating a log from entries signed by peer A, B and C // "logA" accepts entries from peer C so we can join logs A and B - logB, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{items[2][len(items[2])-1]}, &log.NewLogOptions{}, &entry.FetchOptions{}) + logB, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{items[2][len(items[2])-1]}, &ipfslog.LogOptions{}, &entry.FetchOptions{}) c.So(err, ShouldBeNil) - c.So(entry.EntriesAsStrings(logA.Values().Slice()), ShouldResemble, entry.EntriesAsStrings(append(items[0], items[1]...))) - c.So(entry.EntriesAsStrings(logB.Values().Slice()), ShouldResemble, entry.EntriesAsStrings(append(items[0], append(items[1], items[2]...)...))) - _, err = logA.Join(logB, -1) c.So(err, ShouldBeNil) - c.So(entry.EntriesAsStrings(logA.Values().Slice()), ShouldResemble, entry.EntriesAsStrings(append(items[0], append(items[1], items[2]...)...))) - // The last entry, 'entryC100', should be the only head // (it points to entryB100, entryB100 and entryC99) - c.So(len(log.FindHeads(logA.Entries)), ShouldEqual, 1) + c.So(len(entry.FindHeads(logA.Entries)), ShouldEqual, 1) }) c.Convey("returns error if log parameter is not defined", FailureHalts, func() { @@ -439,19 +434,19 @@ func TestLogJoin(t *testing.T) { c.So(logs[3].Clock.Time, ShouldEqual, 8) expected := []entry.Entry{ - entry.Entry{Payload: []byte("helloA1"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[0].PublicKey, Time: 1}}, - entry.Entry{Payload: []byte("helloB1"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[1].PublicKey, Time: 1}}, - entry.Entry{Payload: []byte("helloD1"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 1}}, - entry.Entry{Payload: []byte("helloA2"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[0].PublicKey, Time: 2}}, - entry.Entry{Payload: []byte("helloB2"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[1].PublicKey, Time: 2}}, - entry.Entry{Payload: []byte("helloD2"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 2}}, - entry.Entry{Payload: []byte("helloC1"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[2].PublicKey, Time: 3}}, - entry.Entry{Payload: []byte("helloC2"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[2].PublicKey, Time: 4}}, - entry.Entry{Payload: []byte("helloD3"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 5}}, - entry.Entry{Payload: []byte("helloD4"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 6}}, - entry.Entry{Payload: []byte("helloA5"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[0].PublicKey, Time: 7}}, - entry.Entry{Payload: []byte("helloD5"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 7}}, - entry.Entry{Payload: []byte("helloD6"), LogID: "X", Clock: &lamportclock.LamportClock{ID: identities[3].PublicKey, Time: 8}}, + {Payload: []byte("helloA1"), LogID: "X", Clock: &entry.LamportClock{ID: identities[0].PublicKey, Time: 1}}, + {Payload: []byte("helloB1"), LogID: "X", Clock: &entry.LamportClock{ID: identities[1].PublicKey, Time: 1}}, + {Payload: []byte("helloD1"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 1}}, + {Payload: []byte("helloA2"), LogID: "X", Clock: &entry.LamportClock{ID: identities[0].PublicKey, Time: 2}}, + {Payload: []byte("helloB2"), LogID: "X", Clock: &entry.LamportClock{ID: identities[1].PublicKey, Time: 2}}, + {Payload: []byte("helloD2"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 2}}, + {Payload: []byte("helloC1"), LogID: "X", Clock: &entry.LamportClock{ID: identities[2].PublicKey, Time: 3}}, + {Payload: []byte("helloC2"), LogID: "X", Clock: &entry.LamportClock{ID: identities[2].PublicKey, Time: 4}}, + {Payload: []byte("helloD3"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 5}}, + {Payload: []byte("helloD4"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 6}}, + {Payload: []byte("helloA5"), LogID: "X", Clock: &entry.LamportClock{ID: identities[0].PublicKey, Time: 7}}, + {Payload: []byte("helloD5"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 7}}, + {Payload: []byte("helloD6"), LogID: "X", Clock: &entry.LamportClock{ID: identities[3].PublicKey, Time: 8}}, } c.So(logs[3].Values().Len(), ShouldEqual, 13) diff --git a/test/log_load_test.go b/test/log_load_test.go index 4174093..ff3cb97 100644 --- a/test/log_load_test.go +++ b/test/log_load_test.go @@ -10,12 +10,15 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" + + "berty.tech/go-ipfs-log/entry/sorting" + "berty.tech/go-ipfs-log/entry" idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" "berty.tech/go-ipfs-log/test/logcreator" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -75,13 +78,13 @@ func TestLogLoad(t *testing.T) { //heads := map[string]*entry.Entry{} // //for _, h := range json.Heads { - // e, err := entry.FromMultihash(ipfs, h, identities[0].Provider) + // e, err := entry.fromMultihash(ipfs, h, identities[0].Provider) // c.So(err, ShouldBeNil) // // heads[e.Hash.String()] = e //} - l, err := log.NewFromJSON(ipfs, identities[0], json, &log.NewLogOptions{ID: "X"}, &entry.FetchOptions{}) + l, err := ipfslog.NewFromJSON(ipfs, identities[0], json, &ipfslog.LogOptions{ID: "X"}, &entry.FetchOptions{}) c.So(err, ShouldBeNil) values := l.Values() @@ -98,7 +101,7 @@ func TestLogLoad(t *testing.T) { data := fixture.Log json := fixture.JSON - l, err := log.NewFromJSON(ipfs, identities[0], json, &log.NewLogOptions{ID: "X", SortFn: log.FirstWriteWins}, &entry.FetchOptions{Length: intPtr(-1)}) + l, err := ipfslog.NewFromJSON(ipfs, identities[0], json, &ipfslog.LogOptions{ID: "X", SortFn: sorting.FirstWriteWins}, &entry.FetchOptions{Length: intPtr(-1)}) c.So(err, ShouldBeNil) c.So(l.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -118,8 +121,8 @@ func TestLogLoad(t *testing.T) { data := fixture.Log json := fixture.JSON - log1, err := log.NewFromEntryHash(ipfs, identities[0], json.Heads[0], &log.NewLogOptions{ID: "X"}, &log.FetchOptions{}) - log2, err := log.NewFromEntryHash(ipfs, identities[0], json.Heads[1], &log.NewLogOptions{ID: "X"}, &log.FetchOptions{}) + log1, err := ipfslog.NewFromEntryHash(ipfs, identities[0], json.Heads[0], &ipfslog.LogOptions{ID: "X"}, &ipfslog.FetchOptions{}) + log2, err := ipfslog.NewFromEntryHash(ipfs, identities[0], json.Heads[1], &ipfslog.LogOptions{ID: "X"}, &ipfslog.FetchOptions{}) _, err = log1.Join(log2, -1) c.So(err, ShouldBeNil) @@ -136,8 +139,8 @@ func TestLogLoad(t *testing.T) { data := fixture.Log json := fixture.JSON - log1, err := log.NewFromEntryHash(ipfs, identities[0], json.Heads[0], &log.NewLogOptions{ID: "X", SortFn: log.FirstWriteWins}, &log.FetchOptions{}) - log2, err := log.NewFromEntryHash(ipfs, identities[0], json.Heads[1], &log.NewLogOptions{ID: "X", SortFn: log.FirstWriteWins}, &log.FetchOptions{}) + log1, err := ipfslog.NewFromEntryHash(ipfs, identities[0], json.Heads[0], &ipfslog.LogOptions{ID: "X", SortFn: sorting.FirstWriteWins}, &ipfslog.FetchOptions{}) + log2, err := ipfslog.NewFromEntryHash(ipfs, identities[0], json.Heads[1], &ipfslog.LogOptions{ID: "X", SortFn: sorting.FirstWriteWins}, &ipfslog.FetchOptions{}) _, err = log1.Join(log2, -1) c.So(err, ShouldBeNil) @@ -157,7 +160,7 @@ func TestLogLoad(t *testing.T) { data := fixture.Log - l, err := log.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &log.NewLogOptions{}, &entry.FetchOptions{}) + l, err := ipfslog.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &ipfslog.LogOptions{}, &entry.FetchOptions{}) c.So(err, ShouldBeNil) c.So(l.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -171,7 +174,7 @@ func TestLogLoad(t *testing.T) { data := fixture.Log - l, err := log.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &log.NewLogOptions{SortFn: log.FirstWriteWins}, &entry.FetchOptions{Length: intPtr(-1)}) + l, err := ipfslog.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &ipfslog.LogOptions{SortFn: sorting.FirstWriteWins}, &entry.FetchOptions{Length: intPtr(-1)}) c.So(err, ShouldBeNil) c.So(l.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -185,7 +188,7 @@ func TestLogLoad(t *testing.T) { data := fixture.Log - log1, err := log.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(data.Heads().Len())}) + log1, err := ipfslog.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(data.Heads().Len())}) c.So(err, ShouldBeNil) c.So(log1.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -193,7 +196,7 @@ func TestLogLoad(t *testing.T) { c.So(string(log1.Values().At(0).Payload), ShouldEqual, "entryC0") c.So(string(log1.Values().At(1).Payload), ShouldEqual, "entryA10") - log2, err := log.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(4)}) + log2, err := ipfslog.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(4)}) c.So(err, ShouldBeNil) c.So(log2.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -203,7 +206,7 @@ func TestLogLoad(t *testing.T) { c.So(string(log2.Values().At(2).Payload), ShouldEqual, "entryA9") c.So(string(log2.Values().At(3).Payload), ShouldEqual, "entryA10") - log3, err := log.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(7)}) + log3, err := ipfslog.NewFromEntry(ipfs, identities[0], data.Heads().Slice(), &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(7)}) c.So(err, ShouldBeNil) c.So(log3.ID, ShouldEqual, data.Heads().At(0).LogID) @@ -222,13 +225,13 @@ func TestLogLoad(t *testing.T) { }) c.Convey("retrieves partial log from an entry hash", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) var items1 []*entry.Entry @@ -273,24 +276,24 @@ func TestLogLoad(t *testing.T) { } // limit to 10 entries - a, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(10)}) + a, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(10)}) c.So(err, ShouldBeNil) c.So(a.Values().Len(), ShouldEqual, 10) // limit to 42 entries - b, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(42)}) + b, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(42)}) c.So(err, ShouldBeNil) c.So(b.Values().Len(), ShouldEqual, 42) }) c.Convey("retrieves full log from an entry hash", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) var items1 []*entry.Entry @@ -334,27 +337,27 @@ func TestLogLoad(t *testing.T) { items3 = append(items3, n3) } - lA, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) + lA, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) c.So(err, ShouldBeNil) c.So(lA.Values().Len(), ShouldEqual, amount) - lB, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items2)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) + lB, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items2)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) c.So(err, ShouldBeNil) c.So(lB.Values().Len(), ShouldEqual, amount*2) - lC, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items3)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) + lC, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items3)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) c.So(err, ShouldBeNil) c.So(lC.Values().Len(), ShouldEqual, amount*3) }) c.Convey("retrieves full log from an entry hash 2", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) var items1 []*entry.Entry @@ -398,27 +401,27 @@ func TestLogLoad(t *testing.T) { items3 = append(items3, n3) } - lA, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) + lA, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) c.So(err, ShouldBeNil) c.So(lA.Values().Len(), ShouldEqual, amount) - lB, err := log.NewFromEntry(ipfs, identities[1], []*entry.Entry{lastEntry(items2)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) + lB, err := ipfslog.NewFromEntry(ipfs, identities[1], []*entry.Entry{lastEntry(items2)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) c.So(err, ShouldBeNil) c.So(lB.Values().Len(), ShouldEqual, amount*2) - lC, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(items3)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) + lC, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(items3)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) c.So(err, ShouldBeNil) c.So(lC.Values().Len(), ShouldEqual, amount*3) }) c.Convey("retrieves full log from an entry hash 3", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) var items1 []*entry.Entry @@ -474,7 +477,7 @@ func TestLogLoad(t *testing.T) { items3 = append(items3, n3) } - lA, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) + lA, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 1)}) c.So(err, ShouldBeNil) c.So(lA.Values().Len(), ShouldEqual, amount) @@ -501,12 +504,12 @@ func TestLogLoad(t *testing.T) { "entryB10", } - lB, err := log.NewFromEntry(ipfs, identities[1], []*entry.Entry{lastEntry(items2)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) + lB, err := ipfslog.NewFromEntry(ipfs, identities[1], []*entry.Entry{lastEntry(items2)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 2)}) c.So(err, ShouldBeNil) c.So(lB.Values().Len(), ShouldEqual, amount*2) c.So(entriesAsStrings(lB.Values()), ShouldResemble, itemsInB) - lC, err := log.NewFromEntry(ipfs, identities[3], []*entry.Entry{lastEntry(items3)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) + lC, err := ipfslog.NewFromEntry(ipfs, identities[3], []*entry.Entry{lastEntry(items3)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(amount * 3)}) c.So(err, ShouldBeNil) _, err = lC.Append([]byte("EOF"), 1) @@ -551,7 +554,7 @@ func TestLogLoad(t *testing.T) { c.So(entriesAsStrings(lC.Values()), ShouldResemble, tmp) // make sure logX comes after A, B and C - logX, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + logX, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) _, err = logX.Append([]byte{'1'}, 1) @@ -563,7 +566,7 @@ func TestLogLoad(t *testing.T) { _, err = logX.Append([]byte{'3'}, 1) c.So(err, ShouldBeNil) - lD, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(logX.Values().Slice())}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(-1)}) + lD, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(logX.Values().Slice())}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(-1)}) c.So(err, ShouldBeNil) _, err = lC.Join(lD, -1) @@ -578,10 +581,10 @@ func TestLogLoad(t *testing.T) { _, err = lD.Append([]byte("DONE"), 1) c.So(err, ShouldBeNil) - logF, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(lC.Values().Slice())}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(-1), Exclude: nil}) + logF, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(lC.Values().Slice())}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(-1), Exclude: nil}) c.So(err, ShouldBeNil) - logG, err := log.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(lD.Values().Slice())}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(-1), Exclude: nil}) + logG, err := ipfslog.NewFromEntry(ipfs, identities[2], []*entry.Entry{lastEntry(lD.Values().Slice())}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(-1), Exclude: nil}) c.So(err, ShouldBeNil) c.So(logF.ToString(nil), ShouldEqual, bigLogString) @@ -589,13 +592,13 @@ func TestLogLoad(t *testing.T) { }) c.Convey("retrieves full log of randomly joined log", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 1; i <= 5; i++ { @@ -635,16 +638,16 @@ func TestLogLoad(t *testing.T) { }) c.Convey("retrieves randomly joined log deterministically", FailureHalts, func(c C) { - logA, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + logA, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - logB, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + logB, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - l, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + l, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 1; i <= 5; i++ { @@ -715,19 +718,19 @@ func TestLogLoad(t *testing.T) { } fetchOrder := l.Values().Slice() - entry.Sort(entry.Compare, fetchOrder) + sorting.Sort(sorting.Compare, fetchOrder) c.So(entriesAsStrings(entry.NewOrderedMapFromEntries(fetchOrder)), ShouldResemble, expectedData) reverseOrder := l.Values().Slice() - log.Reverse(reverseOrder) - entry.Sort(entry.Compare, reverseOrder) + sorting.Reverse(reverseOrder) + sorting.Sort(sorting.Compare, reverseOrder) c.So(entriesAsStrings(entry.NewOrderedMapFromEntries(reverseOrder)), ShouldResemble, expectedData) hashOrder := l.Values().Slice() - entry.Sort(func(a, b *entry.Entry) (int, error) { + sorting.Sort(func(a, b *entry.Entry) (int, error) { return strings.Compare(a.Hash.String(), b.Hash.String()), nil }, hashOrder) - entry.Sort(entry.Compare, hashOrder) + sorting.Sort(sorting.Compare, hashOrder) c.So(entriesAsStrings(entry.NewOrderedMapFromEntries(hashOrder)), ShouldResemble, expectedData) var partialLog []*entry.Entry @@ -763,15 +766,15 @@ func TestLogLoad(t *testing.T) { expectedData := testLog.ExpectedData fetchOrder := l.Values().Slice() - entry.Sort(entry.Compare, fetchOrder) + sorting.Sort(sorting.Compare, fetchOrder) c.So(entriesAsStrings(entry.NewOrderedMapFromEntries(fetchOrder)), ShouldResemble, expectedData) for i := 0; i < 1000; i++ { randomOrder := l.Values().Slice() - entry.Sort(func(a, b *entry.Entry) (int, error) { + sorting.Sort(func(a, b *entry.Entry) (int, error) { return rand.Int(), nil }, randomOrder) - entry.Sort(entry.Compare, randomOrder) + sorting.Sort(sorting.Compare, randomOrder) c.So(entriesAsStrings(entry.NewOrderedMapFromEntries(randomOrder)), ShouldResemble, expectedData) } @@ -791,7 +794,7 @@ func TestLogLoad(t *testing.T) { testLog, err := logcreator.CreateLogWithSixteenEntries(ipfs, resortedIdentities) c.So(err, ShouldBeNil) - firstWriteWinsLog, err := log.NewLog(ipfs, resortedIdentities[0], &log.NewLogOptions{ID: "X", SortFn: BadComparatorReturnsZero}) + firstWriteWinsLog, err := ipfslog.NewLog(ipfs, resortedIdentities[0], &ipfslog.LogOptions{ID: "X", SortFn: BadComparatorReturnsZero}) c.So(err, ShouldBeNil) _, err = firstWriteWinsLog.Join(testLog.Log, -1) @@ -803,13 +806,13 @@ func TestLogLoad(t *testing.T) { c.Convey("retrieves partially joined log deterministically - single next pointer", FailureHalts, func(c C) { nextPointersAmount := 1 - logA, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + logA, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - logB, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + logB, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - l, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + l, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 1; i <= 5; i++ { @@ -843,7 +846,7 @@ func TestLogLoad(t *testing.T) { hash, err := l.ToMultihash() // First 5 - res, err := log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(5)}) + res, err := ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(5)}) c.So(err, ShouldBeNil) first5 := []string{ @@ -853,7 +856,7 @@ func TestLogLoad(t *testing.T) { c.So(entriesAsStrings(res.Values()), ShouldResemble, first5) // First 11 - res, err = log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(11)}) + res, err = ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(11)}) c.So(err, ShouldBeNil) first11 := []string{ @@ -866,7 +869,7 @@ func TestLogLoad(t *testing.T) { c.So(entriesAsStrings(res.Values()), ShouldResemble, first11) // All but one - res, err = log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(16 - 1)}) + res, err = ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(16 - 1)}) c.So(err, ShouldBeNil) all := []string{ @@ -883,13 +886,13 @@ func TestLogLoad(t *testing.T) { c.Convey("retrieves partially joined log deterministically - multiple next pointers", FailureHalts, func(c C) { nextPointersAmount := 64 - logA, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + logA, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - logB, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + logB, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - l, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + l, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) for i := 1; i <= 5; i++ { @@ -923,7 +926,7 @@ func TestLogLoad(t *testing.T) { hash, err := l.ToMultihash() // First 5 - res, err := log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(5)}) + res, err := ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(5)}) c.So(err, ShouldBeNil) first5 := []string{ @@ -933,7 +936,7 @@ func TestLogLoad(t *testing.T) { c.So(entriesAsStrings(res.Values()), ShouldResemble, first5) // First 11 - res, err = log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(11)}) + res, err = ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(11)}) c.So(err, ShouldBeNil) first11 := []string{ @@ -946,7 +949,7 @@ func TestLogLoad(t *testing.T) { c.So(entriesAsStrings(res.Values()), ShouldResemble, first11) // All but one - res, err = log.NewFromMultihash(ipfs, identities[1], hash, &log.NewLogOptions{}, &log.FetchOptions{Length: intPtr(16 - 1)}) + res, err = ipfslog.NewFromMultihash(ipfs, identities[1], hash, &ipfslog.LogOptions{}, &ipfslog.FetchOptions{Length: intPtr(16 - 1)}) c.So(err, ShouldBeNil) all := []string{ @@ -960,7 +963,7 @@ func TestLogLoad(t *testing.T) { }) c.Convey("throws an error if ipfs is not defined", FailureHalts, func(c C) { - _, err := log.NewFromEntry(nil, identities[0], []*entry.Entry{}, &log.NewLogOptions{ID: "X"}, &entry.FetchOptions{}) + _, err := ipfslog.NewFromEntry(nil, identities[0], []*entry.Entry{}, &ipfslog.LogOptions{ID: "X"}, &entry.FetchOptions{}) c.So(err, ShouldNotBeNil) c.So(err.Error(), ShouldContainSubstring, "ipfs instance not defined") }) @@ -969,13 +972,13 @@ func TestLogLoad(t *testing.T) { const amount = 100 ts := time.Now().UnixNano() / 1000 - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + log2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) - log3, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) c.So(err, ShouldBeNil) var items1 []*entry.Entry @@ -1026,7 +1029,7 @@ func TestLogLoad(t *testing.T) { } c.Convey("returns all entries - no excluded entries", FailureHalts, func(c C) { - a, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Length: intPtr(-1)}) + a, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Length: intPtr(-1)}) c.So(err, ShouldBeNil) c.So(a.Values().Len(), ShouldEqual, amount) @@ -1035,14 +1038,14 @@ func TestLogLoad(t *testing.T) { c.Convey("returns all entries - including excluded entries", FailureHalts, func(c C) { // One entry - a, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Exclude: []*entry.Entry{items1[0]}, Length: intPtr(-1)}) + a, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Exclude: []*entry.Entry{items1[0]}, Length: intPtr(-1)}) c.So(err, ShouldBeNil) c.So(a.Values().Len(), ShouldEqual, amount) c.So(a.Values().At(0).Hash.String(), ShouldEqual, items1[0].Hash.String()) // All entries - b, err := log.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &log.NewLogOptions{}, &entry.FetchOptions{Exclude: items1, Length: intPtr(-1)}) + b, err := ipfslog.NewFromEntry(ipfs, identities[0], []*entry.Entry{lastEntry(items1)}, &ipfslog.LogOptions{}, &entry.FetchOptions{Exclude: items1, Length: intPtr(-1)}) c.So(err, ShouldBeNil) c.So(b.Values().Len(), ShouldEqual, amount) diff --git a/test/log_test.go b/test/log_test.go index 4fe8641..2a7322e 100644 --- a/test/log_test.go +++ b/test/log_test.go @@ -7,13 +7,12 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" "berty.tech/go-ipfs-log/errmsg" "berty.tech/go-ipfs-log/entry" idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" - "berty.tech/go-ipfs-log/utils/lamportclock" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -52,7 +51,7 @@ func TestLog(t *testing.T) { Convey("Log", t, FailureHalts, func(c C) { c.Convey("constructor", FailureHalts, func(c C) { c.Convey("sets an id and a clock id", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) c.So(log1.ID, ShouldEqual, "A") c.So(log1.Clock.ID, ShouldResemble, identities[0].PublicKey) @@ -60,7 +59,7 @@ func TestLog(t *testing.T) { c.Convey("sets time.now as id string if id is not passed as an argument", FailureHalts, func(c C) { before := time.Now().Unix() / 1000 - log1, err := log.NewLog(ipfs, identities[0], nil) + log1, err := ipfslog.NewLog(ipfs, identities[0], nil) c.So(err, ShouldBeNil) after := time.Now().Unix() / 1000 @@ -90,14 +89,14 @@ func TestLog(t *testing.T) { }) c.So(err, ShouldBeNil) // TODO: Use time=0 and known public keys for all 3 entries - e1, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryA"), LogID: "A"}, lamportclock.New(id1.PublicKey, 0)) + e1, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryA"), LogID: "A"}, entry.NewLamportClock(id1.PublicKey, 0)) c.So(err, ShouldBeNil) - e2, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryB"), LogID: "A"}, lamportclock.New(id2.PublicKey, 1)) + e2, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryB"), LogID: "A"}, entry.NewLamportClock(id2.PublicKey, 1)) c.So(err, ShouldBeNil) - e3, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryC"), LogID: "A"}, lamportclock.New(id3.PublicKey, 2)) + e3, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryC"), LogID: "A"}, entry.NewLamportClock(id3.PublicKey, 2)) c.So(err, ShouldBeNil) - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3})}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3})}) c.So(err, ShouldBeNil) values := log1.Values() @@ -118,7 +117,7 @@ func TestLog(t *testing.T) { e3, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryC"), LogID: "A"}, nil) c.So(err, ShouldBeNil) - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "B", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3}), Heads: []*entry.Entry{e3}}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "B", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3}), Heads: []*entry.Entry{e3}}) c.So(err, ShouldBeNil) heads := log1.Heads() headsKeys := heads.Keys() @@ -135,7 +134,7 @@ func TestLog(t *testing.T) { e3, err := entry.CreateEntry(ipfs, identities[0], &entry.Entry{Payload: []byte("entryC"), LogID: "A"}, nil) c.So(err, ShouldBeNil) - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3})}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A", Entries: entry.NewOrderedMapFromEntries([]*entry.Entry{e1, e2, e3})}) c.So(err, ShouldBeNil) heads := log1.Heads() @@ -148,7 +147,7 @@ func TestLog(t *testing.T) { }) c.Convey("creates default public AccessController if not defined", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, identities[0], nil) + log1, err := ipfslog.NewLog(ipfs, identities[0], nil) c.So(err, ShouldBeNil) err = log1.AccessController.CanAppend(&entry.Entry{Payload: []byte("any")}, identities[0]) @@ -156,13 +155,13 @@ func TestLog(t *testing.T) { }) c.Convey("returns an error if ipfs is not net", FailureHalts, func(c C) { - log1, err := log.NewLog(nil, identities[0], nil) + log1, err := ipfslog.NewLog(nil, identities[0], nil) c.So(log1, ShouldBeNil) c.So(err.Error(), ShouldEqual, errmsg.IPFSNotDefined.Error()) }) c.Convey("returns an error if identity is not net", FailureHalts, func(c C) { - log1, err := log.NewLog(ipfs, nil, nil) + log1, err := ipfslog.NewLog(ipfs, nil, nil) c.So(log1, ShouldBeNil) c.So(err.Error(), ShouldEqual, errmsg.IdentityNotDefined.Error()) }) @@ -170,7 +169,7 @@ func TestLog(t *testing.T) { c.Convey("toString", FailureHalts, func(c C) { expectedData := "five\n└─four\n └─three\n └─two\n └─one" - log1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + log1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) for _, val := range []string{"one", "two", "three", "four", "five"} { _, err := log1.Append([]byte(val), 1) diff --git a/test/logcreator/logcreator.go b/test/logcreator/logcreator.go index dcdf58f..6df443f 100644 --- a/test/logcreator/logcreator.go +++ b/test/logcreator/logcreator.go @@ -3,34 +3,35 @@ package logcreator // import "berty.tech/go-ipfs-log/test/logcreator" import ( "fmt" + ipfslog "berty.tech/go-ipfs-log" + idp "berty.tech/go-ipfs-log/identityprovider" "berty.tech/go-ipfs-log/io" - "berty.tech/go-ipfs-log/log" ) type CreatedLog struct { - Log *log.Log + Log *ipfslog.Log ExpectedData []string - JSON *log.JSONLog + JSON *ipfslog.JSONLog } -func createLogsFor16Entries(ipfs io.IpfsServices, identities [4]*idp.Identity) (*log.Log, error) { - logA, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) +func createLogsFor16Entries(ipfs io.IpfsServices, identities [4]*idp.Identity) (*ipfslog.Log, error) { + logA, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, err } - logB, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + logB, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, err } - log3, err := log.NewLog(ipfs, identities[2], &log.NewLogOptions{ID: "X"}) + log3, err := ipfslog.NewLog(ipfs, identities[2], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, err } - l, err := log.NewLog(ipfs, identities[3], &log.NewLogOptions{ID: "X"}) + l, err := ipfslog.NewLog(ipfs, identities[3], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, err } @@ -101,16 +102,16 @@ func CreateLogWithSixteenEntries(ipfs io.IpfsServices, identities [4]*idp.Identi return &CreatedLog{Log: l, ExpectedData: expectedData, JSON: l.ToJSON()}, nil } -func createLogWithHundredEntries(ipfs io.IpfsServices, identities [4]*idp.Identity) (*log.Log, []string, error) { +func createLogWithHundredEntries(ipfs io.IpfsServices, identities [4]*idp.Identity) (*ipfslog.Log, []string, error) { var expectedData []string const amount = 100 - logA, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "X"}) + logA, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, nil, err } - logB, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "X"}) + logB, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "X"}) if err != nil { return nil, nil, err } diff --git a/test/signed_log_test.go b/test/signed_log_test.go index 65569b2..f846779 100644 --- a/test/signed_log_test.go +++ b/test/signed_log_test.go @@ -8,11 +8,11 @@ import ( "testing" "time" + ipfslog "berty.tech/go-ipfs-log" "berty.tech/go-ipfs-log/entry" "berty.tech/go-ipfs-log/errmsg" idp "berty.tech/go-ipfs-log/identityprovider" ks "berty.tech/go-ipfs-log/keystore" - "berty.tech/go-ipfs-log/log" dssync "github.com/ipfs/go-datastore/sync" . "github.com/smartystreets/goconvey/convey" @@ -77,14 +77,14 @@ func TestSignedLog(t *testing.T) { Convey("Signed Log", t, FailureHalts, func(c C) { c.Convey("creates a signed log", FailureHalts, func(c C) { logID := "A" - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: logID}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: logID}) c.So(err, ShouldBeNil) c.So(l.ID, ShouldNotBeNil) c.So(l.ID, ShouldEqual, logID) }) c.Convey("has the correct identity", FailureHalts, func(c C) { - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) c.So(l.ID, ShouldNotBeNil) c.So(l.Identity.ID, ShouldEqual, "03e0480538c2a39951d054e17ff31fde487cb1031d0044a037b53ad2e028a3e77c") @@ -94,28 +94,28 @@ func TestSignedLog(t *testing.T) { }) c.Convey("has the correct public key", FailureHalts, func(c C) { - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) c.So(l.Identity.PublicKey, ShouldResemble, identities[0].PublicKey) }) c.Convey("has the correct pkSignature", FailureHalts, func(c C) { - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) c.So(l.Identity.Signatures.ID, ShouldResemble, identities[0].Signatures.ID) }) c.Convey("has the correct signature", FailureHalts, func(c C) { - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) c.So(l.Identity.Signatures.PublicKey, ShouldResemble, identities[0].Signatures.PublicKey) }) c.Convey("entries contain an identity", FailureHalts, func(c C) { - l, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = l.Append([]byte("one"), 1) @@ -126,15 +126,15 @@ func TestSignedLog(t *testing.T) { }) c.Convey("doesn't sign entries when identity is not defined", FailureHalts, func(c C) { - _, err := log.NewLog(ipfs, nil, nil) + _, err := ipfslog.NewLog(ipfs, nil, nil) c.So(err, ShouldEqual, errmsg.IdentityNotDefined) }) c.Convey("doesn't join logs with different IDs", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "B"}) + l2, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "B"}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) @@ -155,10 +155,10 @@ func TestSignedLog(t *testing.T) { }) c.Convey("throws an error if log is signed but trying to merge with an entry that doesn't have public signing key", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "A"}) + l2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) @@ -175,10 +175,10 @@ func TestSignedLog(t *testing.T) { }) c.Convey("throws an error if log is signed but trying to merge an entry that doesn't have a signature", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "A"}) + l2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) @@ -195,10 +195,10 @@ func TestSignedLog(t *testing.T) { }) c.Convey("throws an error if log is signed but the signature doesn't verify", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "A"}) + l2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) @@ -218,10 +218,10 @@ func TestSignedLog(t *testing.T) { }) c.Convey("throws an error if entry doesn't have append access", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A"}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "A", AccessController: &DenyAll{}}) + l2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "A", AccessController: &DenyAll{}}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) @@ -233,10 +233,10 @@ func TestSignedLog(t *testing.T) { }) c.Convey("throws an error upon join if entry doesn't have append access", FailureHalts, func(c C) { - l1, err := log.NewLog(ipfs, identities[0], &log.NewLogOptions{ID: "A", AccessController: &TestACL{refIdentity: identities[1]}}) + l1, err := ipfslog.NewLog(ipfs, identities[0], &ipfslog.LogOptions{ID: "A", AccessController: &TestACL{refIdentity: identities[1]}}) c.So(err, ShouldBeNil) - l2, err := log.NewLog(ipfs, identities[1], &log.NewLogOptions{ID: "A"}) + l2, err := ipfslog.NewLog(ipfs, identities[1], &ipfslog.LogOptions{ID: "A"}) c.So(err, ShouldBeNil) _, err = l1.Append([]byte("one"), 1) diff --git a/test/utils.go b/test/utils.go index 184d6a8..3767639 100644 --- a/test/utils.go +++ b/test/utils.go @@ -51,8 +51,8 @@ func lastEntry(entries []*entry.Entry) *entry.Entry { func entriesAsStrings(values *entry.OrderedMap) []string { var foundEntries []string - for _, k := range values.Keys() { - foundEntries = append(foundEntries, string(values.UnsafeGet(k).Payload)) + for _, v := range values.Slice() { + foundEntries = append(foundEntries, string(v.Payload)) } return foundEntries