diff --git a/go.mod b/go.mod index c5d3bdb29630e9d3f518624f442510cacd9c7ec3..99b58c2a43bc10ae476d6d66a9a7aa17d47c2e4c 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/ethereum/go-ethereum v1.9.3 github.com/gdamore/tcell v1.2.0 github.com/go-zeromq/zmq4 v0.5.0 + github.com/gogo/protobuf v1.2.1 github.com/golang/protobuf v1.3.2 // indirect github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51 github.com/gorilla/websocket v1.4.1 diff --git a/go.sum b/go.sum index 2eba5bd28b5cd8aa55e7460ca98744cd8e39f84b..2d2f69d91c485e0570cb93f5a37fea16eac949c9 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-zeromq/zmq4 v0.5.0 h1:DijriKlrr2b48mymvAsZApiPzrbxQodYKG1aDH1rz8c= github.com/go-zeromq/zmq4 v0.5.0/go.mod h1:6p7pjNlkfrQQVipmEuZDk7fakLZCqPPVK+Iq3jfbDg8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= diff --git a/packages/binary/transfer/hash.go b/packages/binary/transfer/hash.go new file mode 100644 index 0000000000000000000000000000000000000000..8b6c32524fc3bfcf94210817e04dda71ccd52798 --- /dev/null +++ b/packages/binary/transfer/hash.go @@ -0,0 +1,39 @@ +package transfer + +import ( + "unicode/utf8" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/stringify" +) + +type Hash [HashLength]byte + +func NewHash(transferHash string) (result Hash) { + copy(result[:], transferHash) + + return +} + +func (transferHash Hash) ToRealityId() (realityId reality.Id) { + copy(realityId[:], transferHash[:]) + + return +} + +func (transferHash *Hash) UnmarshalBinary(data []byte) error { + copy(transferHash[:], data[:HashLength]) + + return nil +} + +func (transferHash Hash) String() string { + if utf8.Valid(transferHash[:]) { + return string(transferHash[:]) + } else { + return stringify.SliceOfBytes(transferHash[:]) + } +} + +const HashLength = 32 diff --git a/packages/binary/transferoutput/reference.go b/packages/binary/transferoutput/reference.go index 6e5658cb084c359928b7f45eb11f533fcd2c3e1a..6b702cfda6eca4e683716b87c3499f177161a1bb 100644 --- a/packages/binary/transferoutput/reference.go +++ b/packages/binary/transferoutput/reference.go @@ -1 +1,32 @@ package transferoutput + +import ( + "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/stringify" +) + +type Reference struct { + storageKey []byte + transferHash transfer.Hash + addressHash address.Address +} + +func NewTransferOutputReference(transferHash transfer.Hash, addressHash address.Address) *Reference { + return &Reference{ + storageKey: append(transferHash[:], addressHash[:]...), + transferHash: transferHash, + addressHash: addressHash, + } +} + +func (reference *Reference) GetStorageKey() []byte { + return reference.storageKey +} + +func (reference *Reference) String() string { + return stringify.Struct("TransferOutputReference", + stringify.StructField("transferHash", reference.transferHash), + stringify.StructField("addressHash", reference.addressHash), + ) +} diff --git a/packages/binary/types/empty.go b/packages/binary/types/empty.go new file mode 100644 index 0000000000000000000000000000000000000000..e8be3c8ad5d8d95d719e4aab5aca3c796aa3e2f3 --- /dev/null +++ b/packages/binary/types/empty.go @@ -0,0 +1,5 @@ +package types + +type Empty struct{} + +var Void Empty diff --git a/packages/ledgerstate/conflict.go b/packages/ledgerstate/conflict/conflict.go similarity index 63% rename from packages/ledgerstate/conflict.go rename to packages/ledgerstate/conflict/conflict.go index 4ae4e0f750c4f928c10614edc3bfd90c3a1fab33..fe54d81138b4543d988cdf12d54ab9800407fa53 100644 --- a/packages/ledgerstate/conflict.go +++ b/packages/ledgerstate/conflict/conflict.go @@ -1,10 +1,12 @@ -package ledgerstate +package conflict import ( "encoding/binary" "fmt" "sync" + "github.com/iotaledger/goshimmer/packages/binary/types" + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" "github.com/iotaledger/goshimmer/packages/stringify" "github.com/iotaledger/hive.go/objectstorage" @@ -13,35 +15,43 @@ import ( type Conflict struct { objectstorage.StorableObjectFlags - id ConflictId - members map[RealityId]empty + id Id + Members map[reality.Id]types.Empty - storageKey []byte - ledgerState *LedgerState + storageKey []byte membersMutex sync.RWMutex } -func newConflictSet(id ConflictId) *Conflict { +func New(id Id) *Conflict { result := &Conflict{ id: id, - members: make(map[RealityId]empty), + Members: make(map[reality.Id]types.Empty), - storageKey: make([]byte, conflictSetIdLength), + storageKey: make([]byte, IdLength), } copy(result.storageKey, id[:]) return result } -func (conflict *Conflict) GetId() ConflictId { +func Factory(key []byte) objectstorage.StorableObject { + result := &Conflict{ + storageKey: make([]byte, len(key)), + } + copy(result.storageKey, key) + + return result +} + +func (conflict *Conflict) GetId() Id { return conflict.id } -func (conflict *Conflict) AddReality(realityId RealityId) { +func (conflict *Conflict) AddReality(realityId reality.Id) { conflict.membersMutex.Lock() - conflict.members[realityId] = void + conflict.Members[realityId] = types.Void conflict.membersMutex.Unlock() } @@ -52,7 +62,7 @@ func (conflict *Conflict) String() string { return stringify.Struct("Conflict", stringify.StructField("id", conflict.id.String()), - stringify.StructField("members", conflict.members), + stringify.StructField("members", conflict.Members), ) } @@ -70,15 +80,15 @@ func (conflict *Conflict) MarshalBinary() ([]byte, error) { conflict.membersMutex.RLock() offset := 0 - membersCount := len(conflict.members) - result := make([]byte, 4+membersCount*realityIdLength) + membersCount := len(conflict.Members) + result := make([]byte, 4+membersCount*reality.IdLength) binary.LittleEndian.PutUint32(result[offset:], uint32(membersCount)) offset += 4 - for realityId := range conflict.members { - copy(result[offset:], realityId[:realityIdLength]) - offset += realityIdLength + for realityId := range conflict.Members { + copy(result[offset:], realityId[:reality.IdLength]) + offset += reality.IdLength } conflict.membersMutex.RUnlock() @@ -94,27 +104,27 @@ func (conflict *Conflict) UnmarshalBinary(serializedObject []byte) error { if members, err := conflict.unmarshalMembers(serializedObject); err != nil { return err } else { - conflict.members = members + conflict.Members = members } return nil } -func (conflict *Conflict) unmarshalMembers(serializedConsumers []byte) (map[RealityId]empty, error) { +func (conflict *Conflict) unmarshalMembers(serializedConsumers []byte) (map[reality.Id]types.Empty, error) { offset := 0 membersCount := int(binary.LittleEndian.Uint32(serializedConsumers[offset:])) offset += 4 - members := make(map[RealityId]empty, membersCount) + members := make(map[reality.Id]types.Empty, membersCount) for i := 0; i < membersCount; i++ { - realityId := RealityId{} + realityId := reality.Id{} if err := realityId.UnmarshalBinary(serializedConsumers[offset:]); err != nil { return nil, err } - offset += realityIdLength + offset += reality.IdLength - members[realityId] = void + members[realityId] = types.Void } return members, nil diff --git a/packages/ledgerstate/conflict/id.go b/packages/ledgerstate/conflict/id.go new file mode 100644 index 0000000000000000000000000000000000000000..5e413b34950dde444215a45d44c05143418e36f4 --- /dev/null +++ b/packages/ledgerstate/conflict/id.go @@ -0,0 +1,56 @@ +package conflict + +import ( + "unicode/utf8" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + + "github.com/iotaledger/goshimmer/packages/binary/address" + + "github.com/iotaledger/goshimmer/packages/stringify" + "golang.org/x/crypto/blake2b" +) + +type Id [IdLength]byte + +func NewId(conflictBytes ...interface{}) (result Id) { + switch len(conflictBytes) { + case 2: + transferHash, ok := conflictBytes[0].(transfer.Hash) + if !ok { + panic("expected first parameter of NewId to be a TransferHash") + } + + addressHash, ok := conflictBytes[0].(transfer.Hash) + if !ok { + panic("expected second parameter of NewId to be a AddressHash") + } + + fullConflictSetIdentifier := make([]byte, transfer.HashLength+address.Length) + copy(fullConflictSetIdentifier, transferHash[:]) + copy(fullConflictSetIdentifier[transfer.HashLength:], addressHash[:]) + + result = blake2b.Sum256(fullConflictSetIdentifier) + case 1: + default: + panic("invalid parameter count when calling NewId") + } + + return +} + +func (conflictId *Id) UnmarshalBinary(data []byte) error { + copy(conflictId[:], data[:IdLength]) + + return nil +} + +func (conflictId Id) String() string { + if utf8.Valid(conflictId[:]) { + return string(conflictId[:]) + } else { + return stringify.SliceOfBytes(conflictId[:]) + } +} + +const IdLength = 32 diff --git a/packages/ledgerstate/conflict/id_list.go b/packages/ledgerstate/conflict/id_list.go new file mode 100644 index 0000000000000000000000000000000000000000..c8586a32e606c8bd72289b3346d3db420bca82d0 --- /dev/null +++ b/packages/ledgerstate/conflict/id_list.go @@ -0,0 +1,25 @@ +package conflict + +import "github.com/iotaledger/goshimmer/packages/binary/types" + +type IdList []Id + +func (idList IdList) Clone() (clone IdList) { + clone = make(IdList, len(idList)) + + for key, value := range idList { + clone[key] = value + } + + return +} + +func (idList IdList) ToSet() (set IdSet) { + set = make(IdSet) + + for _, value := range idList { + set[value] = types.Void + } + + return +} diff --git a/packages/ledgerstate/conflict/id_set.go b/packages/ledgerstate/conflict/id_set.go new file mode 100644 index 0000000000000000000000000000000000000000..707e88b90aa9306bfac9f1275c58e1bf4da7a3bc --- /dev/null +++ b/packages/ledgerstate/conflict/id_set.go @@ -0,0 +1,38 @@ +package conflict + +import "github.com/iotaledger/goshimmer/packages/binary/types" + +type IdSet map[Id]types.Empty + +func NewIdSet(conflictIds ...Id) (conflictIdSet IdSet) { + conflictIdSet = make(IdSet) + + for _, realityId := range conflictIds { + conflictIdSet[realityId] = types.Void + } + + return +} + +func (idSet IdSet) Clone() (clone IdSet) { + clone = make(IdSet, len(idSet)) + + for key := range idSet { + clone[key] = types.Void + } + + return +} + +func (idSet IdSet) ToList() (list IdList) { + list = make(IdList, len(idSet)) + + i := 0 + for key := range idSet { + list[i] = key + + i++ + } + + return +} diff --git a/packages/ledgerstate/conflict_id.go b/packages/ledgerstate/conflict_id.go deleted file mode 100644 index d7f596894be9e771d96aaa9f814d6d8d2e5e1c79..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/conflict_id.go +++ /dev/null @@ -1,54 +0,0 @@ -package ledgerstate - -import ( - "unicode/utf8" - - "github.com/iotaledger/goshimmer/packages/binary/address" - - "github.com/iotaledger/goshimmer/packages/stringify" - "golang.org/x/crypto/blake2b" -) - -type ConflictId [conflictSetIdLength]byte - -func NewConflictId(conflictBytes ...interface{}) (result ConflictId) { - switch len(conflictBytes) { - case 2: - transferHash, ok := conflictBytes[0].(TransferHash) - if !ok { - panic("expected first parameter of NewConflictId to be a TransferHash") - } - - addressHash, ok := conflictBytes[0].(TransferHash) - if !ok { - panic("expected second parameter of NewConflictId to be a AddressHash") - } - - fullConflictSetIdentifier := make([]byte, transferHashLength+address.Length) - copy(fullConflictSetIdentifier, transferHash[:]) - copy(fullConflictSetIdentifier[transferHashLength:], addressHash[:]) - - result = blake2b.Sum256(fullConflictSetIdentifier) - case 1: - default: - panic("invalid parameter count when calling NewConflictId") - } - - return -} - -func (conflictId *ConflictId) UnmarshalBinary(data []byte) error { - copy(conflictId[:], data[:conflictSetIdLength]) - - return nil -} - -func (conflictId ConflictId) String() string { - if utf8.Valid(conflictId[:]) { - return string(conflictId[:]) - } else { - return stringify.SliceOfBytes(conflictId[:]) - } -} - -const conflictSetIdLength = 32 diff --git a/packages/ledgerstate/conflict_id_list.go b/packages/ledgerstate/conflict_id_list.go deleted file mode 100644 index afd0a940ba574362390119b17bfe565898214dfc..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/conflict_id_list.go +++ /dev/null @@ -1,23 +0,0 @@ -package ledgerstate - -type ConflictIdList []ConflictId - -func (conflictIdList ConflictIdList) Clone() (clone ConflictIdList) { - clone = make(ConflictIdList, len(conflictIdList)) - - for key, value := range conflictIdList { - clone[key] = value - } - - return -} - -func (conflictIdList ConflictIdList) ToSet() (set ConflictIdSet) { - set = make(ConflictIdSet) - - for _, value := range conflictIdList { - set[value] = void - } - - return -} diff --git a/packages/ledgerstate/conflict_id_set.go b/packages/ledgerstate/conflict_id_set.go deleted file mode 100644 index ccc431cae1e6a082de9e803dd6ee059b956e091a..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/conflict_id_set.go +++ /dev/null @@ -1,36 +0,0 @@ -package ledgerstate - -type ConflictIdSet map[ConflictId]empty - -func NewConflictIdSet(conflictIds ...ConflictId) (conflictIdSet ConflictIdSet) { - conflictIdSet = make(ConflictIdSet) - - for _, realityId := range conflictIds { - conflictIdSet[realityId] = void - } - - return -} - -func (conflictIdSet ConflictIdSet) Clone() (clone ConflictIdSet) { - clone = make(ConflictIdSet, len(conflictIdSet)) - - for key := range conflictIdSet { - clone[key] = void - } - - return -} - -func (conflictIdSet ConflictIdSet) ToList() (list ConflictIdList) { - list = make(ConflictIdList, len(conflictIdSet)) - - i := 0 - for key := range conflictIdSet { - list[i] = key - - i++ - } - - return -} diff --git a/packages/ledgerstate/constants.go b/packages/ledgerstate/constants.go index 8c5d7d7c4ee8ab34ff16833e5d66ae6040a5551d..5b076188bd327830e02341a0e4ff3f3322af8365 100644 --- a/packages/ledgerstate/constants.go +++ b/packages/ledgerstate/constants.go @@ -2,6 +2,8 @@ package ledgerstate import ( "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" ) const ( @@ -9,18 +11,18 @@ const ( SPENT = SpentIndicator(1) marshalTransferOutputBookingRealityIdStart = 0 - marshalTransferOutputBookingRealityIdEnd = marshalTransferOutputBookingRealityIdStart + realityIdLength + marshalTransferOutputBookingRealityIdEnd = marshalTransferOutputBookingRealityIdStart + reality.IdLength marshalTransferOutputBookingAddressHashStart = marshalTransferOutputBookingRealityIdEnd marshalTransferOutputBookingAddressHashEnd = marshalTransferOutputBookingAddressHashStart + address.Length marshalTransferOutputBookingSpentStart = marshalTransferOutputBookingAddressHashEnd marshalTransferOutputBookingSpentEnd = marshalTransferOutputBookingSpentStart + 1 marshalTransferOutputBookingTransferHashStart = marshalTransferOutputBookingSpentEnd - marshalTransferOutputBookingTransferHashEnd = marshalTransferOutputBookingTransferHashStart + transferHashLength + marshalTransferOutputBookingTransferHashEnd = marshalTransferOutputBookingTransferHashStart + transfer.HashLength marshalTransferOutputBookingTotalLength = marshalTransferOutputBookingTransferHashEnd ) type SpentIndicator byte var ( - MAIN_REALITY_ID = NewRealityId("MAIN_REALITY") + MAIN_REALITY_ID = reality.NewId("MAIN_REALITY") ) diff --git a/packages/ledgerstate/ledgerstate.go b/packages/ledgerstate/ledgerstate.go index c482acd9ee94a664677074728beffb0ae25ec4a0..654c606790c134641dc790486387177a36d4b0d1 100644 --- a/packages/ledgerstate/ledgerstate.go +++ b/packages/ledgerstate/ledgerstate.go @@ -7,6 +7,14 @@ import ( "strings" "time" + "github.com/iotaledger/goshimmer/packages/ledgerstate/conflict" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + + "github.com/iotaledger/goshimmer/packages/binary/transferoutput" + "github.com/iotaledger/goshimmer/packages/binary/address" "github.com/iotaledger/goshimmer/packages/graphviz" @@ -33,7 +41,7 @@ func NewLedgerState(storageId string) *LedgerState { transferOutputs: objectstorage.New(storageId+"TRANSFER_OUTPUTS", transferOutputFactory, objectstorage.CacheTime(1*time.Second)), transferOutputBookings: objectstorage.New(storageId+"TRANSFER_OUTPUT_BOOKING", transferOutputBookingFactory, objectstorage.CacheTime(1*time.Second)), realities: objectstorage.New(storageId+"REALITIES", realityFactory, objectstorage.CacheTime(1*time.Second)), - conflictSets: objectstorage.New(storageId+"CONFLICT_SETS", conflictSetFactory, objectstorage.CacheTime(1*time.Second)), + conflictSets: objectstorage.New(storageId+"CONFLICT_SETS", conflict.Factory, objectstorage.CacheTime(1*time.Second)), } mainReality := newReality(MAIN_REALITY_ID) @@ -44,17 +52,17 @@ func NewLedgerState(storageId string) *LedgerState { return result } -func (ledgerState *LedgerState) AddTransferOutput(transferHash TransferHash, addressHash address.Address, balances ...*ColoredBalance) *LedgerState { +func (ledgerState *LedgerState) AddTransferOutput(transferHash transfer.Hash, addressHash address.Address, balances ...*ColoredBalance) *LedgerState { ledgerState.GetReality(MAIN_REALITY_ID).Consume(func(object objectstorage.StorableObject) { mainReality := object.(*Reality) - mainReality.bookTransferOutput(NewTransferOutput(ledgerState, emptyRealityId, transferHash, addressHash, balances...)) + mainReality.bookTransferOutput(NewTransferOutput(ledgerState, reality.EmptyId, transferHash, addressHash, balances...)) }) return ledgerState } -func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *TransferOutputReference) *objectstorage.CachedObject { +func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *transferoutput.Reference) *objectstorage.CachedObject { if cachedTransferOutput, err := ledgerState.transferOutputs.Load(transferOutputReference.GetStorageKey()); err != nil { panic(err) } else { @@ -70,8 +78,6 @@ func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *Trans func (ledgerState *LedgerState) ForEachConflictSet(callback func(object *objectstorage.CachedObject) bool) { if err := ledgerState.conflictSets.ForEach(func(key []byte, cachedObject *objectstorage.CachedObject) bool { - cachedObject.Get().(*Conflict).ledgerState = ledgerState - return callback(cachedObject) }); err != nil { panic(err) @@ -96,7 +102,7 @@ func (ledgerState *LedgerState) ForEachTransferOutput(callback func(object *obje booking := cachedObject.Get().(*TransferOutputBooking) cachedObject.Release() - return callback(ledgerState.GetTransferOutput(NewTransferOutputReference(booking.GetTransferHash(), booking.GetAddressHash()))) + return callback(ledgerState.GetTransferOutput(transferoutput.NewTransferOutputReference(booking.GetTransferHash(), booking.GetAddressHash()))) }, prefix); err != nil { panic(err) } @@ -124,7 +130,7 @@ func (ledgerState *LedgerState) ForEachTransferOutput(callback func(object *obje } } -func (ledgerState *LedgerState) CreateReality(id RealityId) { +func (ledgerState *LedgerState) CreateReality(id reality.Id) { newReality := newReality(id, MAIN_REALITY_ID) newReality.ledgerState = ledgerState @@ -139,7 +145,7 @@ func (ledgerState *LedgerState) CreateReality(id RealityId) { ledgerState.realities.Store(newReality).Release() } -func (ledgerState *LedgerState) GetReality(id RealityId) *objectstorage.CachedObject { +func (ledgerState *LedgerState) GetReality(id reality.Id) *objectstorage.CachedObject { if cachedObject, err := ledgerState.realities.Load(id[:]); err != nil { panic(err) } else { @@ -173,17 +179,17 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) graph := dot.NewGraph(dot.Directed) graph.Attr("ranksep", "1.0 equally") - realityNodes := make(map[RealityId]dot.Node) + realityNodes := make(map[reality.Id]dot.Node) - drawConflictSet := func(conflictSet *Conflict) { - conflictSetNode := graph.Node(strings.Trim(conflictSet.id.String(), "\x00")) + drawConflictSet := func(conflict *conflict.Conflict) { + conflictSetNode := graph.Node(strings.Trim(conflict.GetId().String(), "\x00")) conflictSetNode.Attr("label", "") conflictSetNode.Attr("shape", "Mdiamond") conflictSetNode.Attr("style", "filled") conflictSetNode.Attr("color", "#B85450") conflictSetNode.Attr("fillcolor", "#F8CECC") - for realityId := range conflictSet.members { + for realityId := range conflict.Members { conflictSetNode.Edge(realityNodes[realityId]).Attr("arrowhead", "none").Attr("arrowtail", "none").Attr("color", "#B85450") } } @@ -235,7 +241,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) }) ledgerState.ForEachConflictSet(func(object *objectstorage.CachedObject) bool { object.Consume(func(object objectstorage.StorableObject) { - drawConflictSet(object.(*Conflict)) + drawConflictSet(object.(*conflict.Conflict)) }) return true @@ -244,7 +250,7 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) return graphviz.RenderPNG(graph, pngFilename) } -func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *objectstorage.CachedObject { +func (ledgerState *LedgerState) AggregateRealities(realityIds ...reality.Id) *objectstorage.CachedObject { switch len(realityIds) { case 0: if loadedReality, loadedRealityErr := ledgerState.realities.Load(MAIN_REALITY_ID[:]); loadedRealityErr != nil { @@ -263,7 +269,7 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj return loadedReality } default: - aggregatedRealities := make(map[RealityId]*objectstorage.CachedObject) + aggregatedRealities := make(map[reality.Id]*objectstorage.CachedObject) AGGREGATE_REALITIES: for _, realityId := range realityIds { @@ -312,8 +318,8 @@ func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *obj } } - parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject) - aggregatedRealityParentIds := make([]RealityId, len(aggregatedRealities)) + parentConflictRealities := make(map[reality.Id]*objectstorage.CachedObject) + aggregatedRealityParentIds := make([]reality.Id, len(aggregatedRealities)) aggregatedRealityIsPreferred := true @@ -402,19 +408,19 @@ func (ledgerState *LedgerState) Prune() *LedgerState { } func (ledgerState *LedgerState) generateFilterPrefixes(filters []interface{}) ([][]byte, bool) { - filteredRealities := make([]RealityId, 0) + filteredRealities := make([]reality.Id, 0) filteredAddresses := make([]address.Address, 0) - filteredTransfers := make([]TransferHash, 0) + filteredTransfers := make([]transfer.Hash, 0) filterSpent := false filterUnspent := false for _, filter := range filters { switch typeCastedValue := filter.(type) { - case RealityId: + case reality.Id: filteredRealities = append(filteredRealities, typeCastedValue) case address.Address: filteredAddresses = append(filteredAddresses, typeCastedValue) - case TransferHash: + case transfer.Hash: filteredTransfers = append(filteredTransfers, typeCastedValue) case SpentIndicator: switch typeCastedValue { @@ -488,9 +494,9 @@ func (ledgerState *LedgerState) storeTransferOutputBooking(transferOutputBooking return ledgerState.transferOutputBookings.Store(transferOutputBooking) } -func (ledgerState *LedgerState) sortRealityIds(aggregatedRealities map[RealityId]*objectstorage.CachedObject) []RealityId { +func (ledgerState *LedgerState) sortRealityIds(aggregatedRealities map[reality.Id]*objectstorage.CachedObject) []reality.Id { counter := 0 - sortedRealityIds := make([]RealityId, len(aggregatedRealities)) + sortedRealityIds := make([]reality.Id, len(aggregatedRealities)) for realityId, aggregatedReality := range aggregatedRealities { sortedRealityIds[counter] = realityId @@ -514,7 +520,7 @@ func (ledgerState *LedgerState) sortRealityIds(aggregatedRealities map[RealityId return sortedRealityIds } -func (ledgerState *LedgerState) generateAggregatedRealityId(sortedRealityIds []RealityId) [32]byte { +func (ledgerState *LedgerState) generateAggregatedRealityId(sortedRealityIds []reality.Id) [32]byte { aggregatedRealityId := make([]byte, 0) for _, realityId := range sortedRealityIds { aggregatedRealityId = append(aggregatedRealityId, realityId[:]...) @@ -524,7 +530,7 @@ func (ledgerState *LedgerState) generateAggregatedRealityId(sortedRealityIds []R } func (ledgerState *LedgerState) getTargetReality(inputs []*objectstorage.CachedObject) *objectstorage.CachedObject { - realityIds := make([]RealityId, len(inputs)) + realityIds := make([]reality.Id, len(inputs)) for i, input := range inputs { realityIds[i] = input.Get().(*TransferOutput).GetRealityId() } @@ -569,12 +575,3 @@ func realityFactory(key []byte) objectstorage.StorableObject { return result } - -func conflictSetFactory(key []byte) objectstorage.StorableObject { - result := &Conflict{ - storageKey: make([]byte, len(key)), - } - copy(result.storageKey, key) - - return result -} diff --git a/packages/ledgerstate/ledgerstate_test.go b/packages/ledgerstate/ledgerstate_test.go index fbe5c0f7b0814eba89f29c5dab0822faa14d1836..1aa8176cf2a02afe34b7f3d33acff23f1251df0e 100644 --- a/packages/ledgerstate/ledgerstate_test.go +++ b/packages/ledgerstate/ledgerstate_test.go @@ -6,6 +6,12 @@ import ( "testing" "time" + "github.com/iotaledger/goshimmer/packages/binary/transferoutput" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/binary/address" "github.com/iotaledger/hive.go/objectstorage" @@ -15,19 +21,19 @@ import ( var ( iota_ = NewColor("IOTA") eth = NewColor("ETH") - transferHash1 = NewTransferHash("TRANSFER1") - transferHash2 = NewTransferHash("TRANSFER2") - transferHash3 = NewTransferHash("TRANSFER3") - transferHash4 = NewTransferHash("TRANSFER4") - transferHash5 = NewTransferHash("TRANSFER5") - transferHash6 = NewTransferHash("TRANSFER6") + transferHash1 = transfer.NewHash("TRANSFER1") + transferHash2 = transfer.NewHash("TRANSFER2") + transferHash3 = transfer.NewHash("TRANSFER3") + transferHash4 = transfer.NewHash("TRANSFER4") + transferHash5 = transfer.NewHash("TRANSFER5") + transferHash6 = transfer.NewHash("TRANSFER6") addressHash1 = address.New([]byte("ADDRESS1")) addressHash2 = address.New([]byte("ADDRESS2")) addressHash3 = address.New([]byte("ADDRESS3")) addressHash4 = address.New([]byte("ADDRESS4")) addressHash5 = address.New([]byte("ADDRESS5")) addressHash6 = address.New([]byte("ADDRESS6")) - pendingReality = NewRealityId("PENDING") + pendingReality = reality.NewId("PENDING") ) func init() { @@ -46,10 +52,10 @@ func Benchmark(b *testing.B) { lastTransferHash := transferHash1 for i := 0; i < b.N; i++ { - newTransferHash := NewTransferHash(strconv.Itoa(i)) + newTransferHash := transfer.NewHash(strconv.Itoa(i)) if err := ledgerState.BookTransfer(NewTransfer(newTransferHash).AddInput( - NewTransferOutputReference(lastTransferHash, addressHash1), + transferoutput.NewTransferOutputReference(lastTransferHash, addressHash1), ).AddOutput( addressHash1, NewColoredBalance(eth, 1024), )); err != nil { @@ -68,7 +74,7 @@ func Test(t *testing.T) { ledgerState.CreateReality(pendingReality) transfer := NewTransfer(transferHash2).AddInput( - NewTransferOutputReference(transferHash1, addressHash1), + transferoutput.NewTransferOutputReference(transferHash1, addressHash1), ).AddOutput( addressHash3, NewColoredBalance(iota_, 338), ).AddOutput( @@ -84,7 +90,7 @@ func Test(t *testing.T) { } if err := ledgerState.BookTransfer(NewTransfer(transferHash3).AddInput( - NewTransferOutputReference(transferHash1, addressHash1), + transferoutput.NewTransferOutputReference(transferHash1, addressHash1), ).AddOutput( addressHash3, NewColoredBalance(iota_, 338), ).AddOutput( @@ -112,10 +118,10 @@ func Test(t *testing.T) { var transferHashCounter = 0 -func generateRandomTransferHash() TransferHash { +func generateRandomTransferHash() transfer.Hash { transferHashCounter++ - return NewTransferHash("TRANSFER" + strconv.Itoa(transferHashCounter)) + return transfer.NewHash("TRANSFER" + strconv.Itoa(transferHashCounter)) } var addressHashCounter = 0 @@ -126,7 +132,7 @@ func generateRandomAddressHash() address.Address { return address.New([]byte("ADDRESS" + strconv.Itoa(addressHashCounter))) } -func initializeLedgerStateWithBalances(numberOfBalances int) (ledgerState *LedgerState, result []*TransferOutputReference) { +func initializeLedgerStateWithBalances(numberOfBalances int) (ledgerState *LedgerState, result []*transferoutput.Reference) { ledgerState = NewLedgerState("testLedger").Prune() for i := 0; i < numberOfBalances; i++ { @@ -135,13 +141,13 @@ func initializeLedgerStateWithBalances(numberOfBalances int) (ledgerState *Ledge ledgerState.AddTransferOutput(transferHash, addressHash, NewColoredBalance(iota_, 1024)) - result = append(result, NewTransferOutputReference(transferHash, addressHash)) + result = append(result, transferoutput.NewTransferOutputReference(transferHash, addressHash)) } return } -func doubleSpend(ledgerState *LedgerState, transferOutputReference *TransferOutputReference) (result []*TransferOutputReference) { +func doubleSpend(ledgerState *LedgerState, transferOutputReference *transferoutput.Reference) (result []*transferoutput.Reference) { for i := 0; i < 2; i++ { result = append(result, spend(ledgerState, transferOutputReference)) } @@ -149,7 +155,7 @@ func doubleSpend(ledgerState *LedgerState, transferOutputReference *TransferOutp return } -func spend(ledgerState *LedgerState, transferOutputReferences ...*TransferOutputReference) (result *TransferOutputReference) { +func spend(ledgerState *LedgerState, transferOutputReferences ...*transferoutput.Reference) (result *transferoutput.Reference) { transferHash := generateRandomTransferHash() addressHash := generateRandomAddressHash() @@ -175,12 +181,12 @@ func spend(ledgerState *LedgerState, transferOutputReferences ...*TransferOutput panic(err) } - result = NewTransferOutputReference(transferHash, addressHash) + result = transferoutput.NewTransferOutputReference(transferHash, addressHash) return } -func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferences ...*TransferOutputReference) (result []*TransferOutputReference) { +func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferences ...*transferoutput.Reference) (result []*transferoutput.Reference) { transferHash := generateRandomTransferHash() transfer := NewTransfer(transferHash) @@ -205,7 +211,7 @@ func multiSpend(ledgerState *LedgerState, outputCount int, transferOutputReferen addressHash, NewColoredBalance(iota_, totalInputBalance/uint64(outputCount)), ) - result = append(result, NewTransferOutputReference(transferHash, addressHash)) + result = append(result, transferoutput.NewTransferOutputReference(transferHash, addressHash)) } if err := ledgerState.BookTransfer(transfer); err != nil { @@ -288,46 +294,46 @@ func TestElevateAggregatedReality(t *testing.T) { func TestElevate(t *testing.T) { ledgerState := NewLedgerState("testLedger").Prune().AddTransferOutput( - transferHash1, addressHash1, NewColoredBalance(eth, 1024), NewColoredBalance(iota_, 1338), + transferHash1, addressHash1, NewColoredBalance(eth, 1337), NewColoredBalance(iota_, 1338), ) // create first legit spend if err := ledgerState.BookTransfer(NewTransfer(transferHash2).AddInput( - NewTransferOutputReference(transferHash1, addressHash1), + transferoutput.NewTransferOutputReference(transferHash1, addressHash1), ).AddOutput( addressHash2, NewColoredBalance(iota_, 1338), ).AddOutput( - addressHash2, NewColoredBalance(eth, 1024), + addressHash2, NewColoredBalance(eth, 1337), )); err != nil { t.Error(err) } // send funds further if err := ledgerState.BookTransfer(NewTransfer(transferHash3).AddInput( - NewTransferOutputReference(transferHash2, addressHash2), + transferoutput.NewTransferOutputReference(transferHash2, addressHash2), ).AddOutput( addressHash4, NewColoredBalance(iota_, 1338), ).AddOutput( - addressHash4, NewColoredBalance(eth, 1024), + addressHash4, NewColoredBalance(eth, 1337), )); err != nil { t.Error(err) } if err := ledgerState.BookTransfer(NewTransfer(transferHash4).AddInput( - NewTransferOutputReference(transferHash2, addressHash2), + transferoutput.NewTransferOutputReference(transferHash2, addressHash2), ).AddOutput( addressHash4, NewColoredBalance(iota_, 1338), ).AddOutput( - addressHash4, NewColoredBalance(eth, 1024), + addressHash4, NewColoredBalance(eth, 1337), )); err != nil { t.Error(err) } // aggregate realities if err := ledgerState.BookTransfer(NewTransfer(transferHash6).AddInput( - NewTransferOutputReference(transferHash3, addressHash4), + transferoutput.NewTransferOutputReference(transferHash3, addressHash4), ).AddInput( - NewTransferOutputReference(transferHash4, addressHash4), + transferoutput.NewTransferOutputReference(transferHash4, addressHash4), ).AddOutput( addressHash6, NewColoredBalance(iota_, 2676), ).AddOutput( @@ -338,11 +344,11 @@ func TestElevate(t *testing.T) { // create double spend for first transfer if err := ledgerState.BookTransfer(NewTransfer(transferHash5).AddInput( - NewTransferOutputReference(transferHash1, addressHash1), + transferoutput.NewTransferOutputReference(transferHash1, addressHash1), ).AddOutput( addressHash5, NewColoredBalance(iota_, 1338), ).AddOutput( - addressHash5, NewColoredBalance(eth, 1024), + addressHash5, NewColoredBalance(eth, 1337), )); err != nil { t.Error(err) } diff --git a/packages/ledgerstate/outputs.png b/packages/ledgerstate/outputs.png index e4b6b842208fe13225b399f6e213b750c101732d..fbc282cfbfb8ee744230710f46f058f8ff961ccd 100644 Binary files a/packages/ledgerstate/outputs.png and b/packages/ledgerstate/outputs.png differ diff --git a/packages/ledgerstate/outputs1.png b/packages/ledgerstate/outputs1.png index 57ed6f4633b7a13441ae570e908b6932fe4ff600..b695948cae29c186c1eb156ee1b0a736ab1045f6 100644 Binary files a/packages/ledgerstate/outputs1.png and b/packages/ledgerstate/outputs1.png differ diff --git a/packages/ledgerstate/outputs2.png b/packages/ledgerstate/outputs2.png index e795eee536931b189a1bc6f5e6640224ea531472..318df0d060ce04472b94f808926808a091490fe0 100644 Binary files a/packages/ledgerstate/outputs2.png and b/packages/ledgerstate/outputs2.png differ diff --git a/packages/ledgerstate/reality.go b/packages/ledgerstate/reality.go index 6036b96bc5d7a44dd0f0c41f7906dac3ab606a71..5265815a2a28059f2c32dd81ff78a29cc39ec982 100644 --- a/packages/ledgerstate/reality.go +++ b/packages/ledgerstate/reality.go @@ -4,6 +4,15 @@ import ( "sync" "sync/atomic" + "github.com/iotaledger/goshimmer/packages/ledgerstate/conflict" + + "github.com/iotaledger/goshimmer/packages/binary/types" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/binary/transferoutput" + "github.com/iotaledger/goshimmer/packages/binary/address" "github.com/iotaledger/goshimmer/packages/stringify" @@ -15,12 +24,12 @@ import ( type Reality struct { objectstorage.StorableObjectFlags - id RealityId - parentRealityIds RealityIdSet + id reality.Id + parentRealityIds reality.IdSet parentRealityIdsMutex sync.RWMutex - subRealityIds RealityIdSet + subRealityIds reality.IdSet subRealityIdsMutex sync.RWMutex - conflictIds ConflictIdSet + conflictIds conflict.IdSet conflictIdsMutex sync.RWMutex transferOutputCount uint32 preferred bool @@ -32,9 +41,9 @@ type Reality struct { ledgerState *LedgerState } -func (reality *Reality) areParentsLiked() (parentsLiked bool) { +func (mreality *Reality) areParentsLiked() (parentsLiked bool) { parentsLiked = true - for _, cachedParentReality := range reality.GetParentRealities() { + for _, cachedParentReality := range mreality.GetParentRealities() { if parentsLiked { cachedParentReality.Consume(func(object objectstorage.StorableObject) { parentsLiked = parentsLiked && object.(*Reality).IsLiked() @@ -47,14 +56,14 @@ func (reality *Reality) areParentsLiked() (parentsLiked bool) { return } -func (reality *Reality) propagateLiked() { - reality.likedMutex.Lock() - reality.liked = true - reality.likedMutex.Unlock() +func (mreality *Reality) propagateLiked() { + mreality.likedMutex.Lock() + mreality.liked = true + mreality.likedMutex.Unlock() - reality.SetModified() + mreality.SetModified() - for _, cachedSubReality := range reality.GetSubRealities() { + for _, cachedSubReality := range mreality.GetSubRealities() { if !cachedSubReality.Exists() { cachedSubReality.Release() @@ -66,7 +75,7 @@ func (reality *Reality) propagateLiked() { subReality := object.(*Reality) subReality.parentRealityIdsMutex.RLock() - if len(subReality.parentRealityIds) == 1 && subReality.parentRealityIds.Contains(reality.id) { + if len(subReality.parentRealityIds) == 1 && subReality.parentRealityIds.Contains(mreality.id) { subReality.parentRealityIdsMutex.RUnlock() subReality.propagateLiked() @@ -81,14 +90,14 @@ func (reality *Reality) propagateLiked() { } } -func (reality *Reality) propagateDisliked() { - reality.likedMutex.Lock() - reality.liked = false - reality.likedMutex.Unlock() +func (mreality *Reality) propagateDisliked() { + mreality.likedMutex.Lock() + mreality.liked = false + mreality.likedMutex.Unlock() - reality.SetModified() + mreality.SetModified() - for _, cachedSubReality := range reality.GetSubRealities() { + for _, cachedSubReality := range mreality.GetSubRealities() { if !cachedSubReality.Exists() { cachedSubReality.Release() @@ -106,57 +115,57 @@ func (reality *Reality) propagateDisliked() { } } -func (reality *Reality) GetSubRealities() (subRealities objectstorage.CachedObjects) { - reality.subRealityIdsMutex.RLock() - subRealities = make(objectstorage.CachedObjects, len(reality.subRealityIds)) +func (mreality *Reality) GetSubRealities() (subRealities objectstorage.CachedObjects) { + mreality.subRealityIdsMutex.RLock() + subRealities = make(objectstorage.CachedObjects, len(mreality.subRealityIds)) i := 0 - for subRealityId := range reality.subRealityIds { - subRealities[i] = reality.ledgerState.GetReality(subRealityId) + for subRealityId := range mreality.subRealityIds { + subRealities[i] = mreality.ledgerState.GetReality(subRealityId) i++ } - reality.subRealityIdsMutex.RUnlock() + mreality.subRealityIdsMutex.RUnlock() return } -func (reality *Reality) SetPreferred(preferred ...bool) (updated bool) { +func (mreality *Reality) SetPreferred(preferred ...bool) (updated bool) { newPreferredValue := len(preferred) == 0 || preferred[0] - reality.preferredMutex.RLock() - if reality.preferred != newPreferredValue { - reality.preferredMutex.RUnlock() + mreality.preferredMutex.RLock() + if mreality.preferred != newPreferredValue { + mreality.preferredMutex.RUnlock() - reality.preferredMutex.Lock() - if reality.preferred != newPreferredValue { - reality.preferred = newPreferredValue + mreality.preferredMutex.Lock() + if mreality.preferred != newPreferredValue { + mreality.preferred = newPreferredValue if newPreferredValue { - if reality.areParentsLiked() { - reality.propagateLiked() + if mreality.areParentsLiked() { + mreality.propagateLiked() } } else { - if reality.IsLiked() { - reality.propagateDisliked() + if mreality.IsLiked() { + mreality.propagateDisliked() } } updated = true - reality.SetModified() + mreality.SetModified() } - reality.preferredMutex.Unlock() + mreality.preferredMutex.Unlock() } else { - reality.preferredMutex.RUnlock() + mreality.preferredMutex.RUnlock() } return } -func (reality *Reality) IsPreferred() (preferred bool) { - reality.preferredMutex.RLock() - preferred = reality.preferred - reality.preferredMutex.RUnlock() +func (mreality *Reality) IsPreferred() (preferred bool) { + mreality.preferredMutex.RLock() + preferred = mreality.preferred + mreality.preferredMutex.RUnlock() return } @@ -164,12 +173,12 @@ func (reality *Reality) IsPreferred() (preferred bool) { // region DONE REVIEWING /////////////////////////////////////////////////////////////////////////////////////////////// // Creates a new Reality with the given id and parents. It is only used internally and therefore "private". -func newReality(id RealityId, parentRealities ...RealityId) *Reality { +func newReality(id reality.Id, parentRealities ...reality.Id) *Reality { result := &Reality{ id: id, - parentRealityIds: NewRealityIdSet(parentRealities...), - subRealityIds: NewRealityIdSet(), - conflictIds: NewConflictIdSet(), + parentRealityIds: reality.NewIdSet(parentRealities...), + subRealityIds: reality.NewIdSet(), + conflictIds: conflict.NewIdSet(), storageKey: make([]byte, len(id)), } @@ -178,68 +187,68 @@ func newReality(id RealityId, parentRealities ...RealityId) *Reality { return result } -func (reality *Reality) IsLiked() (liked bool) { - reality.likedMutex.RLock() - liked = reality.liked - reality.likedMutex.RUnlock() +func (mreality *Reality) IsLiked() (liked bool) { + mreality.likedMutex.RLock() + liked = mreality.liked + mreality.likedMutex.RUnlock() return } -func (reality *Reality) SetLiked(liked ...bool) (likedStatusChanged bool) { +func (mreality *Reality) SetLiked(liked ...bool) (likedStatusChanged bool) { newLikedStatus := len(liked) == 0 || liked[0] - reality.likedMutex.RLock() - if reality.liked != newLikedStatus { - reality.likedMutex.RUnlock() + mreality.likedMutex.RLock() + if mreality.liked != newLikedStatus { + mreality.likedMutex.RUnlock() - reality.likedMutex.Lock() - if reality.liked != newLikedStatus { - reality.liked = newLikedStatus + mreality.likedMutex.Lock() + if mreality.liked != newLikedStatus { + mreality.liked = newLikedStatus likedStatusChanged = true - reality.SetModified() + mreality.SetModified() } - reality.likedMutex.Unlock() + mreality.likedMutex.Unlock() } else { - reality.likedMutex.RUnlock() + mreality.likedMutex.RUnlock() } return } // Returns the id of this Reality. Since the id never changes, we do not need a mutex to protect this property. -func (reality *Reality) GetId() RealityId { - return reality.id +func (mreality *Reality) GetId() reality.Id { + return mreality.id } // Returns the set of RealityIds that are the parents of this Reality (it creates a clone). -func (reality *Reality) GetParentRealityIds() (realityIdSet RealityIdSet) { - reality.parentRealityIdsMutex.RLock() - realityIdSet = reality.parentRealityIds.Clone() - reality.parentRealityIdsMutex.RUnlock() +func (mreality *Reality) GetParentRealityIds() (realityIdSet reality.IdSet) { + mreality.parentRealityIdsMutex.RLock() + realityIdSet = mreality.parentRealityIds.Clone() + mreality.parentRealityIdsMutex.RUnlock() return } // Adds a new parent Reality to this Reality (it is used for aggregating aggregated Realities). -func (reality *Reality) AddParentReality(realityId RealityId) (realityAdded bool) { - reality.parentRealityIdsMutex.RLock() - if _, exists := reality.parentRealityIds[realityId]; !exists { - reality.parentRealityIdsMutex.RUnlock() +func (mreality *Reality) AddParentReality(realityId reality.Id) (realityAdded bool) { + mreality.parentRealityIdsMutex.RLock() + if _, exists := mreality.parentRealityIds[realityId]; !exists { + mreality.parentRealityIdsMutex.RUnlock() - reality.parentRealityIdsMutex.Lock() - if _, exists := reality.parentRealityIds[realityId]; !exists { - reality.parentRealityIds[realityId] = void + mreality.parentRealityIdsMutex.Lock() + if _, exists := mreality.parentRealityIds[realityId]; !exists { + mreality.parentRealityIds[realityId] = types.Void - reality.SetModified() + mreality.SetModified() realityAdded = true } - reality.parentRealityIdsMutex.Unlock() + mreality.parentRealityIdsMutex.Unlock() } else { - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() } return @@ -248,85 +257,85 @@ func (reality *Reality) AddParentReality(realityId RealityId) (realityAdded bool // Utility function that replaces the parent of a reality. // Since IO is the most expensive part of the ledger state, we only update the parents and mark the reality as modified // if either the oldRealityId exists or the newRealityId does not exist. -func (reality *Reality) replaceParentReality(oldRealityId RealityId, newRealityId RealityId) { - reality.parentRealityIdsMutex.RLock() - if _, oldRealityIdExist := reality.parentRealityIds[oldRealityId]; oldRealityIdExist { - reality.parentRealityIdsMutex.RUnlock() +func (mreality *Reality) replaceParentReality(oldRealityId reality.Id, newRealityId reality.Id) { + mreality.parentRealityIdsMutex.RLock() + if _, oldRealityIdExist := mreality.parentRealityIds[oldRealityId]; oldRealityIdExist { + mreality.parentRealityIdsMutex.RUnlock() - reality.parentRealityIdsMutex.Lock() - if _, oldRealityIdExist := reality.parentRealityIds[oldRealityId]; oldRealityIdExist { - delete(reality.parentRealityIds, oldRealityId) + mreality.parentRealityIdsMutex.Lock() + if _, oldRealityIdExist := mreality.parentRealityIds[oldRealityId]; oldRealityIdExist { + delete(mreality.parentRealityIds, oldRealityId) - if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist { - reality.parentRealityIds[newRealityId] = void + if _, newRealityIdExist := mreality.parentRealityIds[newRealityId]; !newRealityIdExist { + mreality.parentRealityIds[newRealityId] = types.Void } - reality.SetModified() + mreality.SetModified() } else { - if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist { - reality.parentRealityIds[newRealityId] = void + if _, newRealityIdExist := mreality.parentRealityIds[newRealityId]; !newRealityIdExist { + mreality.parentRealityIds[newRealityId] = types.Void - reality.SetModified() + mreality.SetModified() } } - reality.parentRealityIdsMutex.Unlock() + mreality.parentRealityIdsMutex.Unlock() } else { - if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist { - reality.parentRealityIdsMutex.RUnlock() + if _, newRealityIdExist := mreality.parentRealityIds[newRealityId]; !newRealityIdExist { + mreality.parentRealityIdsMutex.RUnlock() - reality.parentRealityIdsMutex.Lock() - if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist { - reality.parentRealityIds[newRealityId] = void + mreality.parentRealityIdsMutex.Lock() + if _, newRealityIdExist := mreality.parentRealityIds[newRealityId]; !newRealityIdExist { + mreality.parentRealityIds[newRealityId] = types.Void - reality.SetModified() + mreality.SetModified() } - reality.parentRealityIdsMutex.Unlock() + mreality.parentRealityIdsMutex.Unlock() } else { - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() } } } // Returns the amount of TransferOutputs in this Reality. -func (reality *Reality) GetTransferOutputCount() uint32 { - return atomic.LoadUint32(&(reality.transferOutputCount)) +func (mreality *Reality) GetTransferOutputCount() uint32 { + return atomic.LoadUint32(&(mreality.transferOutputCount)) } // Increases (and returns) the amount of TransferOutputs in this Reality. -func (reality *Reality) IncreaseTransferOutputCount() (transferOutputCount uint32) { - transferOutputCount = atomic.AddUint32(&(reality.transferOutputCount), 1) +func (mreality *Reality) IncreaseTransferOutputCount() (transferOutputCount uint32) { + transferOutputCount = atomic.AddUint32(&(mreality.transferOutputCount), 1) - reality.SetModified() + mreality.SetModified() return } // Decreases (and returns) the amount of TransferOutputs in this Reality. -func (reality *Reality) DecreaseTransferOutputCount() (transferOutputCount uint32) { - transferOutputCount = atomic.AddUint32(&(reality.transferOutputCount), ^uint32(0)) +func (mreality *Reality) DecreaseTransferOutputCount() (transferOutputCount uint32) { + transferOutputCount = atomic.AddUint32(&(mreality.transferOutputCount), ^uint32(0)) - reality.SetModified() + mreality.SetModified() return } // Returns true, if this reality is an "aggregated reality" that combines multiple other realities. -func (reality *Reality) IsAggregated() (isAggregated bool) { - reality.parentRealityIdsMutex.RLock() - isAggregated = len(reality.parentRealityIds) > 1 - reality.parentRealityIdsMutex.RUnlock() +func (mreality *Reality) IsAggregated() (isAggregated bool) { + mreality.parentRealityIdsMutex.RLock() + isAggregated = len(mreality.parentRealityIds) > 1 + mreality.parentRealityIdsMutex.RUnlock() return } // Returns true if the given RealityId addresses the Reality itself or one of its ancestors. -func (reality *Reality) DescendsFrom(realityId RealityId) bool { - if reality.id == realityId { +func (mreality *Reality) DescendsFrom(realityId reality.Id) bool { + if mreality.id == realityId { return true } else { descendsFromReality := false - for ancestorRealityId, ancestorReality := range reality.GetAncestorRealities() { + for ancestorRealityId, ancestorReality := range mreality.GetAncestorRealities() { if ancestorRealityId == realityId { descendsFromReality = true } @@ -340,34 +349,34 @@ func (reality *Reality) DescendsFrom(realityId RealityId) bool { // Returns a map of all parent realities (one level). They have to be "released" manually when they are not needed // anymore. -func (reality *Reality) GetParentRealities() (parentRealities map[RealityId]*objectstorage.CachedObject) { - parentRealities = make(map[RealityId]*objectstorage.CachedObject) +func (mreality *Reality) GetParentRealities() (parentRealities map[reality.Id]*objectstorage.CachedObject) { + parentRealities = make(map[reality.Id]*objectstorage.CachedObject) - reality.parentRealityIdsMutex.RLock() - for parentRealityId := range reality.parentRealityIds { - loadedParentReality := reality.ledgerState.GetReality(parentRealityId) + mreality.parentRealityIdsMutex.RLock() + for parentRealityId := range mreality.parentRealityIds { + loadedParentReality := mreality.ledgerState.GetReality(parentRealityId) if !loadedParentReality.Exists() { - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() panic("could not load parent reality with id \"" + string(parentRealityId[:]) + "\"") } parentRealities[loadedParentReality.Get().(*Reality).id] = loadedParentReality } - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() return } // Returns a map of all parent realities that are not aggregated (aggregated realities are "transparent"). They have to // be "released" manually when they are not needed anymore. -func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorage.CachedObject { - if !reality.IsAggregated() { - return reality.GetParentRealities() +func (mreality *Reality) GetParentConflictRealities() map[reality.Id]*objectstorage.CachedObject { + if !mreality.IsAggregated() { + return mreality.GetParentRealities() } else { - parentConflictRealities := make(map[RealityId]*objectstorage.CachedObject) + parentConflictRealities := make(map[reality.Id]*objectstorage.CachedObject) - reality.collectParentConflictRealities(parentConflictRealities) + mreality.collectParentConflictRealities(parentConflictRealities) return parentConflictRealities } @@ -375,10 +384,10 @@ func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorag // Returns a map of all ancestor realities (up till the MAIN_REALITY). They have to manually be "released" when they are // not needed anymore. -func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstorage.CachedObject) { - result = make(map[RealityId]*objectstorage.CachedObject, 1) +func (mreality *Reality) GetAncestorRealities() (result map[reality.Id]*objectstorage.CachedObject) { + result = make(map[reality.Id]*objectstorage.CachedObject, 1) - for parentRealityId, parentReality := range reality.GetParentRealities() { + for parentRealityId, parentReality := range mreality.GetParentRealities() { result[parentRealityId] = parentReality for ancestorId, ancestor := range parentReality.Get().(*Reality).GetAncestorRealities() { @@ -390,54 +399,54 @@ func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstor } // Registers the conflict set in the Reality. -func (reality *Reality) AddConflict(conflictSetId ConflictId) { - reality.conflictIdsMutex.RLock() - if _, exists := reality.conflictIds[conflictSetId]; !exists { - reality.conflictIdsMutex.RUnlock() +func (mreality *Reality) AddConflict(conflictSetId conflict.Id) { + mreality.conflictIdsMutex.RLock() + if _, exists := mreality.conflictIds[conflictSetId]; !exists { + mreality.conflictIdsMutex.RUnlock() - reality.conflictIdsMutex.Lock() - if _, exists := reality.conflictIds[conflictSetId]; !exists { - reality.conflictIds[conflictSetId] = void + mreality.conflictIdsMutex.Lock() + if _, exists := mreality.conflictIds[conflictSetId]; !exists { + mreality.conflictIds[conflictSetId] = types.Void - reality.SetModified() + mreality.SetModified() } - reality.conflictIdsMutex.Unlock() + mreality.conflictIdsMutex.Unlock() } else { - reality.conflictIdsMutex.RUnlock() + mreality.conflictIdsMutex.RUnlock() } } // Creates a new sub Reality and "stores" it. It has to manually be "released" when it is not needed anymore. -func (reality *Reality) CreateReality(id RealityId) *objectstorage.CachedObject { - newReality := newReality(id, reality.id) - newReality.ledgerState = reality.ledgerState +func (mreality *Reality) CreateReality(id reality.Id) *objectstorage.CachedObject { + newReality := newReality(id, mreality.id) + newReality.ledgerState = mreality.ledgerState - reality.RegisterSubReality(id) + mreality.RegisterSubReality(id) - return reality.ledgerState.realities.Store(newReality) + return mreality.ledgerState.realities.Store(newReality) } // Books a transfer into this reality (wrapper for the private bookTransfer function). -func (reality *Reality) BookTransfer(transfer *Transfer) (err error) { - err = reality.bookTransfer(transfer.GetHash(), reality.ledgerState.getTransferInputs(transfer), transfer.GetOutputs()) +func (mreality *Reality) BookTransfer(transfer *Transfer) (err error) { + err = mreality.bookTransfer(transfer.GetHash(), mreality.ledgerState.getTransferInputs(transfer), transfer.GetOutputs()) return } // Creates a string representation of this Reality. -func (reality *Reality) String() (result string) { - reality.parentRealityIdsMutex.RLock() - parentRealities := make([]string, len(reality.parentRealityIds)) +func (mreality *Reality) String() (result string) { + mreality.parentRealityIdsMutex.RLock() + parentRealities := make([]string, len(mreality.parentRealityIds)) i := 0 - for parentRealityId := range reality.parentRealityIds { + for parentRealityId := range mreality.parentRealityIds { parentRealities[i] = parentRealityId.String() i++ } - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() result = stringify.Struct("Reality", - stringify.StructField("id", reality.GetId().String()), + stringify.StructField("id", mreality.GetId().String()), stringify.StructField("parentRealities", parentRealities), ) @@ -445,17 +454,17 @@ func (reality *Reality) String() (result string) { } // Books a transfer into this reality (contains the dispatcher for the actual tasks). -func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectstorage.CachedObjects, outputs map[address.Address][]*ColoredBalance) (err error) { - if err = reality.verifyTransfer(inputs, outputs); err != nil { +func (mreality *Reality) bookTransfer(transferHash transfer.Hash, inputs objectstorage.CachedObjects, outputs map[address.Address][]*ColoredBalance) (err error) { + if err = mreality.verifyTransfer(inputs, outputs); err != nil { return } - conflicts, err := reality.consumeInputs(inputs, transferHash, outputs) + conflicts, err := mreality.consumeInputs(inputs, transferHash, outputs) if err != nil { return } - if err = reality.createTransferOutputs(transferHash, outputs, conflicts); err != nil { + if err = mreality.createTransferOutputs(transferHash, outputs, conflicts); err != nil { return } @@ -466,7 +475,7 @@ func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectsto } // Internal utility function that verifies the transfer and checks if it is valid (inputs exist + the net balance is 0). -func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, outputs map[address.Address][]*ColoredBalance) error { +func (mreality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, outputs map[address.Address][]*ColoredBalance) error { totalColoredBalances := make(map[Color]uint64) for _, cachedInput := range inputs { @@ -475,7 +484,7 @@ func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, out } input := cachedInput.Get().(*TransferOutput) - if !reality.DescendsFrom(input.GetRealityId()) { + if !mreality.DescendsFrom(input.GetRealityId()) { return errors.New("the referenced funds do not exist in this reality") } @@ -506,7 +515,7 @@ func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, out // Internal utility function that marks the consumed inputs as spent and returns the corresponding conflicts if the // inputs have been consumed before. -func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transferHash TransferHash, outputs map[address.Address][]*ColoredBalance) (conflicts objectstorage.CachedObjects, err error) { +func (mreality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transferHash transfer.Hash, outputs map[address.Address][]*ColoredBalance) (conflicts objectstorage.CachedObjects, err error) { conflicts = make(objectstorage.CachedObjects, 0) for _, input := range inputs { @@ -517,7 +526,7 @@ func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transf return } else if consumersToElevate != nil { - if conflict, conflictErr := reality.processConflictingInput(consumedInput, consumersToElevate); conflictErr != nil { + if conflict, conflictErr := mreality.processConflictingInput(consumedInput, consumersToElevate); conflictErr != nil { err = conflictErr return @@ -534,29 +543,29 @@ func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transf // // If the inputs have been used before and we consequently have a non-empty list of conflicts, we first create a new // reality for the inputs and then book the transfer outputs into the correct reality. -func (reality *Reality) createTransferOutputs(transferHash TransferHash, outputs map[address.Address][]*ColoredBalance, conflicts objectstorage.CachedObjects) (err error) { +func (mreality *Reality) createTransferOutputs(transferHash transfer.Hash, outputs map[address.Address][]*ColoredBalance, conflicts objectstorage.CachedObjects) (err error) { if len(conflicts) >= 1 { targetRealityId := transferHash.ToRealityId() - reality.CreateReality(targetRealityId).Consume(func(object objectstorage.StorableObject) { + mreality.CreateReality(targetRealityId).Consume(func(object objectstorage.StorableObject) { targetReality := object.(*Reality) for _, cachedConflictSet := range conflicts { - conflictSet := cachedConflictSet.Get().(*Conflict) + conflictSet := cachedConflictSet.Get().(*conflict.Conflict) conflictSet.AddReality(targetRealityId) targetReality.AddConflict(conflictSet.GetId()) } for addressHash, coloredBalances := range outputs { - if err = targetReality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil { + if err = targetReality.bookTransferOutput(NewTransferOutput(mreality.ledgerState, reality.EmptyId, transferHash, addressHash, coloredBalances...)); err != nil { return } } }) } else { for addressHash, coloredBalances := range outputs { - if err = reality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil { + if err = mreality.bookTransferOutput(NewTransferOutput(mreality.ledgerState, reality.EmptyId, transferHash, addressHash, coloredBalances...)); err != nil { return } } @@ -567,8 +576,8 @@ func (reality *Reality) createTransferOutputs(transferHash TransferHash, outputs // Utility function that collects all non-aggregated parent realities. It is used by GetParentConflictRealities and // prevents us from having to allocate multiple maps during recursion. -func (reality *Reality) collectParentConflictRealities(parentConflictRealities map[RealityId]*objectstorage.CachedObject) { - for realityId, cachedParentReality := range reality.GetParentRealities() { +func (mreality *Reality) collectParentConflictRealities(parentConflictRealities map[reality.Id]*objectstorage.CachedObject) { + for realityId, cachedParentReality := range mreality.GetParentRealities() { parentReality := cachedParentReality.Get().(*Reality) if !parentReality.IsAggregated() { @@ -583,21 +592,16 @@ func (reality *Reality) collectParentConflictRealities(parentConflictRealities m // Utility function that processes a conflicting input by retrieving the corresponding conflict. // If there is a non-empty list of consumers to elevate, we elevate them. -func (reality *Reality) processConflictingInput(input *TransferOutput, consumersToElevate map[TransferHash][]address.Address) (conflict *objectstorage.CachedObject, err error) { - conflictId := NewConflictId(input.GetTransferHash(), input.GetAddressHash()) +func (mreality *Reality) processConflictingInput(input *TransferOutput, consumersToElevate map[transfer.Hash][]address.Address) (cachedConflict *objectstorage.CachedObject, err error) { + conflictId := conflict.NewId(input.GetTransferHash(), input.GetAddressHash()) if len(consumersToElevate) >= 1 { - newConflict := newConflictSet(conflictId) - newConflict.ledgerState = reality.ledgerState - - conflict = reality.ledgerState.conflictSets.Store(newConflict) + cachedConflict = mreality.ledgerState.conflictSets.Store(conflict.New(conflictId)) - err = reality.createRealityForPreviouslyUnconflictingConsumers(consumersToElevate, conflict.Get().(*Conflict)) + err = mreality.createRealityForPreviouslyUnconflictingConsumers(consumersToElevate, cachedConflict.Get().(*conflict.Conflict)) } else { - if conflict, err = reality.ledgerState.conflictSets.Load(conflictId[:]); err != nil { + if cachedConflict, err = mreality.ledgerState.conflictSets.Load(conflictId[:]); err != nil { return - } else { - conflict.Get().(*Conflict).ledgerState = reality.ledgerState } } @@ -605,18 +609,18 @@ func (reality *Reality) processConflictingInput(input *TransferOutput, consumers } // Creates a Reality for the consumers of the conflicting inputs and registers it as part of the corresponding Conflict. -func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consumersOfConflictingInput map[TransferHash][]address.Address, conflict *Conflict) (err error) { +func (mreality *Reality) createRealityForPreviouslyUnconflictingConsumers(consumersOfConflictingInput map[transfer.Hash][]address.Address, conflict *conflict.Conflict) (err error) { for transferHash, addressHashes := range consumersOfConflictingInput { elevatedRealityId := transferHash.ToRealityId() // Retrieve the Reality for this Transfer or create one if no Reality exists, yet. var realityIsNew bool - if cachedElevatedReality, realityErr := reality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) { - newReality := newReality(elevatedRealityId, reality.id) - newReality.ledgerState = reality.ledgerState + if cachedElevatedReality, realityErr := mreality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) { + newReality := newReality(elevatedRealityId, mreality.id) + newReality.ledgerState = mreality.ledgerState newReality.SetPreferred() - reality.RegisterSubReality(elevatedRealityId) + mreality.RegisterSubReality(elevatedRealityId) newReality.Persist() newReality.SetModified() @@ -640,7 +644,7 @@ func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consume // Reality is created the first time). if realityIsNew { for _, addressHash := range addressHashes { - if err = reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), elevatedReality); err != nil { + if err = mreality.elevateTransferOutput(transferoutput.NewTransferOutputReference(transferHash, addressHash), elevatedReality); err != nil { return } } @@ -653,20 +657,20 @@ func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consume } // Private utility function that elevates a transfer output to the given reality. -func (reality *Reality) elevateTransferOutput(transferOutputReference *TransferOutputReference, newReality *Reality) (err error) { - if cachedTransferOutputToElevate := reality.ledgerState.GetTransferOutput(transferOutputReference); !cachedTransferOutputToElevate.Exists() { +func (mreality *Reality) elevateTransferOutput(transferOutputReference *transferoutput.Reference, newReality *Reality) (err error) { + if cachedTransferOutputToElevate := mreality.ledgerState.GetTransferOutput(transferOutputReference); !cachedTransferOutputToElevate.Exists() { err = errors.New("could not find TransferOutput to elevate") } else { cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) { transferOutputToElevate := object.(*TransferOutput) - if currentTransferOutputRealityId := transferOutputToElevate.GetRealityId(); currentTransferOutputRealityId == reality.GetId() { - err = reality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality) - } else if cachedNestedReality := reality.ledgerState.GetReality(currentTransferOutputRealityId); !cachedNestedReality.Exists() { + if currentTransferOutputRealityId := transferOutputToElevate.GetRealityId(); currentTransferOutputRealityId == mreality.GetId() { + err = mreality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality) + } else if cachedNestedReality := mreality.ledgerState.GetReality(currentTransferOutputRealityId); !cachedNestedReality.Exists() { err = errors.New("could not find nested reality to elevate TransferOutput") } else { cachedNestedReality.Consume(func(nestedReality objectstorage.StorableObject) { - err = nestedReality.(*Reality).elevateTransferOutputOfNestedReality(transferOutputToElevate, reality.GetId(), newReality.GetId()) + err = nestedReality.(*Reality).elevateTransferOutputOfNestedReality(transferOutputToElevate, mreality.GetId(), newReality.GetId()) }) } }) @@ -676,10 +680,10 @@ func (reality *Reality) elevateTransferOutput(transferOutputReference *TransferO } // Private utility function that elevates the transfer output from the current reality to the new reality. -func (reality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *TransferOutput, newReality *Reality) (err error) { +func (mreality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *TransferOutput, newReality *Reality) (err error) { for transferHash, addresses := range transferOutput.GetConsumers() { for _, addressHash := range addresses { - if elevateErr := reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil { + if elevateErr := mreality.elevateTransferOutput(transferoutput.NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil { err = elevateErr return @@ -694,85 +698,85 @@ func (reality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *Tr // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// -func (reality *Reality) GetSubRealityIdCount() (subRealityIdCount int) { - reality.subRealityIdsMutex.RLock() - subRealityIdCount = len(reality.subRealityIds) - reality.subRealityIdsMutex.RUnlock() +func (mreality *Reality) GetSubRealityIdCount() (subRealityIdCount int) { + mreality.subRealityIdsMutex.RLock() + subRealityIdCount = len(mreality.subRealityIds) + mreality.subRealityIdsMutex.RUnlock() return } -func (reality *Reality) UnregisterSubReality(realityId RealityId) { - reality.subRealityIdsMutex.RLock() - if _, subRealityIdExists := reality.subRealityIds[realityId]; subRealityIdExists { - reality.subRealityIdsMutex.RUnlock() +func (mreality *Reality) UnregisterSubReality(realityId reality.Id) { + mreality.subRealityIdsMutex.RLock() + if _, subRealityIdExists := mreality.subRealityIds[realityId]; subRealityIdExists { + mreality.subRealityIdsMutex.RUnlock() - reality.subRealityIdsMutex.Lock() - if _, subRealityIdExists := reality.subRealityIds[realityId]; subRealityIdExists { - delete(reality.subRealityIds, realityId) + mreality.subRealityIdsMutex.Lock() + if _, subRealityIdExists := mreality.subRealityIds[realityId]; subRealityIdExists { + delete(mreality.subRealityIds, realityId) - reality.SetModified() + mreality.SetModified() } - reality.subRealityIdsMutex.Unlock() + mreality.subRealityIdsMutex.Unlock() } else { - reality.subRealityIdsMutex.RUnlock() + mreality.subRealityIdsMutex.RUnlock() } } -func (reality *Reality) RegisterSubReality(realityId RealityId) { - reality.subRealityIdsMutex.RLock() - if _, subRealityIdExists := reality.subRealityIds[realityId]; !subRealityIdExists { - reality.subRealityIdsMutex.RUnlock() +func (mreality *Reality) RegisterSubReality(realityId reality.Id) { + mreality.subRealityIdsMutex.RLock() + if _, subRealityIdExists := mreality.subRealityIds[realityId]; !subRealityIdExists { + mreality.subRealityIdsMutex.RUnlock() - reality.subRealityIdsMutex.Lock() - if _, subRealityIdExists := reality.subRealityIds[realityId]; !subRealityIdExists { - reality.subRealityIds[realityId] = void + mreality.subRealityIdsMutex.Lock() + if _, subRealityIdExists := mreality.subRealityIds[realityId]; !subRealityIdExists { + mreality.subRealityIds[realityId] = types.Void - reality.SetModified() + mreality.SetModified() } - reality.subRealityIdsMutex.Unlock() + mreality.subRealityIdsMutex.Unlock() } else { - reality.subRealityIdsMutex.RUnlock() + mreality.subRealityIdsMutex.RUnlock() } } -func (reality *Reality) elevateTransferOutputOfNestedReality(transferOutput *TransferOutput, oldParentRealityId RealityId, newParentRealityId RealityId) (err error) { - if !reality.IsAggregated() { - reality.replaceParentReality(oldParentRealityId, newParentRealityId) +func (mreality *Reality) elevateTransferOutputOfNestedReality(transferOutput *TransferOutput, oldParentRealityId reality.Id, newParentRealityId reality.Id) (err error) { + if !mreality.IsAggregated() { + mreality.replaceParentReality(oldParentRealityId, newParentRealityId) } else { - reality.ledgerState.AggregateRealities(reality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()...).Consume(func(newAggregatedReality objectstorage.StorableObject) { + mreality.ledgerState.AggregateRealities(mreality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()...).Consume(func(newAggregatedReality objectstorage.StorableObject) { newAggregatedReality.Persist() - err = reality.elevateTransferOutputOfCurrentReality(transferOutput, newAggregatedReality.(*Reality)) + err = mreality.elevateTransferOutputOfCurrentReality(transferOutput, newAggregatedReality.(*Reality)) }) } return } -func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err error) { +func (mreality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err error) { // retrieve required variables - realityId := reality.id + realityId := mreality.id transferOutputRealityId := transferOutput.GetRealityId() transferOutputAddressHash := transferOutput.GetAddressHash() transferOutputSpent := len(transferOutput.consumers) >= 1 transferOutputTransferHash := transferOutput.GetTransferHash() // store the transferOutput if it is "new" - if transferOutputRealityId == emptyRealityId { + if transferOutputRealityId == reality.EmptyId { transferOutput.SetRealityId(realityId) - reality.ledgerState.storeTransferOutput(transferOutput).Release() + mreality.ledgerState.storeTransferOutput(transferOutput).Release() } else // remove old booking if the TransferOutput is currently booked in another reality if transferOutputRealityId != realityId { - if oldTransferOutputBooking, err := reality.ledgerState.transferOutputBookings.Load(generateTransferOutputBookingStorageKey(transferOutputRealityId, transferOutputAddressHash, len(transferOutput.consumers) >= 1, transferOutput.GetTransferHash())); err != nil { + if oldTransferOutputBooking, err := mreality.ledgerState.transferOutputBookings.Load(generateTransferOutputBookingStorageKey(transferOutputRealityId, transferOutputAddressHash, len(transferOutput.consumers) >= 1, transferOutput.GetTransferHash())); err != nil { return err } else { transferOutput.SetRealityId(realityId) - reality.ledgerState.GetReality(transferOutputRealityId).Consume(func(object objectstorage.StorableObject) { + mreality.ledgerState.GetReality(transferOutputRealityId).Consume(func(object objectstorage.StorableObject) { transferOutputReality := object.(*Reality) // decrease transferOutputCount and remove reality if it is empty @@ -794,9 +798,9 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err // book the TransferOutput into the current Reality if transferOutputRealityId != realityId { - reality.ledgerState.storeTransferOutputBooking(newTransferOutputBooking(realityId, transferOutputAddressHash, transferOutputSpent, transferOutputTransferHash)).Release() + mreality.ledgerState.storeTransferOutputBooking(newTransferOutputBooking(realityId, transferOutputAddressHash, transferOutputSpent, transferOutputTransferHash)).Release() - reality.IncreaseTransferOutputCount() + mreality.IncreaseTransferOutputCount() } return diff --git a/packages/ledgerstate/reality.objectstorage.go b/packages/ledgerstate/reality.objectstorage.go index fac42376ff3104ca79619217c4686232bcb442be..6371349e46aee66f7ef14c60bcc9ed9e9f4b1f55 100644 --- a/packages/ledgerstate/reality.objectstorage.go +++ b/packages/ledgerstate/reality.objectstorage.go @@ -3,144 +3,148 @@ package ledgerstate import ( "encoding/binary" + "github.com/iotaledger/goshimmer/packages/binary/types" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + "github.com/iotaledger/hive.go/bitmask" "github.com/iotaledger/hive.go/objectstorage" ) -func (reality *Reality) GetStorageKey() []byte { - return reality.storageKey +func (mreality *Reality) GetStorageKey() []byte { + return mreality.storageKey } -func (reality *Reality) Update(other objectstorage.StorableObject) { +func (mreality *Reality) Update(other objectstorage.StorableObject) { if otherReality, ok := other.(*Reality); !ok { panic("Update method expects a *TransferOutputBooking") } else { - reality.parentRealityIdsMutex.Lock() - reality.parentRealityIds = otherReality.parentRealityIds - reality.parentRealityIdsMutex.Unlock() + mreality.parentRealityIdsMutex.Lock() + mreality.parentRealityIds = otherReality.parentRealityIds + mreality.parentRealityIdsMutex.Unlock() } } -func (reality *Reality) MarshalBinary() ([]byte, error) { - reality.parentRealityIdsMutex.RLock() +func (mreality *Reality) MarshalBinary() ([]byte, error) { + mreality.parentRealityIdsMutex.RLock() - parentRealityCount := len(reality.parentRealityIds) - subRealityCount := len(reality.subRealityIds) + parentRealityCount := len(mreality.parentRealityIds) + subRealityCount := len(mreality.subRealityIds) - marshaledReality := make([]byte, 1+4+4+4+parentRealityCount*realityIdLength+subRealityCount*realityIdLength) + marshaledReality := make([]byte, 1+4+4+4+parentRealityCount*reality.IdLength+subRealityCount*reality.IdLength) offset := 0 var flags bitmask.BitMask - if reality.IsPreferred() { + if mreality.IsPreferred() { flags = flags.SetFlag(0) } - if reality.IsLiked() { + if mreality.IsLiked() { flags = flags.SetFlag(1) } marshaledReality[offset] = byte(flags) offset += 1 - binary.LittleEndian.PutUint32(marshaledReality[offset:], reality.GetTransferOutputCount()) + binary.LittleEndian.PutUint32(marshaledReality[offset:], mreality.GetTransferOutputCount()) offset += 4 binary.LittleEndian.PutUint32(marshaledReality[offset:], uint32(parentRealityCount)) offset += 4 - for parentRealityId := range reality.parentRealityIds { + for parentRealityId := range mreality.parentRealityIds { copy(marshaledReality[offset:], parentRealityId[:]) - offset += realityIdLength + offset += reality.IdLength } binary.LittleEndian.PutUint32(marshaledReality[offset:], uint32(subRealityCount)) offset += 4 - for subRealityId := range reality.subRealityIds { + for subRealityId := range mreality.subRealityIds { copy(marshaledReality[offset:], subRealityId[:]) - offset += realityIdLength + offset += reality.IdLength } - reality.parentRealityIdsMutex.RUnlock() + mreality.parentRealityIdsMutex.RUnlock() return marshaledReality, nil } -func (reality *Reality) UnmarshalBinary(serializedObject []byte) (err error) { - if err = reality.id.UnmarshalBinary(reality.storageKey[:realityIdLength]); err != nil { +func (mreality *Reality) UnmarshalBinary(serializedObject []byte) (err error) { + if err = mreality.id.UnmarshalBinary(mreality.storageKey[:reality.IdLength]); err != nil { return } offset := 0 - reality.unmarshalBinaryFlags(serializedObject, &offset) + mreality.unmarshalBinaryFlags(serializedObject, &offset) - reality.unmarshalBinaryTransferOutputCount(serializedObject, &offset) + mreality.unmarshalBinaryTransferOutputCount(serializedObject, &offset) - if err = reality.unmarshalBinaryParentRealities(serializedObject, &offset); err != nil { + if err = mreality.unmarshalBinaryParentRealities(serializedObject, &offset); err != nil { return } - if err = reality.unmarshalBinarySubRealities(serializedObject, &offset); err != nil { + if err = mreality.unmarshalBinarySubRealities(serializedObject, &offset); err != nil { return } return nil } -func (reality *Reality) unmarshalBinaryFlags(serializedObject []byte, offset *int) { +func (mreality *Reality) unmarshalBinaryFlags(serializedObject []byte, offset *int) { var flags = bitmask.BitMask(serializedObject[*offset]) if flags.HasFlag(0) { - reality.preferred = true + mreality.preferred = true } if flags.HasFlag(1) { - reality.liked = true + mreality.liked = true } *offset += 1 } -func (reality *Reality) unmarshalBinaryTransferOutputCount(serializedObject []byte, offset *int) { - reality.transferOutputCount = binary.LittleEndian.Uint32(serializedObject[*offset:]) +func (mreality *Reality) unmarshalBinaryTransferOutputCount(serializedObject []byte, offset *int) { + mreality.transferOutputCount = binary.LittleEndian.Uint32(serializedObject[*offset:]) *offset = *offset + 4 } -func (reality *Reality) unmarshalBinaryParentRealities(serializedObject []byte, offset *int) (err error) { - reality.parentRealityIds = NewRealityIdSet() +func (mreality *Reality) unmarshalBinaryParentRealities(serializedObject []byte, offset *int) (err error) { + mreality.parentRealityIds = reality.NewIdSet() parentRealityCount := int(binary.LittleEndian.Uint32(serializedObject[*offset:])) *offset += 4 for i := 0; i < parentRealityCount; i++ { - var restoredRealityId RealityId + var restoredRealityId reality.Id if err = restoredRealityId.UnmarshalBinary(serializedObject[*offset:]); err != nil { return } - *offset += realityIdLength + *offset += reality.IdLength - reality.parentRealityIds[restoredRealityId] = void + mreality.parentRealityIds[restoredRealityId] = types.Void } return } -func (reality *Reality) unmarshalBinarySubRealities(serializedObject []byte, offset *int) (err error) { - reality.subRealityIds = NewRealityIdSet() +func (mreality *Reality) unmarshalBinarySubRealities(serializedObject []byte, offset *int) (err error) { + mreality.subRealityIds = reality.NewIdSet() subRealityCount := int(binary.LittleEndian.Uint32(serializedObject[*offset:])) *offset += 4 for i := 0; i < subRealityCount; i++ { - var restoredRealityId RealityId + var restoredRealityId reality.Id if err = restoredRealityId.UnmarshalBinary(serializedObject[*offset:]); err != nil { return } - *offset += realityIdLength + *offset += reality.IdLength - reality.subRealityIds[restoredRealityId] = void + mreality.subRealityIds[restoredRealityId] = types.Void } return diff --git a/packages/ledgerstate/reality/id.go b/packages/ledgerstate/reality/id.go new file mode 100644 index 0000000000000000000000000000000000000000..33e3c5aacef58cb1abd43fb51c34733c9c822290 --- /dev/null +++ b/packages/ledgerstate/reality/id.go @@ -0,0 +1,33 @@ +package reality + +import ( + "unicode/utf8" + + "github.com/iotaledger/goshimmer/packages/stringify" +) + +type Id [IdLength]byte + +func NewId(realityId string) (result Id) { + copy(result[:], realityId) + + return +} + +func (id *Id) UnmarshalBinary(data []byte) error { + copy(id[:], data[:IdLength]) + + return nil +} + +func (id Id) String() string { + if utf8.Valid(id[:]) { + return string(id[:]) + } else { + return stringify.SliceOfBytes(id[:]) + } +} + +var EmptyId = Id{} + +const IdLength = 32 diff --git a/packages/ledgerstate/reality/id_list.go b/packages/ledgerstate/reality/id_list.go new file mode 100644 index 0000000000000000000000000000000000000000..b200c0e0796890cb7536f27dd089c961f9c7a614 --- /dev/null +++ b/packages/ledgerstate/reality/id_list.go @@ -0,0 +1,27 @@ +package reality + +import ( + "github.com/iotaledger/goshimmer/packages/binary/types" +) + +type IdList []Id + +func (idList IdList) Clone() (clone IdList) { + clone = make(IdList, len(idList)) + + for key, value := range idList { + clone[key] = value + } + + return +} + +func (idList IdList) ToSet() (set IdSet) { + set = make(IdSet) + + for _, value := range idList { + set[value] = types.Void + } + + return +} diff --git a/packages/ledgerstate/reality/id_set.go b/packages/ledgerstate/reality/id_set.go new file mode 100644 index 0000000000000000000000000000000000000000..e9dffffce395ad57e5d438be82abb13c1625523c --- /dev/null +++ b/packages/ledgerstate/reality/id_set.go @@ -0,0 +1,56 @@ +package reality + +import "github.com/iotaledger/goshimmer/packages/binary/types" + +type IdSet map[Id]types.Empty + +func NewIdSet(realityIds ...Id) (realityIdSet IdSet) { + realityIdSet = make(IdSet) + + for _, realityId := range realityIds { + realityIdSet[realityId] = types.Void + } + + return +} + +func (realityIdSet IdSet) Contains(realityId Id) bool { + _, exists := realityIdSet[realityId] + + return exists +} + +func (realityIdSet IdSet) Add(realityId Id) IdSet { + realityIdSet[realityId] = types.Void + + return realityIdSet +} + +func (realityIdSet IdSet) Remove(realityId Id) IdSet { + delete(realityIdSet, realityId) + + return realityIdSet +} + +func (realityIdSet IdSet) Clone() (clone IdSet) { + clone = make(IdSet, len(realityIdSet)) + + for key := range realityIdSet { + clone[key] = types.Void + } + + return +} + +func (realityIdSet IdSet) ToList() (list IdList) { + list = make(IdList, len(realityIdSet)) + + i := 0 + for key := range realityIdSet { + list[i] = key + + i++ + } + + return +} diff --git a/packages/ledgerstate/reality_id.go b/packages/ledgerstate/reality_id.go deleted file mode 100644 index 9f07e4b0258c90e33cb7cd1c6a05278838e1fd71..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/reality_id.go +++ /dev/null @@ -1,33 +0,0 @@ -package ledgerstate - -import ( - "unicode/utf8" - - "github.com/iotaledger/goshimmer/packages/stringify" -) - -type RealityId [realityIdLength]byte - -func NewRealityId(realityId string) (result RealityId) { - copy(result[:], realityId) - - return -} - -func (realityId *RealityId) UnmarshalBinary(data []byte) error { - copy(realityId[:], data[:realityIdLength]) - - return nil -} - -func (realityId RealityId) String() string { - if utf8.Valid(realityId[:]) { - return string(realityId[:]) - } else { - return stringify.SliceOfBytes(realityId[:]) - } -} - -var emptyRealityId = RealityId{} - -const realityIdLength = 32 diff --git a/packages/ledgerstate/reality_id_list.go b/packages/ledgerstate/reality_id_list.go deleted file mode 100644 index 1d6189cdf9aab39a2a9c121ef39ec5487db2fca0..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/reality_id_list.go +++ /dev/null @@ -1,23 +0,0 @@ -package ledgerstate - -type RealityIdList []RealityId - -func (realityIdList RealityIdList) Clone() (clone RealityIdList) { - clone = make(RealityIdList, len(realityIdList)) - - for key, value := range realityIdList { - clone[key] = value - } - - return -} - -func (realityIdList RealityIdList) ToSet() (set RealityIdSet) { - set = make(RealityIdSet) - - for _, value := range realityIdList { - set[value] = void - } - - return -} diff --git a/packages/ledgerstate/reality_id_set.go b/packages/ledgerstate/reality_id_set.go deleted file mode 100644 index e5c6ce54f93e73e47277342557238018858e2db4..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/reality_id_set.go +++ /dev/null @@ -1,54 +0,0 @@ -package ledgerstate - -type RealityIdSet map[RealityId]empty - -func NewRealityIdSet(realityIds ...RealityId) (realityIdSet RealityIdSet) { - realityIdSet = make(RealityIdSet) - - for _, realityId := range realityIds { - realityIdSet[realityId] = void - } - - return -} - -func (realityIdSet RealityIdSet) Contains(realityId RealityId) bool { - _, exists := realityIdSet[realityId] - - return exists -} - -func (realityIdSet RealityIdSet) Add(realityId RealityId) RealityIdSet { - realityIdSet[realityId] = void - - return realityIdSet -} - -func (realityIdSet RealityIdSet) Remove(realityId RealityId) RealityIdSet { - delete(realityIdSet, realityId) - - return realityIdSet -} - -func (realityIdSet RealityIdSet) Clone() (clone RealityIdSet) { - clone = make(RealityIdSet, len(realityIdSet)) - - for key := range realityIdSet { - clone[key] = void - } - - return -} - -func (realityIdSet RealityIdSet) ToList() (list RealityIdList) { - list = make(RealityIdList, len(realityIdSet)) - - i := 0 - for key := range realityIdSet { - list[i] = key - - i++ - } - - return -} diff --git a/packages/ledgerstate/transfer.go b/packages/ledgerstate/transfer.go index 9398631fcd19bd340c993822d840efc5707fdd90..d5ade36c08fb2f1a3f068e235e676293e089763a 100644 --- a/packages/ledgerstate/transfer.go +++ b/packages/ledgerstate/transfer.go @@ -2,31 +2,33 @@ package ledgerstate import ( "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/binary/transferoutput" ) type Transfer struct { - hash TransferHash - inputs []*TransferOutputReference + hash transfer.Hash + inputs []*transferoutput.Reference outputs map[address.Address][]*ColoredBalance } -func NewTransfer(transferHash TransferHash) *Transfer { +func NewTransfer(transferHash transfer.Hash) *Transfer { return &Transfer{ hash: transferHash, - inputs: make([]*TransferOutputReference, 0), + inputs: make([]*transferoutput.Reference, 0), outputs: make(map[address.Address][]*ColoredBalance), } } -func (transfer *Transfer) GetHash() TransferHash { +func (transfer *Transfer) GetHash() transfer.Hash { return transfer.hash } -func (transfer *Transfer) GetInputs() []*TransferOutputReference { +func (transfer *Transfer) GetInputs() []*transferoutput.Reference { return transfer.inputs } -func (transfer *Transfer) AddInput(input *TransferOutputReference) *Transfer { +func (transfer *Transfer) AddInput(input *transferoutput.Reference) *Transfer { transfer.inputs = append(transfer.inputs, input) return transfer diff --git a/packages/ledgerstate/transfer_hash.go b/packages/ledgerstate/transfer_hash.go index 4c9a92615cd3d67b8269e7b4d50cfce91a870161..35093ba49055b0d2ecd0e6c413d16d5b01c9d431 100644 --- a/packages/ledgerstate/transfer_hash.go +++ b/packages/ledgerstate/transfer_hash.go @@ -1,11 +1,6 @@ package ledgerstate -import ( - "unicode/utf8" - - "github.com/iotaledger/goshimmer/packages/stringify" -) - +/* type TransferHash [transferHashLength]byte func NewTransferHash(transferHash string) (result TransferHash) { @@ -35,3 +30,4 @@ func (transferHash TransferHash) String() string { } const transferHashLength = 32 +*/ diff --git a/packages/ledgerstate/transfer_output.go b/packages/ledgerstate/transfer_output.go index f814da77ea67b4b7a67ebe7b553e53b2dd0d776d..2af500e8adcea187e18ec38739dbbd9e0939778a 100644 --- a/packages/ledgerstate/transfer_output.go +++ b/packages/ledgerstate/transfer_output.go @@ -4,6 +4,10 @@ import ( "encoding/binary" "sync" + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/binary/address" "github.com/iotaledger/goshimmer/packages/stringify" @@ -13,11 +17,11 @@ import ( type TransferOutput struct { objectstorage.StorableObjectFlags - transferHash TransferHash + transferHash transfer.Hash addressHash address.Address balances []*ColoredBalance - realityId RealityId - consumers map[TransferHash][]address.Address + realityId reality.Id + consumers map[transfer.Hash][]address.Address storageKey []byte ledgerState *LedgerState @@ -27,26 +31,26 @@ type TransferOutput struct { bookingMutex sync.Mutex } -func NewTransferOutput(ledgerState *LedgerState, realityId RealityId, transferHash TransferHash, addressHash address.Address, balances ...*ColoredBalance) *TransferOutput { +func NewTransferOutput(ledgerState *LedgerState, realityId reality.Id, transferHash transfer.Hash, addressHash address.Address, balances ...*ColoredBalance) *TransferOutput { return &TransferOutput{ transferHash: transferHash, addressHash: addressHash, balances: balances, realityId: realityId, - consumers: make(map[TransferHash][]address.Address), + consumers: make(map[transfer.Hash][]address.Address), storageKey: append(transferHash[:], addressHash[:]...), ledgerState: ledgerState, } } -func (transferOutput *TransferOutput) GetTransferHash() (transferHash TransferHash) { +func (transferOutput *TransferOutput) GetTransferHash() (transferHash transfer.Hash) { transferHash = transferOutput.transferHash return } -func (transferOutput *TransferOutput) GetRealityId() (realityId RealityId) { +func (transferOutput *TransferOutput) GetRealityId() (realityId reality.Id) { transferOutput.realityIdMutex.RLock() realityId = transferOutput.realityId transferOutput.realityIdMutex.RUnlock() @@ -58,7 +62,7 @@ func (transferOutput *TransferOutput) GetAddressHash() (addressHash address.Addr return transferOutput.addressHash } -func (transferOutput *TransferOutput) SetRealityId(realityId RealityId) { +func (transferOutput *TransferOutput) SetRealityId(realityId reality.Id) { transferOutput.realityIdMutex.RLock() if transferOutput.realityId != realityId { transferOutput.realityIdMutex.RUnlock() @@ -79,8 +83,8 @@ func (transferOutput *TransferOutput) GetBalances() []*ColoredBalance { return transferOutput.balances } -func (transferOutput *TransferOutput) GetConsumers() (consumers map[TransferHash][]address.Address) { - consumers = make(map[TransferHash][]address.Address) +func (transferOutput *TransferOutput) GetConsumers() (consumers map[transfer.Hash][]address.Address) { + consumers = make(map[transfer.Hash][]address.Address) transferOutput.consumersMutex.RLock() for transferHash, addresses := range transferOutput.consumers { @@ -92,7 +96,7 @@ func (transferOutput *TransferOutput) GetConsumers() (consumers map[TransferHash return } -func (transferOutput *TransferOutput) addConsumer(consumer TransferHash, outputs map[address.Address][]*ColoredBalance) (consumersToElevate map[TransferHash][]address.Address, err error) { +func (transferOutput *TransferOutput) addConsumer(consumer transfer.Hash, outputs map[address.Address][]*ColoredBalance) (consumersToElevate map[transfer.Hash][]address.Address, err error) { transferOutput.consumersMutex.RLock() if _, exist := transferOutput.consumers[consumer]; exist { transferOutput.consumersMutex.RUnlock() @@ -105,13 +109,13 @@ func (transferOutput *TransferOutput) addConsumer(consumer TransferHash, outputs consumersToElevate = nil err = transferOutput.markAsSpent() case 1: - consumersToElevate = make(map[TransferHash][]address.Address, 1) + consumersToElevate = make(map[transfer.Hash][]address.Address, 1) for transferHash, addresses := range transferOutput.consumers { consumersToElevate[transferHash] = addresses } err = nil default: - consumersToElevate = make(map[TransferHash][]address.Address) + consumersToElevate = make(map[transfer.Hash][]address.Address) err = nil } consumers := make([]address.Address, len(outputs)) @@ -177,7 +181,7 @@ func (transferOutput *TransferOutput) MarshalBinary() ([]byte, error) { balanceCount := len(transferOutput.balances) consumerCount := len(transferOutput.consumers) - serializedLength := realityIdLength + 4 + balanceCount*coloredBalanceLength + 4 + consumerCount*transferHashLength + serializedLength := reality.IdLength + 4 + balanceCount*coloredBalanceLength + 4 + consumerCount*transfer.HashLength for _, addresses := range transferOutput.consumers { serializedLength += 4 for range addresses { @@ -189,18 +193,18 @@ func (transferOutput *TransferOutput) MarshalBinary() ([]byte, error) { copy(result[0:], transferOutput.realityId[:]) - binary.LittleEndian.PutUint32(result[realityIdLength:], uint32(balanceCount)) + binary.LittleEndian.PutUint32(result[reality.IdLength:], uint32(balanceCount)) for i := 0; i < balanceCount; i++ { - copy(result[realityIdLength+4+i*coloredBalanceLength:], transferOutput.balances[i].color[:colorLength]) - binary.LittleEndian.PutUint64(result[realityIdLength+4+i*coloredBalanceLength+colorLength:], transferOutput.balances[i].balance) + copy(result[reality.IdLength+4+i*coloredBalanceLength:], transferOutput.balances[i].color[:colorLength]) + binary.LittleEndian.PutUint64(result[reality.IdLength+4+i*coloredBalanceLength+colorLength:], transferOutput.balances[i].balance) } - offset := realityIdLength + 4 + balanceCount*coloredBalanceLength + offset := reality.IdLength + 4 + balanceCount*coloredBalanceLength binary.LittleEndian.PutUint32(result[offset:], uint32(consumerCount)) offset += 4 for transferHash, addresses := range transferOutput.consumers { - copy(result[offset:], transferHash[:transferHashLength]) - offset += transferHashLength + copy(result[offset:], transferHash[:transfer.HashLength]) + offset += transfer.HashLength binary.LittleEndian.PutUint32(result[offset:], uint32(len(addresses))) offset += 4 @@ -218,25 +222,25 @@ func (transferOutput *TransferOutput) MarshalBinary() ([]byte, error) { } func (transferOutput *TransferOutput) UnmarshalBinary(serializedObject []byte) error { - if err := transferOutput.transferHash.UnmarshalBinary(transferOutput.storageKey[:transferHashLength]); err != nil { + if err := transferOutput.transferHash.UnmarshalBinary(transferOutput.storageKey[:transfer.HashLength]); err != nil { return err } - if err := transferOutput.addressHash.UnmarshalBinary(transferOutput.storageKey[transferHashLength:]); err != nil { + if err := transferOutput.addressHash.UnmarshalBinary(transferOutput.storageKey[transfer.HashLength:]); err != nil { return err } - if err := transferOutput.realityId.UnmarshalBinary(serializedObject[:realityIdLength]); err != nil { + if err := transferOutput.realityId.UnmarshalBinary(serializedObject[:reality.IdLength]); err != nil { return err } - if balances, err := transferOutput.unmarshalBalances(serializedObject[realityIdLength:]); err != nil { + if balances, err := transferOutput.unmarshalBalances(serializedObject[reality.IdLength:]); err != nil { return err } else { transferOutput.balances = balances } - if consumers, err := transferOutput.unmarshalConsumers(serializedObject[realityIdLength+4+len(transferOutput.balances)*coloredBalanceLength:]); err != nil { + if consumers, err := transferOutput.unmarshalConsumers(serializedObject[reality.IdLength+4+len(transferOutput.balances)*coloredBalanceLength:]); err != nil { return err } else { transferOutput.consumers = consumers @@ -261,19 +265,19 @@ func (transferOutput *TransferOutput) unmarshalBalances(serializedBalances []byt return balances, nil } -func (transferOutput *TransferOutput) unmarshalConsumers(serializedConsumers []byte) (map[TransferHash][]address.Address, error) { +func (transferOutput *TransferOutput) unmarshalConsumers(serializedConsumers []byte) (map[transfer.Hash][]address.Address, error) { offset := 0 consumerCount := int(binary.LittleEndian.Uint32(serializedConsumers[offset:])) offset += 4 - consumers := make(map[TransferHash][]address.Address, consumerCount) + consumers := make(map[transfer.Hash][]address.Address, consumerCount) for i := 0; i < consumerCount; i++ { - transferHash := TransferHash{} + transferHash := transfer.Hash{} if err := transferHash.UnmarshalBinary(serializedConsumers[offset:]); err != nil { return nil, err } - offset += transferHashLength + offset += transfer.HashLength addressHashCount := int(binary.LittleEndian.Uint32(serializedConsumers[offset:])) offset += 4 diff --git a/packages/ledgerstate/transfer_output_booking.go b/packages/ledgerstate/transfer_output_booking.go index ef01387400d2615e8cfc6f8ec5abfafe8f43731d..ae84791e909c93afb4a1a4b8060b2e7defb5debe 100644 --- a/packages/ledgerstate/transfer_output_booking.go +++ b/packages/ledgerstate/transfer_output_booking.go @@ -2,7 +2,9 @@ package ledgerstate import ( "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transfer" "github.com/iotaledger/goshimmer/packages/errors" + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" "github.com/iotaledger/goshimmer/packages/stringify" "github.com/iotaledger/hive.go/objectstorage" ) @@ -12,15 +14,15 @@ import ( type TransferOutputBooking struct { objectstorage.StorableObjectFlags - realityId RealityId + realityId reality.Id addressHash address.Address spent bool - transferHash TransferHash + transferHash transfer.Hash storageKey []byte } -func newTransferOutputBooking(realityId RealityId, addressHash address.Address, spent bool, transferHash TransferHash) (result *TransferOutputBooking) { +func newTransferOutputBooking(realityId reality.Id, addressHash address.Address, spent bool, transferHash transfer.Hash) (result *TransferOutputBooking) { result = &TransferOutputBooking{ realityId: realityId, addressHash: addressHash, @@ -33,7 +35,7 @@ func newTransferOutputBooking(realityId RealityId, addressHash address.Address, return } -func (booking *TransferOutputBooking) GetRealityId() RealityId { +func (booking *TransferOutputBooking) GetRealityId() reality.Id { return booking.realityId } @@ -45,7 +47,7 @@ func (booking *TransferOutputBooking) IsSpent() bool { return booking.spent } -func (booking *TransferOutputBooking) GetTransferHash() TransferHash { +func (booking *TransferOutputBooking) GetTransferHash() transfer.Hash { return booking.transferHash } @@ -114,17 +116,17 @@ func (booking *TransferOutputBooking) UnmarshalBinary(data []byte) error { // region private utility methods ////////////////////////////////////////////////////////////////////////////////////// -func generateTransferOutputBookingStorageKey(realityId RealityId, addressHash address.Address, spent bool, transferHash TransferHash) (storageKey []byte) { - storageKey = make([]byte, realityIdLength+address.Length+1+transferHashLength) +func generateTransferOutputBookingStorageKey(realityId reality.Id, addressHash address.Address, spent bool, transferHash transfer.Hash) (storageKey []byte) { + storageKey = make([]byte, reality.IdLength+address.Length+1+transfer.HashLength) - copy(storageKey[marshalTransferOutputBookingRealityIdStart:marshalTransferOutputBookingRealityIdEnd], realityId[:realityIdLength]) + copy(storageKey[marshalTransferOutputBookingRealityIdStart:marshalTransferOutputBookingRealityIdEnd], realityId[:reality.IdLength]) copy(storageKey[marshalTransferOutputBookingAddressHashStart:marshalTransferOutputBookingAddressHashEnd], addressHash[:address.Length]) if spent { storageKey[marshalTransferOutputBookingSpentStart] = byte(SPENT) } else { storageKey[marshalTransferOutputBookingSpentStart] = byte(UNSPENT) } - copy(storageKey[marshalTransferOutputBookingTransferHashStart:marshalTransferOutputBookingTransferHashEnd], transferHash[:transferHashLength]) + copy(storageKey[marshalTransferOutputBookingTransferHashStart:marshalTransferOutputBookingTransferHashEnd], transferHash[:transfer.HashLength]) return } diff --git a/packages/ledgerstate/transfer_output_reference.go b/packages/ledgerstate/transfer_output_reference.go index c8fdcd697223b88b7529412b02c997890d76acc7..cb8e885c8971415d0ee0b2ac1ead04fd6ca5db96 100644 --- a/packages/ledgerstate/transfer_output_reference.go +++ b/packages/ledgerstate/transfer_output_reference.go @@ -1,17 +1,19 @@ package ledgerstate +/* import ( "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transfer" "github.com/iotaledger/goshimmer/packages/stringify" ) type TransferOutputReference struct { storageKey []byte - transferHash TransferHash + transferHash transfer.Hash addressHash address.Address } -func NewTransferOutputReference(transferHash TransferHash, addressHash address.Address) *TransferOutputReference { +func NewTransferOutputReference(transferHash transfer.Hash, addressHash address.Address) *TransferOutputReference { return &TransferOutputReference{ storageKey: append(transferHash[:], addressHash[:]...), transferHash: transferHash, @@ -29,3 +31,5 @@ func (transferOutputReference *TransferOutputReference) String() string { stringify.StructField("addressHash", transferOutputReference.addressHash), ) } + +*/ diff --git a/packages/ledgerstate/transfer_output_test.go b/packages/ledgerstate/transfer_output_test.go index b733a3ca516762ec452a8b6eb980197f21e154cc..ca872e25e3da9f072f36ad3e475b26e6964de7d0 100644 --- a/packages/ledgerstate/transfer_output_test.go +++ b/packages/ledgerstate/transfer_output_test.go @@ -3,16 +3,20 @@ package ledgerstate import ( "testing" + "github.com/iotaledger/goshimmer/packages/binary/transfer" + + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + "github.com/iotaledger/goshimmer/packages/binary/address" "github.com/magiconair/properties/assert" ) func TestTransferOutput_MarshalUnmarshal(t *testing.T) { - transferOutput := NewTransferOutput(nil, NewRealityId("REALITY"), NewTransferHash("RECEIVE"), address.New([]byte("ADDRESS1")), NewColoredBalance(NewColor("IOTA"), 44), NewColoredBalance(NewColor("BTC"), 88)) - transferOutput.consumers = make(map[TransferHash][]address.Address) + transferOutput := NewTransferOutput(nil, reality.NewId("REALITY"), transfer.NewHash("RECEIVE"), address.New([]byte("ADDRESS1")), NewColoredBalance(NewColor("IOTA"), 44), NewColoredBalance(NewColor("BTC"), 88)) + transferOutput.consumers = make(map[transfer.Hash][]address.Address) - spendTransferHash := NewTransferHash("SPEND") + spendTransferHash := transfer.NewHash("SPEND") transferOutput.consumers[spendTransferHash] = make([]address.Address, 2) transferOutput.consumers[spendTransferHash][0] = address.New([]byte("ADDRESS2")) transferOutput.consumers[spendTransferHash][1] = address.New([]byte("ADDRESS3")) diff --git a/packages/ledgerstate/types.go b/packages/ledgerstate/types.go deleted file mode 100644 index ca03b79ad8052416e491515dc9fc5bacd054c07e..0000000000000000000000000000000000000000 --- a/packages/ledgerstate/types.go +++ /dev/null @@ -1,5 +0,0 @@ -package ledgerstate - -type empty struct{} - -var void empty diff --git a/packages/ledgerstate/visualizer.go b/packages/ledgerstate/visualizer.go index a8f1299dcb38008badf7d2c3ec32730419b50ae4..14e09a925853ee353b67c3cbb19cabc2cd2bea36 100644 --- a/packages/ledgerstate/visualizer.go +++ b/packages/ledgerstate/visualizer.go @@ -3,7 +3,12 @@ package ledgerstate import ( "strings" + "github.com/iotaledger/goshimmer/packages/ledgerstate/reality" + + "github.com/iotaledger/goshimmer/packages/binary/transfer" + "github.com/iotaledger/goshimmer/packages/binary/address" + "github.com/iotaledger/goshimmer/packages/binary/transferoutput" "github.com/iotaledger/goshimmer/packages/graphviz" @@ -11,12 +16,12 @@ import ( "github.com/iotaledger/hive.go/objectstorage" ) -type transferOutputId [transferHashLength + address.Length]byte +type transferOutputId [transfer.HashLength + address.Length]byte type Visualizer struct { ledgerState *LedgerState graph *dot.Graph - realitySubGraphs map[RealityId]*dot.Graph + realitySubGraphs map[reality.Id]*dot.Graph transferOutputNodes map[transferOutputId]dot.Node } @@ -45,7 +50,7 @@ func (visualizer *Visualizer) RenderTransferOutputs(pngFileName string) error { func (visualizer *Visualizer) reset() *Visualizer { visualizer.graph = dot.NewGraph(dot.Directed) - visualizer.realitySubGraphs = make(map[RealityId]*dot.Graph) + visualizer.realitySubGraphs = make(map[reality.Id]*dot.Graph) visualizer.transferOutputNodes = make(map[transferOutputId]dot.Node) return visualizer @@ -62,7 +67,7 @@ func (visualizer *Visualizer) drawTransferOutput(transferOutput *TransferOutput) for transferHash, addresses := range transferOutput.GetConsumers() { for _, addressHash := range addresses { - visualizer.ledgerState.GetTransferOutput(NewTransferOutputReference(transferHash, addressHash)).Consume(func(object objectstorage.StorableObject) { + visualizer.ledgerState.GetTransferOutput(transferoutput.NewTransferOutputReference(transferHash, addressHash)).Consume(func(object objectstorage.StorableObject) { transferOutputNode.Edge(visualizer.drawTransferOutput(object.(*TransferOutput))) }) } @@ -79,7 +84,7 @@ func (visualizer *Visualizer) generateTransferOutputId(transferOutput *TransferO addressHash := transferOutput.GetAddressHash() copy(result[:], transferHash[:]) - copy(result[transferHashLength:], addressHash[:]) + copy(result[transfer.HashLength:], addressHash[:]) return } @@ -93,7 +98,7 @@ func (Visualizer *Visualizer) styleTransferOutputNode(transferOutputNode dot.Nod transferOutputNode.Attr("fillcolor", "white") } -func (visualizer *Visualizer) getRealitySubGraph(realityId RealityId) *dot.Graph { +func (visualizer *Visualizer) getRealitySubGraph(realityId reality.Id) *dot.Graph { realityGraph, exists := visualizer.realitySubGraphs[realityId] if !exists { visualizer.ledgerState.GetReality(realityId).Consume(func(object objectstorage.StorableObject) { @@ -150,7 +155,7 @@ func (visualizer *Visualizer) styleRealitySubGraph(realitySubGraph *dot.Graph, r } } -func (visualizer *Visualizer) generateRealityName(realityId RealityId) (result string) { +func (visualizer *Visualizer) generateRealityName(realityId reality.Id) (result string) { visualizer.ledgerState.GetReality(realityId).Consume(func(object objectstorage.StorableObject) { reality := object.(*Reality)