diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index de3a7232263616767d8cd0e8a18af75eeab55de4..608d4a9ec6ae9753121f63b499fa49157b51d2d9 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -19,7 +19,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest @@ -54,7 +54,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest @@ -88,7 +88,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest @@ -123,7 +123,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest @@ -159,7 +159,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest @@ -195,7 +195,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:latest docker pull gaiadocker/iproute2:latest @@ -229,7 +229,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:latest docker pull gaiadocker/iproute2:latest @@ -263,7 +263,7 @@ jobs: - name: Pull additional Docker images run: | - docker pull angelocapossele/drand:1.1.1 + docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:latest docker pull gaiadocker/iproute2:latest diff --git a/dapps/faucet/packages/payload/payload.go b/dapps/faucet/packages/payload/payload.go index 6e6e0a9659008a420acdfd077f04447a3c0c9a61..a949f043ade356dac8521ab71f974895af4ab9e8 100644 --- a/dapps/faucet/packages/payload/payload.go +++ b/dapps/faucet/packages/payload/payload.go @@ -50,31 +50,22 @@ func New(addr address.Address, powTarget int) (*Payload, error) { } func init() { - payload.RegisterType(Type, ObjectName, GenericPayloadUnmarshalerFactory(Type)) + payload.RegisterType(Type, ObjectName, PayloadUnmarshaler) } // FromBytes parses the marshaled version of a Payload into an object. // It either returns a new Payload or fills an optionally provided Payload with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to FromBytes") - } - +func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) { // initialize helper marshalUtil := marshalutil.New(bytes) // read data - result.payloadType, err = marshalUtil.ReadUint32() - if err != nil { + result = &Payload{} + if _, err = marshalUtil.ReadUint32(); err != nil { return } - if _, err = marshalUtil.ReadUint32(); err != nil { + result.payloadType, err = marshalUtil.ReadUint32() + if err != nil { return } addr, err := marshalUtil.ReadBytes(address.Length) @@ -113,8 +104,8 @@ func (faucetPayload *Payload) Bytes() []byte { marshalUtil := marshalutil.New() // marshal the payload specific information - marshalUtil.WriteUint32(faucetPayload.Type()) marshalUtil.WriteUint32(uint32(address.Length + pow.NonceBytes)) + marshalUtil.WriteUint32(faucetPayload.Type()) marshalUtil.WriteBytes(faucetPayload.address.Bytes()) marshalUtil.WriteUint64(faucetPayload.nonce) @@ -122,13 +113,6 @@ func (faucetPayload *Payload) Bytes() []byte { return marshalUtil.Bytes() } -// Unmarshal unmarshals a given slice of bytes and fills the object. -func (faucetPayload *Payload) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, faucetPayload) - - return -} - // String returns a human readable version of faucet payload (for debug purposes). func (faucetPayload *Payload) String() string { return stringify.Struct("FaucetPayload", @@ -136,16 +120,11 @@ func (faucetPayload *Payload) String() string { ) } -// GenericPayloadUnmarshalerFactory sets the generic unmarshaler. -func GenericPayloadUnmarshalerFactory(payloadType payload.Type) payload.Unmarshaler { - return func(data []byte) (payload payload.Payload, err error) { - payload = &Payload{ - payloadType: payloadType, - } - err = payload.Unmarshal(data) +// PayloadUnmarshaler sets the generic unmarshaler. +func PayloadUnmarshaler(data []byte) (payload payload.Payload, err error) { + payload, _, err = FromBytes(data) - return - } + return } // IsFaucetReq checks if the message is faucet payload. diff --git a/dapps/networkdelay/object.go b/dapps/networkdelay/object.go index 40e45947dddddc662c292e6ec006e59920731f86..99464032fcc1de789379f205f3d1f4e1a1847bf7 100644 --- a/dapps/networkdelay/object.go +++ b/dapps/networkdelay/object.go @@ -41,26 +41,16 @@ func NewObject(id ID, sentTime int64) *Object { // FromBytes parses the marshaled version of an Object into a Go object. // It either returns a new Object or fills an optionally provided Object with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Object) (result *Object, consumedBytes int, err error) { +func FromBytes(bytes []byte) (result *Object, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = Parse(marshalUtil, optionalTargetObject...) + result, err = Parse(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // Parse unmarshals an Object using the given marshalUtil (for easier marshaling/unmarshaling). -func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTarget ...*Object) (result *Object, err error) { - // determine the target that will hold the unmarshaled information - switch len(optionalTarget) { - case 0: - result = &Object{} - case 1: - result = optionalTarget[0] - default: - panic("too many arguments in call to FromBytes") - } - +func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Object, err error) { // read information that are required to identify the object from the outside if _, err = marshalUtil.ReadUint32(); err != nil { return @@ -70,6 +60,7 @@ func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTarget ...*Object) (res } // parse id + result = &Object{} id, err := marshalUtil.ReadBytes(32) if err != nil { return @@ -114,8 +105,8 @@ func (o *Object) Bytes() (bytes []byte) { marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + objectLength) // marshal the payload specific information - marshalUtil.WriteUint32(Type) marshalUtil.WriteUint32(uint32(objectLength)) + marshalUtil.WriteUint32(Type) marshalUtil.WriteBytes(o.id[:]) marshalUtil.WriteInt64(o.sentTime) @@ -142,17 +133,9 @@ func (o *Object) Type() payload.Type { return Type } -// Unmarshal unmarshals the payload from the given bytes. -func (o *Object) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, o) - - return -} - func init() { payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { - payload = &Object{} - err = payload.Unmarshal(data) + payload, _, err = FromBytes(data) return }) diff --git a/dapps/valuetransfers/packages/branchmanager/branch.go b/dapps/valuetransfers/packages/branchmanager/branch.go index 7ccf9b0cc161bb01d44dabd323af3d212a8530de..1fce39bf6944f1e5a581ab6c13499fd277011bc3 100644 --- a/dapps/valuetransfers/packages/branchmanager/branch.go +++ b/dapps/valuetransfers/packages/branchmanager/branch.go @@ -4,6 +4,7 @@ import ( "fmt" "sync" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -43,54 +44,62 @@ func NewBranch(id BranchID, parentBranches []BranchID) *Branch { } } -// BranchFromStorageKey is a factory method that creates a new Branch instance from a storage key of the objectstorage. -// It is used by the objectstorage, to create new instances of this entity. -func BranchFromStorageKey(key []byte, optionalTargetObject ...*Branch) (result *Branch, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Branch{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to BranchFromStorageKey") - } - - // parse information - marshalUtil := marshalutil.New(key) - result.id, err = ParseBranchID(marshalUtil) - if err != nil { - return - } +// BranchFromBytes unmarshals a Branch from a sequence of bytes. +func BranchFromBytes(bytes []byte) (result *Branch, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseBranch(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// BranchFromBytes unmarshals a Branch from a sequence of bytes. -func BranchFromBytes(bytes []byte, optionalTargetObject ...*Branch) (result *Branch, consumedBytes int, err error) { - marshalUtil := marshalutil.New(bytes) - result, err = ParseBranch(marshalUtil, optionalTargetObject...) - consumedBytes = marshalUtil.ReadOffset() +// BranchFromObjectStorage is a factory method that creates a new Branch instance from the ObjectStorage. +func BranchFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + if result, _, err = BranchFromBytes(byteutils.ConcatBytes(key, data)); err != nil { + return + } return } // ParseBranch unmarshals a Branch using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseBranch(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Branch) (result *Branch, err error) { - parsedObject, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return BranchFromStorageKey(data, optionalTargetObject...) - }) +func ParseBranch(marshalUtil *marshalutil.MarshalUtil) (result *Branch, err error) { + result = &Branch{} + + if result.id, err = ParseBranchID(marshalUtil); err != nil { + return + } + result.preferred, err = marshalUtil.ReadBool() if err != nil { return } - - result = parsedObject.(*Branch) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + result.liked, err = marshalUtil.ReadBool() + if err != nil { + return + } + result.finalized, err = marshalUtil.ReadBool() + if err != nil { + return + } + result.confirmed, err = marshalUtil.ReadBool() + if err != nil { + return + } + result.rejected, err = marshalUtil.ReadBool() + if err != nil { + return + } + parentBranchCount, err := marshalUtil.ReadUint32() + if err != nil { return - }) + } + result.parentBranches = make([]BranchID, parentBranchCount) + for i := uint32(0); i < parentBranchCount; i++ { + result.parentBranches[i], err = ParseBranchID(marshalUtil) + if err != nil { + return + } + } return } @@ -403,45 +412,6 @@ func (branch *Branch) ObjectStorageValue() []byte { return marshalUtil.Bytes() } -// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. -func (branch *Branch) UnmarshalObjectStorageValue(valueBytes []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(valueBytes) - branch.preferred, err = marshalUtil.ReadBool() - if err != nil { - return - } - branch.liked, err = marshalUtil.ReadBool() - if err != nil { - return - } - branch.finalized, err = marshalUtil.ReadBool() - if err != nil { - return - } - branch.confirmed, err = marshalUtil.ReadBool() - if err != nil { - return - } - branch.rejected, err = marshalUtil.ReadBool() - if err != nil { - return - } - parentBranchCount, err := marshalUtil.ReadUint32() - if err != nil { - return - } - branch.parentBranches = make([]BranchID, parentBranchCount) - for i := uint32(0); i < parentBranchCount; i++ { - branch.parentBranches[i], err = ParseBranchID(marshalUtil) - if err != nil { - return - } - } - consumedBytes = marshalUtil.ReadOffset() - - return -} - // CachedBranch is a wrapper for the generic CachedObject returned by the objectstorage, that overrides the accessor // methods, with a type-casted one. type CachedBranch struct { diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager.go b/dapps/valuetransfers/packages/branchmanager/branchmanager.go index 3e58994b5abebb8d20cdafe5505dd348e1d8a30f..80cbd55d33a8b5d3eb2dbee0731066845bdc6c34 100644 --- a/dapps/valuetransfers/packages/branchmanager/branchmanager.go +++ b/dapps/valuetransfers/packages/branchmanager/branchmanager.go @@ -43,10 +43,10 @@ func New(store kvstore.KVStore) (branchManager *BranchManager) { osFactory := objectstorage.NewFactory(store, storageprefix.ValueTransfers) branchManager = &BranchManager{ - branchStorage: osFactory.New(osBranch, osBranchFactory, osBranchOptions...), - childBranchStorage: osFactory.New(osChildBranch, osChildBranchFactory, osChildBranchOptions...), - conflictStorage: osFactory.New(osConflict, osConflictFactory, osConflictOptions...), - conflictMemberStorage: osFactory.New(osConflictMember, osConflictMemberFactory, osConflictMemberOptions...), + branchStorage: osFactory.New(osBranch, BranchFromObjectStorage, osBranchOptions...), + childBranchStorage: osFactory.New(osChildBranch, ChildBranchFromObjectStorage, osChildBranchOptions...), + conflictStorage: osFactory.New(osConflict, ConflictFromObjectStorage, osConflictOptions...), + conflictMemberStorage: osFactory.New(osConflictMember, ConflictMemberFromObjectStorage, osConflictMemberOptions...), Events: newEvents(), } branchManager.init() diff --git a/dapps/valuetransfers/packages/branchmanager/child_branch.go b/dapps/valuetransfers/packages/branchmanager/child_branch.go index 10c1bfbf00cd146e93b31a3c7235d905e964d608..4f4d0504947f3717e82aa79be97a90bd3be0240c 100644 --- a/dapps/valuetransfers/packages/branchmanager/child_branch.go +++ b/dapps/valuetransfers/packages/branchmanager/child_branch.go @@ -1,6 +1,7 @@ package branchmanager import ( + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" ) @@ -24,57 +25,34 @@ func NewChildBranch(parentID BranchID, childID BranchID) *ChildBranch { } // ChildBranchFromBytes unmarshals a ChildBranch from a sequence of bytes. -func ChildBranchFromBytes(bytes []byte, optionalTargetObject ...*ChildBranch) (result *ChildBranch, consumedBytes int, err error) { +func ChildBranchFromBytes(bytes []byte) (result *ChildBranch, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseChildBranch(marshalUtil, optionalTargetObject...) + result, err = ParseChildBranch(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// ChildBranchFromStorageKey is a factory method that creates a new ChildBranch instance from a storage key of the +// ChildBranchFromObjectStorage is a factory method that creates a new ChildBranch instance from a storage key of the // objectstorage. It is used by the objectstorage, to create new instances of this entity. -func ChildBranchFromStorageKey(key []byte, optionalTargetObject ...*ChildBranch) (result *ChildBranch, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &ChildBranch{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ChildBranchFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.parentID, err = ParseBranchID(marshalUtil); err != nil { +func ChildBranchFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + if result, _, err = ChildBranchFromBytes(byteutils.ConcatBytes(key, data)); err != nil { return } - if result.childID, err = ParseBranchID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() return } // ParseChildBranch unmarshals a ChildBranch using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseChildBranch(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*ChildBranch) (result *ChildBranch, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return ChildBranchFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseChildBranch(marshalUtil *marshalutil.MarshalUtil) (result *ChildBranch, err error) { + result = &ChildBranch{} + if result.parentID, err = ParseBranchID(marshalUtil); err != nil { return } - - result = parsedObject.(*ChildBranch) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.childID, err = ParseBranchID(marshalUtil); err != nil { return - }) + } return } @@ -89,6 +67,11 @@ func (childBranch *ChildBranch) ChildID() BranchID { return childBranch.childID } +// Bytes returns a marshaled version of this ChildBranch. +func (childBranch *ChildBranch) Bytes() []byte { + return childBranch.ObjectStorageKey() +} + // ObjectStorageKey returns the bytes that are used a key when storing the Branch in an objectstorage. func (childBranch ChildBranch) ObjectStorageKey() []byte { return marshalutil.New(ConflictIDLength + BranchIDLength). @@ -103,12 +86,6 @@ func (childBranch ChildBranch) ObjectStorageValue() []byte { return nil } -// UnmarshalObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a -// marshaled Branch. -func (childBranch ChildBranch) UnmarshalObjectStorageValue([]byte) (consumedBytes int, err error) { - return -} - // Update is disabled but needs to be implemented to be compatible with the objectstorage. func (childBranch ChildBranch) Update(objectstorage.StorableObject) { panic("updates are disabled - use the setters") diff --git a/dapps/valuetransfers/packages/branchmanager/conflict.go b/dapps/valuetransfers/packages/branchmanager/conflict.go index f717aea91778b64868a59141ff562d45765226d0..304c78fcd57df73d49af443488e5146f352e7c5d 100644 --- a/dapps/valuetransfers/packages/branchmanager/conflict.go +++ b/dapps/valuetransfers/packages/branchmanager/conflict.go @@ -3,6 +3,7 @@ package branchmanager import ( "sync" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -26,54 +27,33 @@ func NewConflict(id ConflictID) *Conflict { } // ConflictFromBytes unmarshals a Conflict from a sequence of bytes. -func ConflictFromBytes(bytes []byte, optionalTargetObject ...*Conflict) (result *Conflict, consumedBytes int, err error) { +func ConflictFromBytes(bytes []byte) (result *Conflict, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseConflict(marshalUtil, optionalTargetObject...) + result, err = ParseConflict(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// ConflictFromStorageKey is a factory method that creates a new Conflict instance from a storage key of the -// objectstorage. It is used by the objectstorage, to create new instances of this entity. -func ConflictFromStorageKey(key []byte, optionalTargetObject ...*Conflict) (result *Conflict, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Conflict{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ConflictFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.id, err = ParseConflictID(marshalUtil); err != nil { +// ConflictFromObjectStorage is a factory method that creates a new Conflict instance from the ObjectStorage. +func ConflictFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + if result, _, err = ConflictFromBytes(byteutils.ConcatBytes(key, data)); err != nil { return } - consumedBytes = marshalUtil.ReadOffset() return } // ParseConflict unmarshals a Conflict using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseConflict(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Conflict) (result *Conflict, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return ConflictFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseConflict(marshalUtil *marshalutil.MarshalUtil) (result *Conflict, err error) { + result = &Conflict{} + if result.id, err = ParseConflictID(marshalUtil); err != nil { return } - - result = parsedObject.(*Conflict) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.memberCount, err = marshalUtil.ReadUint32(); err != nil { return - }) + } return } @@ -126,10 +106,7 @@ func (conflict *Conflict) DecreaseMemberCount(optionalDelta ...int) (newMemberCo // Bytes returns a marshaled version of this Conflict. func (conflict *Conflict) Bytes() []byte { - return marshalutil.New(). - WriteBytes(conflict.ObjectStorageKey()). - WriteBytes(conflict.ObjectStorageValue()). - Bytes() + return byteutils.ConcatBytes(conflict.ObjectStorageKey(), conflict.ObjectStorageValue()) } // String returns a human readable version of this Conflict (for debug purposes). @@ -153,18 +130,6 @@ func (conflict *Conflict) ObjectStorageValue() []byte { Bytes() } -// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. -func (conflict *Conflict) UnmarshalObjectStorageValue(valueBytes []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(valueBytes) - conflict.memberCount, err = marshalUtil.ReadUint32() - if err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - - return -} - // Update is disabled but needs to be implemented to be compatible with the objectstorage. func (conflict *Conflict) Update(other objectstorage.StorableObject) { panic("updates are disabled - use the setters") diff --git a/dapps/valuetransfers/packages/branchmanager/conflict_member.go b/dapps/valuetransfers/packages/branchmanager/conflict_member.go index 4d7fb663a03e17d478860a88f7e66a5d0b31e827..9e4e45b03c1b408eaef3d65cade392d52b06785e 100644 --- a/dapps/valuetransfers/packages/branchmanager/conflict_member.go +++ b/dapps/valuetransfers/packages/branchmanager/conflict_member.go @@ -24,57 +24,32 @@ func NewConflictMember(conflictID ConflictID, branchID BranchID) *ConflictMember } // ConflictMemberFromBytes unmarshals a ConflictMember from a sequence of bytes. -func ConflictMemberFromBytes(bytes []byte, optionalTargetObject ...*ConflictMember) (result *ConflictMember, consumedBytes int, err error) { +func ConflictMemberFromBytes(bytes []byte) (result *ConflictMember, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseConflictMember(marshalUtil, optionalTargetObject...) + result, err = ParseConflictMember(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// ConflictMemberFromStorageKey is a factory method that creates a new ConflictMember instance from a storage key of the +// ConflictMemberFromObjectStorage is a factory method that creates a new ConflictMember instance from a storage key of the // objectstorage. It is used by the objectstorage, to create new instances of this entity. -func ConflictMemberFromStorageKey(key []byte, optionalTargetObject ...*ConflictMember) (result *ConflictMember, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &ConflictMember{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ConflictMemberFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.conflictID, err = ParseConflictID(marshalUtil); err != nil { - return - } - if result.branchID, err = ParseBranchID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() +func ConflictMemberFromObjectStorage(key []byte, _ []byte) (result objectstorage.StorableObject, err error) { + result, _, err = ConflictMemberFromBytes(key) return } // ParseConflictMember unmarshals a ConflictMember using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseConflictMember(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*ConflictMember) (result *ConflictMember, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return ConflictMemberFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseConflictMember(marshalUtil *marshalutil.MarshalUtil) (result *ConflictMember, err error) { + result = &ConflictMember{} + if result.conflictID, err = ParseConflictID(marshalUtil); err != nil { return } - - result = parsedObject.(*ConflictMember) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.branchID, err = ParseBranchID(marshalUtil); err != nil { return - }) + } return } @@ -103,12 +78,6 @@ func (conflictMember ConflictMember) ObjectStorageValue() []byte { return nil } -// UnmarshalObjectStorageValue returns the bytes that represent all remaining information (not stored in the key) of a -// marshaled Branch. -func (conflictMember ConflictMember) UnmarshalObjectStorageValue([]byte) (consumedBytes int, err error) { - return -} - // Update is disabled but needs to be implemented to be compatible with the objectstorage. func (conflictMember ConflictMember) Update(other objectstorage.StorableObject) { panic("updates are disabled - use the setters") diff --git a/dapps/valuetransfers/packages/branchmanager/objectstorage.go b/dapps/valuetransfers/packages/branchmanager/objectstorage.go index 21cb4d20fba2c40625f3c2864b38c5c4fdbedcb1..bec990418c29bd272deafe79f5ca45b3b36d557c 100644 --- a/dapps/valuetransfers/packages/branchmanager/objectstorage.go +++ b/dapps/valuetransfers/packages/branchmanager/objectstorage.go @@ -47,19 +47,3 @@ var ( osLeakDetectionOption, } ) - -func osBranchFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return BranchFromStorageKey(key) -} - -func osChildBranchFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return ChildBranchFromStorageKey(key) -} - -func osConflictFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return ConflictFromStorageKey(key) -} - -func osConflictMemberFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return ConflictMemberFromStorageKey(key) -} diff --git a/dapps/valuetransfers/packages/payload/payload.go b/dapps/valuetransfers/packages/payload/payload.go index 118b5b842f2eb28e88c71c8d514a44c0ad12d6c6..4b4c0c0c50d73e49cbd99bd203896b30ac5ce690 100644 --- a/dapps/valuetransfers/packages/payload/payload.go +++ b/dapps/valuetransfers/packages/payload/payload.go @@ -1,6 +1,7 @@ package payload import ( + "fmt" "sync" "github.com/iotaledger/hive.go/marshalutil" @@ -43,58 +44,72 @@ func New(parent1PayloadID, parent2PayloadID ID, valueTransfer *transaction.Trans // FromBytes parses the marshaled version of a Payload into an object. // It either returns a new Payload or fills an optionally provided Payload with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { +func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = Parse(marshalUtil, optionalTargetObject...) + result, err = Parse(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// FromStorageKey is a factory method that creates a new Payload instance from a storage key of the objectstorage. -// It is used by the objectstorage, to create new instances of this entity. -func FromStorageKey(key []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to MissingPayloadFromStorageKey") +// FromObjectStorage is a factory method that creates a new Payload from the ObjectStorage. +func FromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + // parse the message + parsedPayload, err := Parse(marshalutil.New(data)) + if err != nil { + return } - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - payloadID, idErr := ParseID(marshalUtil) - if idErr != nil { - err = idErr - + // parse the ID from they key + payloadID, err := ParseID(marshalutil.New(key)) + if err != nil { return } - result.id = &payloadID - consumedBytes = marshalUtil.ReadOffset() + parsedPayload.id = &payloadID + + // assign result + result = parsedPayload return } // Parse unmarshals a Payload using the given marshalUtil (for easier marshaling/unmarshaling). -func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Payload) (result *Payload, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to Parse") +func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Payload, err error) { + // determine read offset before starting to parse + readOffsetStart := marshalUtil.ReadOffset() + + // read information that are required to identify the payload from the outside + _, err = marshalUtil.ReadUint32() + if err != nil { + return + } + _, err = marshalUtil.ReadUint32() + if err != nil { + return } - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + // parse parent1 payload id + result = &Payload{} + if result.parent1PayloadID, err = ParseID(marshalUtil); err != nil { + return + } + if result.parent2PayloadID, err = ParseID(marshalUtil); err != nil { + return + } + if result.transaction, err = transaction.Parse(marshalUtil); err != nil { + return + } + + // retrieve the number of bytes we processed + readOffsetEnd := marshalUtil.ReadOffset() + + // store marshaled version as a copy + result.bytes, err = marshalUtil.ReadBytes(readOffsetEnd-readOffsetStart, readOffsetStart) + if err != nil { + err = fmt.Errorf("error trying to copy raw source bytes: %w", err) return - }) + } return } @@ -201,8 +216,8 @@ func (payload *Payload) ObjectStorageValue() (bytes []byte) { // marshal fields payloadLength := IDLength + IDLength + len(transferBytes) marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength) - marshalUtil.WriteUint32(Type) marshalUtil.WriteUint32(uint32(payloadLength)) + marshalUtil.WriteUint32(Type) marshalUtil.WriteBytes(payload.parent1PayloadID.Bytes()) marshalUtil.WriteBytes(payload.parent2PayloadID.Bytes()) marshalUtil.WriteBytes(transferBytes) @@ -214,48 +229,6 @@ func (payload *Payload) ObjectStorageValue() (bytes []byte) { return } -// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. -func (payload *Payload) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - - // read information that are required to identify the payload from the outside - _, err = marshalUtil.ReadUint32() - if err != nil { - return - } - _, err = marshalUtil.ReadUint32() - if err != nil { - return - } - - // parse parent1 payload id - if payload.parent1PayloadID, err = ParseID(marshalUtil); err != nil { - return - } - if payload.parent2PayloadID, err = ParseID(marshalUtil); err != nil { - return - } - if payload.transaction, err = transaction.Parse(marshalUtil); err != nil { - return - } - - // return the number of bytes we processed - consumedBytes = marshalUtil.ReadOffset() - - // store bytes, so we don't have to marshal manually - payload.bytes = make([]byte, consumedBytes) - copy(payload.bytes, data[:consumedBytes]) - - return -} - -// Unmarshal unmarshals a given slice of bytes and fills the object with the. -func (payload *Payload) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, payload) - - return -} - func init() { payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { payload, _, err = FromBytes(data) diff --git a/dapps/valuetransfers/packages/tangle/attachment.go b/dapps/valuetransfers/packages/tangle/attachment.go index e7b41335b57948f0f9eb57bd1585d4831e1a1f69..7fa2b81a3c6828541262984077fb6064e0816366 100644 --- a/dapps/valuetransfers/packages/tangle/attachment.go +++ b/dapps/valuetransfers/packages/tangle/attachment.go @@ -3,6 +3,7 @@ package tangle import ( "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -15,8 +16,6 @@ type Attachment struct { transactionID transaction.ID payloadID payload.ID - - storageKey []byte } // NewAttachment creates an attachment object with the given information. @@ -24,68 +23,36 @@ func NewAttachment(transactionID transaction.ID, payloadID payload.ID) *Attachme return &Attachment{ transactionID: transactionID, payloadID: payloadID, - - storageKey: marshalutil.New(AttachmentLength). - WriteBytes(transactionID.Bytes()). - WriteBytes(payloadID.Bytes()). - Bytes(), } } // AttachmentFromBytes unmarshals an Attachment from a sequence of bytes - it either creates a new object or fills the // optionally provided one with the parsed information. -func AttachmentFromBytes(bytes []byte, optionalTargetObject ...*Attachment) (result *Attachment, consumedBytes int, err error) { +func AttachmentFromBytes(bytes []byte) (result *Attachment, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseAttachment(marshalUtil, optionalTargetObject...) + result, err = ParseAttachment(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseAttachment is a wrapper for simplified unmarshaling of Attachments from a byte stream using the marshalUtil package. -func ParseAttachment(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Attachment) (result *Attachment, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return AttachmentFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr - +func ParseAttachment(marshalUtil *marshalutil.MarshalUtil) (result *Attachment, err error) { + result = &Attachment{} + if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { return } - - result = parsedObject.(*Attachment) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { return - }) + } return } -// AttachmentFromStorageKey gets called when we restore an Attachment from the storage - it parses the key bytes and +// AttachmentFromObjectStorage gets called when we restore an Attachment from the storage - it parses the key bytes and // returns the new object. -func AttachmentFromStorageKey(key []byte, optionalTargetObject ...*Attachment) (result *Attachment, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Attachment{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to AttachmentFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { - return - } - if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) +func AttachmentFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = AttachmentFromBytes(byteutils.ConcatBytes(key, data)) return } @@ -115,7 +82,7 @@ func (attachment *Attachment) String() string { // ObjectStorageKey returns the key that is used to store the object in the database. func (attachment *Attachment) ObjectStorageKey() []byte { - return attachment.storageKey + return byteutils.ConcatBytes(attachment.transactionID.Bytes(), attachment.payloadID.Bytes()) } // ObjectStorageValue marshals the "content part" of an Attachment to a sequence of bytes. Since all of the information @@ -124,12 +91,6 @@ func (attachment *Attachment) ObjectStorageValue() (data []byte) { return } -// UnmarshalObjectStorageValue unmarshals the "content part" of an Attachment from a sequence of bytes. Since all of the information -// for this object are stored in its key, this method does nothing and is only required to conform with the interface. -func (attachment *Attachment) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - return -} - // Update is disabled - updates are supposed to happen through the setters (if existing). func (attachment *Attachment) Update(other objectstorage.StorableObject) { panic("update forbidden") diff --git a/dapps/valuetransfers/packages/tangle/consumer.go b/dapps/valuetransfers/packages/tangle/consumer.go index 1fdcacb63ae9f3bc7cef6438973bb7e3adf83f79..2afc4099fd18d17aae4dd2fedab6b7b78911828a 100644 --- a/dapps/valuetransfers/packages/tangle/consumer.go +++ b/dapps/valuetransfers/packages/tangle/consumer.go @@ -3,6 +3,7 @@ package tangle import ( "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -18,8 +19,6 @@ type Consumer struct { consumedInput transaction.OutputID transactionID transaction.ID - - storageKey []byte } // NewConsumer creates a Consumer object with the given information. @@ -27,68 +26,37 @@ func NewConsumer(consumedInput transaction.OutputID, transactionID transaction.I return &Consumer{ consumedInput: consumedInput, transactionID: transactionID, - - storageKey: marshalutil.New(ConsumerLength). - WriteBytes(consumedInput.Bytes()). - WriteBytes(transactionID.Bytes()). - Bytes(), } } // ConsumerFromBytes unmarshals a Consumer from a sequence of bytes - it either creates a new object or fills the // optionally provided one with the parsed information. -func ConsumerFromBytes(bytes []byte, optionalTargetObject ...*Consumer) (result *Consumer, consumedBytes int, err error) { +func ConsumerFromBytes(bytes []byte) (result *Consumer, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseConsumer(marshalUtil, optionalTargetObject...) + result, err = ParseConsumer(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseConsumer unmarshals a Consumer using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseConsumer(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Consumer) (result *Consumer, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return ConsumerFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseConsumer(marshalUtil *marshalutil.MarshalUtil) (result *Consumer, err error) { + result = &Consumer{} + if result.consumedInput, err = transaction.ParseOutputID(marshalUtil); err != nil { return } - - result = parsedObject.(*Consumer) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { return - }) + } return } -// ConsumerFromStorageKey is a factory method that creates a new Consumer instance from a storage key of the +// ConsumerFromObjectStorage is a factory method that creates a new Consumer instance from a storage key of the // objectstorage. It is used by the objectstorage, to create new instances of this entity. -func ConsumerFromStorageKey(key []byte, optionalTargetObject ...*Consumer) (result *Consumer, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Consumer{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ConsumerFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.consumedInput, err = transaction.ParseOutputID(marshalUtil); err != nil { - return - } - if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) +func ConsumerFromObjectStorage(key []byte, _ []byte) (result objectstorage.StorableObject, err error) { + result, _, err = ConsumerFromBytes(key) return } @@ -118,7 +86,7 @@ func (consumer *Consumer) String() string { // ObjectStorageKey returns the key that is used to store the object in the database. func (consumer *Consumer) ObjectStorageKey() []byte { - return consumer.storageKey + return byteutils.ConcatBytes(consumer.consumedInput.Bytes(), consumer.transactionID.Bytes()) } // ObjectStorageValue marshals the "content part" of an Consumer to a sequence of bytes. Since all of the information for @@ -127,12 +95,6 @@ func (consumer *Consumer) ObjectStorageValue() (data []byte) { return } -// UnmarshalObjectStorageValue unmarshals the "content part" of a Consumer from a sequence of bytes. Since all of the information -// for this object are stored in its key, this method does nothing and is only required to conform with the interface. -func (consumer *Consumer) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - return -} - // Update is disabled - updates are supposed to happen through the setters (if existing). func (consumer *Consumer) Update(other objectstorage.StorableObject) { panic("update forbidden") diff --git a/dapps/valuetransfers/packages/tangle/missingpayload.go b/dapps/valuetransfers/packages/tangle/missingpayload.go index ebad334e58f6a8c47183ff3d069ed2b3518afa18..075b88b1a0dd693dea2376f70a8590c0f96ac842 100644 --- a/dapps/valuetransfers/packages/tangle/missingpayload.go +++ b/dapps/valuetransfers/packages/tangle/missingpayload.go @@ -4,6 +4,7 @@ import ( "time" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" ) @@ -27,54 +28,32 @@ func NewMissingPayload(payloadID payload.ID) *MissingPayload { // MissingPayloadFromBytes unmarshals an entry for a missing value transfer payload from a sequence of bytes. // It either creates a new entry or fills the optionally provided one with the parsed information. -func MissingPayloadFromBytes(bytes []byte, optionalTargetObject ...*MissingPayload) (result *MissingPayload, consumedBytes int, err error) { +func MissingPayloadFromBytes(bytes []byte) (result *MissingPayload, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseMissingPayload(marshalUtil, optionalTargetObject...) + result, err = ParseMissingPayload(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseMissingPayload unmarshals a MissingPayload using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseMissingPayload(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*MissingPayload) (result *MissingPayload, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return MissingPayloadFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseMissingPayload(marshalUtil *marshalutil.MarshalUtil) (result *MissingPayload, err error) { + result = &MissingPayload{} + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { return } - - result = parsedObject.(*MissingPayload) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.missingSince, err = marshalUtil.ReadTime(); err != nil { return - }) + } return } -// MissingPayloadFromStorageKey gets called when we restore an entry for a missing value transfer payload from the storage. The bytes and +// MissingPayloadFromObjectStorage gets called when we restore an entry for a missing value transfer payload from the storage. The bytes and // the content will be unmarshaled by an external caller using the binary.ObjectStorageValue interface. -func MissingPayloadFromStorageKey(key []byte, optionalTargetObject ...*MissingPayload) (result *MissingPayload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &MissingPayload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to MissingPayloadFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() +func MissingPayloadFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = MissingPayloadFromBytes(byteutils.ConcatBytes(key, data)) return } @@ -91,10 +70,7 @@ func (missingPayload *MissingPayload) MissingSince() time.Time { // Bytes marshals the missing payload into a sequence of bytes. func (missingPayload *MissingPayload) Bytes() []byte { - return marshalutil.New(payload.IDLength + marshalutil.TIME_SIZE). - WriteBytes(missingPayload.ObjectStorageKey()). - WriteBytes(missingPayload.ObjectStorageValue()). - Bytes() + return byteutils.ConcatBytes(missingPayload.ObjectStorageKey(), missingPayload.ObjectStorageValue()) } // Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. @@ -116,16 +92,5 @@ func (missingPayload *MissingPayload) ObjectStorageValue() (data []byte) { Bytes() } -// UnmarshalObjectStorageValue is required to match the encoding.BinaryUnmarshaler interface. -func (missingPayload *MissingPayload) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - if missingPayload.missingSince, err = marshalUtil.ReadTime(); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - - return -} - // Interface contract: make compiler warn if the interface is not implemented correctly. var _ objectstorage.StorableObject = &MissingPayload{} diff --git a/dapps/valuetransfers/packages/tangle/objectstorage.go b/dapps/valuetransfers/packages/tangle/objectstorage.go index 593d041c9831e6a58e6810c7530905b2523c2cdb..294a24d5741b4a1a8a1fd0ca427c2c5e551f13fb 100644 --- a/dapps/valuetransfers/packages/tangle/objectstorage.go +++ b/dapps/valuetransfers/packages/tangle/objectstorage.go @@ -3,8 +3,6 @@ package tangle import ( "time" - "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" - "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" "github.com/iotaledger/hive.go/objectstorage" ) @@ -32,39 +30,3 @@ var ( MaxConsumerHoldTime: 10 * time.Second, }) ) - -func osPayloadFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return payload.FromStorageKey(key) -} - -func osPayloadMetadataFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return PayloadMetadataFromStorageKey(key) -} - -func osMissingPayloadFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return MissingPayloadFromStorageKey(key) -} - -func osPayloadApproverFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return PayloadApproverFromStorageKey(key) -} - -func osTransactionFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return transaction.FromStorageKey(key) -} - -func osTransactionMetadataFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return TransactionMetadataFromStorageKey(key) -} - -func osAttachmentFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return AttachmentFromStorageKey(key) -} - -func osOutputFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return OutputFromStorageKey(key) -} - -func osConsumerFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return ConsumerFromStorageKey(key) -} diff --git a/dapps/valuetransfers/packages/tangle/output.go b/dapps/valuetransfers/packages/tangle/output.go index 4421454ee8b13ef90b3c5302f16121c7e45ec146..dd1f4c4b3cdff90efc619c0c49ef01fd2952ec2d 100644 --- a/dapps/valuetransfers/packages/tangle/output.go +++ b/dapps/valuetransfers/packages/tangle/output.go @@ -8,6 +8,7 @@ import ( "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -43,7 +44,6 @@ type Output struct { rejectedMutex sync.RWMutex objectstorage.StorableObjectFlags - storageKey []byte } // NewOutput creates an Output that contains the balances and identifiers of a Transaction. @@ -55,68 +55,81 @@ func NewOutput(address address.Address, transactionID transaction.ID, branchID b solid: false, solidificationTime: time.Time{}, balances: balances, - - storageKey: marshalutil.New().WriteBytes(address.Bytes()).WriteBytes(transactionID.Bytes()).Bytes(), } } // OutputFromBytes unmarshals an Output object from a sequence of bytes. // It either creates a new object or fills the optionally provided object with the parsed information. -func OutputFromBytes(bytes []byte, optionalTargetObject ...*Output) (result *Output, consumedBytes int, err error) { +func OutputFromBytes(bytes []byte) (result *Output, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseOutput(marshalUtil, optionalTargetObject...) + result, err = ParseOutput(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseOutput unmarshals an Output using the given marshalUtil (for easier marshaling/unmarshaling). -func ParseOutput(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Output) (result *Output, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return OutputFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseOutput(marshalUtil *marshalutil.MarshalUtil) (result *Output, err error) { + result = &Output{} + if result.address, err = address.Parse(marshalUtil); err != nil { return } - - result = parsedObject.(*Output) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.transactionID, err = transaction.ParseID(marshalUtil); err != nil { return - }) - - return -} - -// OutputFromStorageKey get's called when we restore a Output from the storage. -// In contrast to other database models, it unmarshals some information from the key so we simply store the key before -// it gets handed over to UnmarshalObjectStorageValue (by the ObjectStorage). -func OutputFromStorageKey(keyBytes []byte, optionalTargetObject ...*Output) (result *Output, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Output{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to OutputFromStorageKey") - } - - // parse information - marshalUtil := marshalutil.New(keyBytes) - result.address, err = address.Parse(marshalUtil) + } + if result.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { + return + } + if result.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.firstConsumer, err = transaction.ParseID(marshalUtil); err != nil { + return + } + consumerCount, err := marshalUtil.ReadUint32() if err != nil { return } - result.transactionID, err = transaction.ParseID(marshalUtil) + if result.preferred, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.finalized, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } + result.consumerCount = int(consumerCount) + balanceCount, err := marshalUtil.ReadUint32() if err != nil { return } - result.storageKey = marshalutil.New(keyBytes[:transaction.OutputIDLength]).Bytes(true) - consumedBytes = marshalUtil.ReadOffset() + result.balances = make([]*balance.Balance, balanceCount) + for i := uint32(0); i < balanceCount; i++ { + result.balances[i], err = balance.Parse(marshalUtil) + if err != nil { + return + } + } + + return +} + +// OutputFromObjectStorage get's called when we restore a Output from the storage. +// In contrast to other database models, it unmarshals some information from the key so we simply store the key before +// it gets handed over to UnmarshalObjectStorageValue (by the ObjectStorage). +func OutputFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = OutputFromBytes(byteutils.ConcatBytes(key, data)) return } @@ -407,19 +420,13 @@ func (output *Output) Balances() []*balance.Balance { // Bytes marshals the object into a sequence of bytes. func (output *Output) Bytes() []byte { - return marshalutil.New(). - WriteBytes(output.ObjectStorageKey()). - WriteBytes(output.ObjectStorageValue()). - Bytes() + return byteutils.ConcatBytes(output.ObjectStorageKey(), output.ObjectStorageValue()) } // ObjectStorageKey returns the key that is used to store the object in the database. // It is required to match StorableObject interface. func (output *Output) ObjectStorageKey() []byte { - return marshalutil.New(transaction.OutputIDLength). - WriteBytes(output.address.Bytes()). - WriteBytes(output.transactionID.Bytes()). - Bytes() + return byteutils.ConcatBytes(output.address.Bytes(), output.transactionID.Bytes()) } // ObjectStorageValue marshals the balances into a sequence of bytes - the address and transaction id are stored inside the key @@ -449,58 +456,6 @@ func (output *Output) ObjectStorageValue() []byte { return marshalUtil.Bytes() } -// UnmarshalObjectStorageValue restores a Output from a serialized version in the ObjectStorage with parts of the object -// being stored in its key rather than the content of the database to reduce storage requirements. -func (output *Output) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - if output.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { - return - } - if output.solid, err = marshalUtil.ReadBool(); err != nil { - return - } - if output.solidificationTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if output.firstConsumer, err = transaction.ParseID(marshalUtil); err != nil { - return - } - consumerCount, err := marshalUtil.ReadUint32() - if err != nil { - return - } - if output.preferred, err = marshalUtil.ReadBool(); err != nil { - return - } - if output.finalized, err = marshalUtil.ReadBool(); err != nil { - return - } - if output.liked, err = marshalUtil.ReadBool(); err != nil { - return - } - if output.confirmed, err = marshalUtil.ReadBool(); err != nil { - return - } - if output.rejected, err = marshalUtil.ReadBool(); err != nil { - return - } - output.consumerCount = int(consumerCount) - balanceCount, err := marshalUtil.ReadUint32() - if err != nil { - return - } - output.balances = make([]*balance.Balance, balanceCount) - for i := uint32(0); i < balanceCount; i++ { - output.balances[i], err = balance.Parse(marshalUtil) - if err != nil { - return - } - } - consumedBytes = marshalUtil.ReadOffset() - - return -} - // Update is disabled and panics if it ever gets called - it is required to match StorableObject interface. func (output *Output) Update(other objectstorage.StorableObject) { panic("this object should never be updated") diff --git a/dapps/valuetransfers/packages/tangle/payloadapprover.go b/dapps/valuetransfers/packages/tangle/payloadapprover.go index 7646395d36d3fe3231ec8159e9ecb0257a39e248..e5f0973a82b0c03fa78551d24d0f418a2c0596d1 100644 --- a/dapps/valuetransfers/packages/tangle/payloadapprover.go +++ b/dapps/valuetransfers/packages/tangle/payloadapprover.go @@ -2,6 +2,7 @@ package tangle import ( "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" ) @@ -12,78 +13,45 @@ import ( type PayloadApprover struct { objectstorage.StorableObjectFlags - storageKey []byte referencedPayloadID payload.ID approvingPayloadID payload.ID } // NewPayloadApprover creates an approver object that encodes a single relation between an approved and an approving payload. func NewPayloadApprover(referencedPayload payload.ID, approvingPayload payload.ID) *PayloadApprover { - marshalUtil := marshalutil.New(payload.IDLength + payload.IDLength) - marshalUtil.WriteBytes(referencedPayload.Bytes()) - marshalUtil.WriteBytes(approvingPayload.Bytes()) - return &PayloadApprover{ referencedPayloadID: referencedPayload, approvingPayloadID: approvingPayload, - storageKey: marshalUtil.Bytes(), } } // PayloadApproverFromBytes unmarshals a PayloadApprover from a sequence of bytes. -func PayloadApproverFromBytes(bytes []byte, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, consumedBytes int, err error) { +func PayloadApproverFromBytes(bytes []byte) (result *PayloadApprover, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParsePayloadApprover(marshalUtil, optionalTargetObject...) + result, err = ParsePayloadApprover(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParsePayloadApprover unmarshals a PayloadApprover using the given marshalUtil (for easier marshaling/unmarshaling). -func ParsePayloadApprover(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return PayloadApproverFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr - +func ParsePayloadApprover(marshalUtil *marshalutil.MarshalUtil) (result *PayloadApprover, err error) { + result = &PayloadApprover{} + if result.referencedPayloadID, err = payload.ParseID(marshalUtil); err != nil { return } - - result = parsedObject.(*PayloadApprover) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.approvingPayloadID, err = payload.ParseID(marshalUtil); err != nil { return - }) + } return } -// PayloadApproverFromStorageKey get's called when we restore transaction metadata from the storage. +// PayloadApproverFromObjectStorage get's called when we restore transaction metadata from the storage. // In contrast to other database models, it unmarshals the information from the key and does not use the UnmarshalObjectStorageValue // method. -func PayloadApproverFromStorageKey(key []byte, optionalTargetObject ...*PayloadApprover) (result *PayloadApprover, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &PayloadApprover{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to PayloadApproverFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.referencedPayloadID, err = payload.ParseID(marshalUtil); err != nil { - return - } - if result.approvingPayloadID, err = payload.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - result.storageKey = marshalutil.New(key[:consumedBytes]).Bytes(true) +func PayloadApproverFromObjectStorage(key []byte, _ []byte) (result objectstorage.StorableObject, err error) { + result, _, err = PayloadMetadataFromBytes(key) return } @@ -96,7 +64,7 @@ func (payloadApprover *PayloadApprover) ApprovingPayloadID() payload.ID { // ObjectStorageKey returns the key that is used to store the object in the database. // It is required to match StorableObject interface. func (payloadApprover *PayloadApprover) ObjectStorageKey() []byte { - return payloadApprover.storageKey + return byteutils.ConcatBytes(payloadApprover.referencedPayloadID.Bytes(), payloadApprover.approvingPayloadID.Bytes()) } // ObjectStorageValue is implemented to conform with the StorableObject interface, but it does not really do anything, @@ -105,12 +73,6 @@ func (payloadApprover *PayloadApprover) ObjectStorageValue() (data []byte) { return } -// UnmarshalObjectStorageValue is implemented to conform with the StorableObject interface, but it does not really do -// anything, since all of the information about an approver are stored in the "key". -func (payloadApprover *PayloadApprover) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - return -} - // Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters. // It is required to match StorableObject interface. func (payloadApprover *PayloadApprover) Update(other objectstorage.StorableObject) { diff --git a/dapps/valuetransfers/packages/tangle/payloadmetadata.go b/dapps/valuetransfers/packages/tangle/payloadmetadata.go index be575207930db9ff5107719e43e1c623400dace3..dc7b1fb86366b3f8b034c0e6a710f9f7a0c90f2e 100644 --- a/dapps/valuetransfers/packages/tangle/payloadmetadata.go +++ b/dapps/valuetransfers/packages/tangle/payloadmetadata.go @@ -4,6 +4,7 @@ import ( "sync" "time" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -42,54 +43,46 @@ func NewPayloadMetadata(payloadID payload.ID) *PayloadMetadata { // PayloadMetadataFromBytes unmarshals a container with the metadata of a value transfer payload from a sequence of bytes. // It either creates a new container or fills the optionally provided container with the parsed information. -func PayloadMetadataFromBytes(bytes []byte, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, consumedBytes int, err error) { +func PayloadMetadataFromBytes(bytes []byte) (result *PayloadMetadata, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParsePayloadMetadata(marshalUtil, optionalTargetObject...) + result, err = ParsePayloadMetadata(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParsePayloadMetadata is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package. -func ParsePayloadMetadata(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return PayloadMetadataFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr - +func ParsePayloadMetadata(marshalUtil *marshalutil.MarshalUtil) (result *PayloadMetadata, err error) { + result = &PayloadMetadata{} + if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { return } - - result = parsedObject.(*PayloadMetadata) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.solidificationTime, err = marshalUtil.ReadTime(); err != nil { return - }) + } + if result.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { + return + } return } -// PayloadMetadataFromStorageKey gets called when we restore transaction metadata from the storage. The bytes and the content will be +// PayloadMetadataFromObjectStorage gets called when we restore transaction metadata from the storage. The bytes and the content will be // unmarshaled by an external caller using the binary.ObjectStorageValue interface. -func PayloadMetadataFromStorageKey(id []byte, optionalTargetObject ...*PayloadMetadata) (result *PayloadMetadata, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &PayloadMetadata{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to PayloadMetadataFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(id) - if result.payloadID, err = payload.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() +func PayloadMetadataFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = PayloadMetadataFromBytes(byteutils.ConcatBytes(key, data)) return } @@ -275,10 +268,7 @@ func (payloadMetadata *PayloadMetadata) setBranchID(branchID branchmanager.Branc // Bytes marshals the metadata into a sequence of bytes. func (payloadMetadata *PayloadMetadata) Bytes() []byte { - return marshalutil.New(payload.IDLength + marshalutil.TIME_SIZE + 2*marshalutil.BOOL_SIZE + branchmanager.BranchIDLength). - WriteBytes(payloadMetadata.ObjectStorageKey()). - WriteBytes(payloadMetadata.ObjectStorageValue()). - Bytes() + return byteutils.ConcatBytes(payloadMetadata.ObjectStorageKey(), payloadMetadata.ObjectStorageValue()) } // String creates a human readable version of the metadata (for debug purposes). @@ -314,32 +304,6 @@ func (payloadMetadata *PayloadMetadata) ObjectStorageValue() []byte { Bytes() } -// UnmarshalObjectStorageValue is required to match the encoding.BinaryUnmarshaler interface. -func (payloadMetadata *PayloadMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - if payloadMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if payloadMetadata.solid, err = marshalUtil.ReadBool(); err != nil { - return - } - if payloadMetadata.liked, err = marshalUtil.ReadBool(); err != nil { - return - } - if payloadMetadata.confirmed, err = marshalUtil.ReadBool(); err != nil { - return - } - if payloadMetadata.rejected, err = marshalUtil.ReadBool(); err != nil { - return - } - if payloadMetadata.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - - return -} - // CachedPayloadMetadata is a wrapper for the object storage, that takes care of type casting the managed objects. // Since go does not have generics (yet), the object storage works based on the generic "interface{}" type, which means // that we have to regularly type cast the returned objects, to match the expected type. To reduce the burden of diff --git a/dapps/valuetransfers/packages/tangle/signature_filter_test.go b/dapps/valuetransfers/packages/tangle/signature_filter_test.go index e664d062b3893bcb3f9d3d101a3f087e31564111..c8640ad5d295d75bafde03f6c1f88f4c2f5a94c3 100644 --- a/dapps/valuetransfers/packages/tangle/signature_filter_test.go +++ b/dapps/valuetransfers/packages/tangle/signature_filter_test.go @@ -87,7 +87,7 @@ func TestSignatureFilter(t *testing.T) { marshalUtil := marshalutil.New(messagePayload.NewData([]byte("test")).Bytes()) // set the type to be a value payload - marshalUtil.WriteSeek(0) + marshalUtil.WriteSeek(4) marshalUtil.WriteUint32(valuePayload.Type) // parse modified bytes back into a payload object diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go index 52007a6be3c999ba580975a34c28a58c95bd2be9..c9d79d8e79fedf3f2c4f31072552cae741740be5 100644 --- a/dapps/valuetransfers/packages/tangle/tangle.go +++ b/dapps/valuetransfers/packages/tangle/tangle.go @@ -48,15 +48,15 @@ func New(store kvstore.KVStore) (tangle *Tangle) { tangle = &Tangle{ branchManager: branchmanager.New(store), - payloadStorage: osFactory.New(osPayload, osPayloadFactory, objectstorage.CacheTime(cacheTime)), - payloadMetadataStorage: osFactory.New(osPayloadMetadata, osPayloadMetadataFactory, objectstorage.CacheTime(cacheTime)), - missingPayloadStorage: osFactory.New(osMissingPayload, osMissingPayloadFactory, objectstorage.CacheTime(cacheTime)), - approverStorage: osFactory.New(osApprover, osPayloadApproverFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(payload.IDLength, payload.IDLength), objectstorage.KeysOnly(true)), - transactionStorage: osFactory.New(osTransaction, osTransactionFactory, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), - transactionMetadataStorage: osFactory.New(osTransactionMetadata, osTransactionMetadataFactory, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), - attachmentStorage: osFactory.New(osAttachment, osAttachmentFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(transaction.IDLength, payload.IDLength), osLeakDetectionOption), - outputStorage: osFactory.New(osOutput, osOutputFactory, OutputKeyPartitions, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), - consumerStorage: osFactory.New(osConsumer, osConsumerFactory, ConsumerPartitionKeys, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + payloadStorage: osFactory.New(osPayload, payload.FromObjectStorage, objectstorage.CacheTime(cacheTime)), + payloadMetadataStorage: osFactory.New(osPayloadMetadata, PayloadMetadataFromObjectStorage, objectstorage.CacheTime(cacheTime)), + missingPayloadStorage: osFactory.New(osMissingPayload, MissingPayloadFromObjectStorage, objectstorage.CacheTime(cacheTime)), + approverStorage: osFactory.New(osApprover, PayloadApproverFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(payload.IDLength, payload.IDLength), objectstorage.KeysOnly(true)), + transactionStorage: osFactory.New(osTransaction, transaction.FromObjectStorage, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + transactionMetadataStorage: osFactory.New(osTransactionMetadata, TransactionMetadataFromObjectStorage, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + attachmentStorage: osFactory.New(osAttachment, AttachmentFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(transaction.IDLength, payload.IDLength), osLeakDetectionOption), + outputStorage: osFactory.New(osOutput, OutputFromObjectStorage, OutputKeyPartitions, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), + consumerStorage: osFactory.New(osConsumer, ConsumerFromObjectStorage, ConsumerPartitionKeys, objectstorage.CacheTime(cacheTime), osLeakDetectionOption), Events: newEvents(), } diff --git a/dapps/valuetransfers/packages/tangle/transactionmetadata.go b/dapps/valuetransfers/packages/tangle/transactionmetadata.go index 753e70593a2e141c092ff2553a31e340d386c3ee..f3e966bbb3e03a377c52dee586350023045ef2ed 100644 --- a/dapps/valuetransfers/packages/tangle/transactionmetadata.go +++ b/dapps/valuetransfers/packages/tangle/transactionmetadata.go @@ -6,6 +6,7 @@ import ( "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager" "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/stringify" @@ -46,56 +47,57 @@ func NewTransactionMetadata(id transaction.ID) *TransactionMetadata { // TransactionMetadataFromBytes unmarshals a TransactionMetadata object from a sequence of bytes. // It either creates a new object or fills the optionally provided object with the parsed information. -func TransactionMetadataFromBytes(bytes []byte, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, consumedBytes int, err error) { +func TransactionMetadataFromBytes(bytes []byte) (result *TransactionMetadata, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseTransactionMetadata(marshalUtil, optionalTargetObject...) + result, err = ParseTransactionMetadata(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// TransactionMetadataFromStorageKey get's called when we restore TransactionMetadata from the storage. +// TransactionMetadataFromObjectStorage get's called when we restore TransactionMetadata from the storage. // In contrast to other database models, it unmarshals some information from the key so we simply store the key before // it gets handed over to UnmarshalObjectStorageValue (by the ObjectStorage). -func TransactionMetadataFromStorageKey(keyBytes []byte, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &TransactionMetadata{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to TransactionMetadataFromStorageKey") - } - - // parse information - marshalUtil := marshalutil.New(keyBytes) - result.id, err = transaction.ParseID(marshalUtil) - if err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() +func TransactionMetadataFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = TransactionMetadataFromBytes(byteutils.ConcatBytes(key, data)) return } // ParseTransactionMetadata is a wrapper for simplified unmarshaling of TransactionMetadata objects from a byte stream using the marshalUtil package. -func ParseTransactionMetadata(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*TransactionMetadata) (result *TransactionMetadata, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return TransactionMetadataFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseTransactionMetadata(marshalUtil *marshalutil.MarshalUtil) (result *TransactionMetadata, err error) { + result = &TransactionMetadata{} + if result.id, err = transaction.ParseID(marshalUtil); err != nil { return } - - result = parsedObject.(*TransactionMetadata) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { return - }) + } + if result.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.finalizationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.solid, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.preferred, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.finalized, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.liked, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.confirmed, err = marshalUtil.ReadBool(); err != nil { + return + } + if result.rejected, err = marshalUtil.ReadBool(); err != nil { + return + } return } @@ -364,17 +366,7 @@ func (transactionMetadata *TransactionMetadata) SolidificationTime() time.Time { // Bytes marshals the TransactionMetadata object into a sequence of bytes. func (transactionMetadata *TransactionMetadata) Bytes() []byte { - return marshalutil.New(branchmanager.BranchIDLength + 2*marshalutil.TIME_SIZE + 6*marshalutil.BOOL_SIZE). - WriteBytes(transactionMetadata.BranchID().Bytes()). - WriteTime(transactionMetadata.SolidificationTime()). - WriteTime(transactionMetadata.FinalizationTime()). - WriteBool(transactionMetadata.Solid()). - WriteBool(transactionMetadata.Preferred()). - WriteBool(transactionMetadata.Finalized()). - WriteBool(transactionMetadata.Liked()). - WriteBool(transactionMetadata.Confirmed()). - WriteBool(transactionMetadata.Rejected()). - Bytes() + return byteutils.ConcatBytes(transactionMetadata.ObjectStorageKey(), transactionMetadata.ObjectStorageValue()) } // String creates a human readable version of the metadata (for debug purposes). @@ -400,43 +392,17 @@ func (transactionMetadata *TransactionMetadata) Update(other objectstorage.Stora // ObjectStorageValue marshals the TransactionMetadata object into a sequence of bytes and matches the encoding.BinaryMarshaler // interface. func (transactionMetadata *TransactionMetadata) ObjectStorageValue() []byte { - return transactionMetadata.Bytes() -} - -// UnmarshalObjectStorageValue restores the values of a TransactionMetadata object from a sequence of bytes and matches the -// encoding.BinaryUnmarshaler interface. -func (transactionMetadata *TransactionMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - if transactionMetadata.branchID, err = branchmanager.ParseBranchID(marshalUtil); err != nil { - return - } - if transactionMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if transactionMetadata.finalizationTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if transactionMetadata.solid, err = marshalUtil.ReadBool(); err != nil { - return - } - if transactionMetadata.preferred, err = marshalUtil.ReadBool(); err != nil { - return - } - if transactionMetadata.finalized, err = marshalUtil.ReadBool(); err != nil { - return - } - if transactionMetadata.liked, err = marshalUtil.ReadBool(); err != nil { - return - } - if transactionMetadata.confirmed, err = marshalUtil.ReadBool(); err != nil { - return - } - if transactionMetadata.rejected, err = marshalUtil.ReadBool(); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - - return + return marshalutil.New(branchmanager.BranchIDLength + 2*marshalutil.TIME_SIZE + 6*marshalutil.BOOL_SIZE). + WriteBytes(transactionMetadata.BranchID().Bytes()). + WriteTime(transactionMetadata.SolidificationTime()). + WriteTime(transactionMetadata.FinalizationTime()). + WriteBool(transactionMetadata.Solid()). + WriteBool(transactionMetadata.Preferred()). + WriteBool(transactionMetadata.Finalized()). + WriteBool(transactionMetadata.Liked()). + WriteBool(transactionMetadata.Confirmed()). + WriteBool(transactionMetadata.Rejected()). + Bytes() } // CachedTransactionMetadata is a wrapper for the object storage, that takes care of type casting the TransactionMetadata objects. diff --git a/dapps/valuetransfers/packages/transaction/transaction.go b/dapps/valuetransfers/packages/transaction/transaction.go index da41e4a4140bc49d769891ee296f98b86056bfd1..bd552869dd4fee9ec007a1ee1a4cebec9ffe426e 100644 --- a/dapps/valuetransfers/packages/transaction/transaction.go +++ b/dapps/valuetransfers/packages/transaction/transaction.go @@ -64,54 +64,96 @@ func New(inputs *Inputs, outputs *Outputs) *Transaction { } // FromBytes unmarshals a Transaction from a sequence of bytes. -func FromBytes(bytes []byte, optionalTargetObject ...*Transaction) (result *Transaction, consumedBytes int, err error) { +func FromBytes(bytes []byte) (result *Transaction, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = Parse(marshalUtil, optionalTargetObject...) + result, err = Parse(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } -// FromStorageKey is a factory method that creates a new Transaction instance from a storage key of the objectstorage. +// FromObjectStorage is a factory method that creates a new Transaction instance from a storage key of the objectstorage. // It is used by the objectstorage, to create new instances of this entity. -func FromStorageKey(key []byte, optionalTargetObject ...*Transaction) (result objectstorage.StorableObject, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Transaction{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to FromStorageKey") +func FromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + // parse the message + transaction, err := Parse(marshalutil.New(data)) + if err != nil { + return } - marshalUtil := marshalutil.New(key) - id, err := ParseID(marshalUtil) + id, err := ParseID(marshalutil.New(key)) if err != nil { return } - result.(*Transaction).id = &id + transaction.id = &id + + // assign result + result = transaction return } // Parse unmarshals a Transaction using the given marshalUtil (for easier marshaling/unmarshaling). -func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Transaction) (result *Transaction, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Transaction{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to Parse") +func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Transaction, err error) { + // determine read offset before starting to parse + readOffsetStart := marshalUtil.ReadOffset() + + // parse information + result = &Transaction{} + + // unmarshal inputs + parsedInputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return InputsFromBytes(data) }) + if err != nil { + return } + result.inputs = parsedInputs.(*Inputs) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + // unmarshal outputs + parsedOutputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return OutputsFromBytes(data) }) + if err != nil { + return + } + result.outputs = parsedOutputs.(*Outputs) + // unmarshal data payload size + var dataPayloadSize uint32 + dataPayloadSize, err = marshalUtil.ReadUint32() + if err != nil { return - }) + } + + // unmarshal data payload + result.dataPayload, err = marshalUtil.ReadBytes(int(dataPayloadSize)) + if err != nil { + return + } + + // store essence bytes + essenceBytesCount := marshalUtil.ReadOffset() - readOffsetStart + result.essenceBytes, err = marshalUtil.ReadBytes(essenceBytesCount, readOffsetStart) + if err != nil { + return + } + + // unmarshal outputs + parsedSignatures, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return SignaturesFromBytes(data) }) + if err != nil { + return + } + result.signatures = parsedSignatures.(*Signatures) + + // store signature bytes + signatureBytesCount := marshalUtil.ReadOffset() - readOffsetStart - essenceBytesCount + result.signatureBytes, err = marshalUtil.ReadBytes(signatureBytesCount, readOffsetStart+essenceBytesCount) + if err != nil { + return + } + + // store bytes, so we don't have to marshal manually + result.bytes, err = marshalUtil.ReadBytes(essenceBytesCount+signatureBytesCount, readOffsetStart) + if err != nil { + return + } return } @@ -379,64 +421,6 @@ func (transaction *Transaction) ObjectStorageValue() []byte { return transaction.Bytes() } -// UnmarshalObjectStorageValue unmarshals the bytes that are stored in the value of the objectstorage. -func (transaction *Transaction) UnmarshalObjectStorageValue(bytes []byte) (consumedBytes int, err error) { - // initialize helper - marshalUtil := marshalutil.New(bytes) - - // unmarshal inputs - parsedInputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return InputsFromBytes(data) }) - if err != nil { - return - } - transaction.inputs = parsedInputs.(*Inputs) - - // unmarshal outputs - parsedOutputs, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return OutputsFromBytes(data) }) - if err != nil { - return - } - transaction.outputs = parsedOutputs.(*Outputs) - - // unmarshal data payload size - var dataPayloadSize uint32 - dataPayloadSize, err = marshalUtil.ReadUint32() - if err != nil { - return - } - - // unmarshal data payload - transaction.dataPayload, err = marshalUtil.ReadBytes(int(dataPayloadSize)) - if err != nil { - return - } - - // store essence bytes - essenceBytesCount := marshalUtil.ReadOffset() - transaction.essenceBytes = make([]byte, essenceBytesCount) - copy(transaction.essenceBytes, bytes[:essenceBytesCount]) - - // unmarshal outputs - parsedSignatures, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return SignaturesFromBytes(data) }) - if err != nil { - return - } - transaction.signatures = parsedSignatures.(*Signatures) - - // store signature bytes - signatureBytesCount := marshalUtil.ReadOffset() - essenceBytesCount - transaction.signatureBytes = make([]byte, signatureBytesCount) - copy(transaction.signatureBytes, bytes[essenceBytesCount:essenceBytesCount+signatureBytesCount]) - - // return the number of bytes we processed - consumedBytes = essenceBytesCount + signatureBytesCount - - // store bytes, so we don't have to marshal manually - transaction.bytes = bytes[:consumedBytes] - - return -} - // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// // CachedTransaction is a wrapper for the object storage, that takes care of type casting the Transaction objects. diff --git a/dapps/valuetransfers/packages/transaction/transaction_test.go b/dapps/valuetransfers/packages/transaction/transaction_test.go index d1bb17271ba803bd0577b2ca40fc635757c5b54d..54e6c698ee1912620d968ad2361cd449703d1745 100644 --- a/dapps/valuetransfers/packages/transaction/transaction_test.go +++ b/dapps/valuetransfers/packages/transaction/transaction_test.go @@ -89,8 +89,7 @@ func TestMarshalingEmptyDataPayload(t *testing.T) { v := tx.ObjectStorageValue() - tx1 := Transaction{} - _, err := tx1.UnmarshalObjectStorageValue(v) + tx1, _, err := FromBytes(v) assert.NoError(t, err) assert.Equal(t, true, tx1.SignaturesValid()) @@ -116,8 +115,7 @@ func TestMarshalingDataPayload(t *testing.T) { v := tx.ObjectStorageValue() - tx1 := Transaction{} - _, err = tx1.UnmarshalObjectStorageValue(v) + tx1, _, err := FromBytes(v) assert.NoError(t, err) assert.Equal(t, true, tx1.SignaturesValid()) diff --git a/go.mod b/go.mod index 8e79858b8638c30738372d7bca97009cff0623a7..638db4d32813fb66e36457ce02f6c694889ed3c7 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/gobuffalo/packr/v2 v2.8.0 github.com/golang/protobuf v1.4.2 github.com/gorilla/websocket v1.4.2 - github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21 + github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6 github.com/labstack/echo v3.3.10+incompatible github.com/labstack/gommon v0.3.0 github.com/magiconair/properties v1.8.1 diff --git a/go.sum b/go.sum index efba6b5b5b289306bdfe709d64bf1bcd8c4ce80f..70b3a9f6bf32089d87ff5b448558ab661174ad48 100644 --- a/go.sum +++ b/go.sum @@ -350,8 +350,8 @@ github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7 github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21 h1:ZbVqGAVePnHgTSF4ZuXXH9G+UBQcp1/KUbqpTBMaapg= -github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21/go.mod h1:tLI+HS0amqY5YqClfFZDHlFM7eeIZjoU25Oj1u9jCzQ= +github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6 h1:fYKwzYCzewzTLFb/hCEnJtopHL7Qm+Ztvki+6Z2bVXo= +github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6/go.mod h1:tLI+HS0amqY5YqClfFZDHlFM7eeIZjoU25Oj1u9jCzQ= github.com/iotaledger/iota.go v1.0.0-beta.15 h1:HI8PqerEnO1CCIqmXHJ6zh1IaSFXU+S0qlUAEKshho8= github.com/iotaledger/iota.go v1.0.0-beta.15/go.mod h1:Rn6v5hLAn8YBaJlRu1ZQdPAgKlshJR1PTeLQaft2778= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/packages/binary/drng/payload/payload.go b/packages/binary/drng/payload/payload.go index 8d49709b4789773b376f5544d69b81c9cf7309c0..1849b55b447f11b76641313855cbca19dcb71ff3 100644 --- a/packages/binary/drng/payload/payload.go +++ b/packages/binary/drng/payload/payload.go @@ -42,27 +42,18 @@ func Parse(marshalUtil *marshalutil.MarshalUtil) (*Payload, error) { // FromBytes parses the marshaled version of a Payload into an object. // It either returns a new Payload or fills an optionally provided Payload with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to OutputFromBytes") - } - +func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) { // initialize helper marshalUtil := marshalutil.New(bytes) // read information that are required to identify the payload from the outside - if _, err = marshalUtil.ReadUint32(); err != nil { + result = &Payload{} + len, err := marshalUtil.ReadUint32() + if err != nil { return } - len, err := marshalUtil.ReadUint32() - if err != nil { + if _, err = marshalUtil.ReadUint32(); err != nil { return } @@ -109,8 +100,8 @@ func (payload *Payload) Bytes() (bytes []byte) { marshalUtil := marshalutil.New() // marshal the payload specific information - marshalUtil.WriteUint32(Type) marshalUtil.WriteUint32(uint32(len(payload.Data) + header.Length)) + marshalUtil.WriteUint32(Type) marshalUtil.WriteBytes(payload.Header.Bytes()) marshalUtil.WriteBytes(payload.Data[:]) @@ -142,17 +133,9 @@ func (payload *Payload) Marshal() (bytes []byte, err error) { return payload.Bytes(), nil } -// Unmarshal unmarshals the given bytes into a drng payload. -func (payload *Payload) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, payload) - - return -} - func init() { payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { - payload = &Payload{} - err = payload.Unmarshal(data) + payload, _, err = FromBytes(data) return }) diff --git a/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go b/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go index 25644f371bd0fa29e01732ff8770ae9a1cb8ff0b..273f419738f49bde12db58b405e84503eb7751e0 100644 --- a/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go +++ b/packages/binary/drng/subtypes/collectivebeacon/payload/payload.go @@ -52,17 +52,7 @@ func Parse(marshalUtil *marshalutil.MarshalUtil) (*Payload, error) { // FromBytes parses the marshaled version of a Payload into an object. // It either returns a new Payload or fills an optionally provided Payload with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to OutputFromBytes") - } - +func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) { // initialize helper marshalUtil := marshalutil.New(bytes) @@ -75,6 +65,7 @@ func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, } // parse header + result = &Payload{} if result.Header, err = header.Parse(marshalUtil); err != nil { return } @@ -132,8 +123,8 @@ func (payload *Payload) Bytes() (bytes []byte) { // marshal fields payloadLength := header.Length + marshalutil.UINT64_SIZE + SignatureSize*2 + PublicKeySize marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength) - marshalUtil.WriteUint32(drngPayload.Type) marshalUtil.WriteUint32(uint32(payloadLength)) + marshalUtil.WriteUint32(drngPayload.Type) marshalUtil.WriteBytes(payload.Header.Bytes()) marshalUtil.WriteUint64(payload.Round) marshalUtil.WriteBytes(payload.PrevSignature) @@ -171,11 +162,4 @@ func (payload *Payload) Marshal() (bytes []byte, err error) { return payload.Bytes(), nil } -// Unmarshal returns a collective beacon payload from the given bytes. -func (payload *Payload) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, payload) - - return -} - // // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/binary/messagelayer/message/message.go b/packages/binary/messagelayer/message/message.go index 95954923f17337327c4e2de5e7b1e17bb3265353..0ea9d7a2f8260fad608c85f596611d46c09385dd 100644 --- a/packages/binary/messagelayer/message/message.go +++ b/packages/binary/messagelayer/message/message.go @@ -1,6 +1,7 @@ package message import ( + "fmt" "sync" "time" @@ -52,56 +53,77 @@ func New(parent1ID ID, parent2ID ID, issuingTime time.Time, issuerPublicKey ed25 } // FromBytes parses the given bytes into a message. -func FromBytes(bytes []byte, optionalTargetObject ...*Message) (result *Message, consumedBytes int, err error) { +func FromBytes(bytes []byte) (result *Message, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = Parse(marshalUtil, optionalTargetObject...) + result, err = Parse(marshalUtil) consumedBytes = marshalUtil.ReadOffset() + return } -// Parse parses a message from the given marshal util. -func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Message) (result *Message, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Message{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to Parse") +// Parse parses a Message using the given marshal util. +func Parse(marshalUtil *marshalutil.MarshalUtil) (result *Message, err error) { + // determine read offset before starting to parse + readOffsetStart := marshalUtil.ReadOffset() + + // parse information + result = &Message{} + if result.parent1ID, err = ParseID(marshalUtil); err != nil { + return } + if result.parent2ID, err = ParseID(marshalUtil); err != nil { + return + } + if result.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil { + return + } + if result.issuingTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil { + return + } + if result.payload, err = payload.Parse(marshalUtil); err != nil { + return + } + if result.nonce, err = marshalUtil.ReadUint64(); err != nil { + return + } + if result.signature, err = ed25519.ParseSignature(marshalUtil); err != nil { + return + } + + // retrieve the number of bytes we processed + readOffsetEnd := marshalUtil.ReadOffset() - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) + // store marshaled version as a copy + result.bytes, err = marshalUtil.ReadBytes(readOffsetEnd-readOffsetStart, readOffsetStart) + if err != nil { + err = fmt.Errorf("error trying to copy raw source bytes: %w", err) return - }) + } return } -// StorableObjectFromKey gets called when we restore a message from storage. -// The bytes and the content will be unmarshaled by an external caller (the objectStorage factory). -func StorableObjectFromKey(key []byte, optionalTargetObject ...*Message) (result objectstorage.StorableObject, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Message{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to StorableObjectFromKey") +// FromObjectStorage gets called when we restore a message from the ObjectStorage. +func FromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + // parse the message + message, err := Parse(marshalutil.New(data)) + if err != nil { + return } - marshalUtil := marshalutil.New(key) - id, idErr := ParseID(marshalUtil) - if idErr != nil { - err = idErr - + // parse the ID from they key + id, err := ParseID(marshalutil.New(key)) + if err != nil { return } - result.(*Message).id = &id - consumedBytes = marshalUtil.ReadOffset() + message.id = &id + + // assign result + result = message return } @@ -254,47 +276,6 @@ func (message *Message) Bytes() []byte { return message.bytes } -// UnmarshalObjectStorageValue unmarshals the bytes into a message. -func (message *Message) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - // initialize helper - marshalUtil := marshalutil.New(data) - - // parse information - if message.parent1ID, err = ParseID(marshalUtil); err != nil { - return - } - if message.parent2ID, err = ParseID(marshalUtil); err != nil { - return - } - if message.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil { - return - } - if message.issuingTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if message.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil { - return - } - if message.payload, err = payload.Parse(marshalUtil); err != nil { - return - } - if message.nonce, err = marshalUtil.ReadUint64(); err != nil { - return - } - if message.signature, err = ed25519.ParseSignature(marshalUtil); err != nil { - return - } - - // return the number of bytes we processed - consumedBytes = marshalUtil.ReadOffset() - - // store marshaled version - message.bytes = make([]byte, consumedBytes) - copy(message.bytes, data) - - return -} - // ObjectStorageKey returns the key of the stored message object. // This returns the bytes of the message ID. func (message *Message) ObjectStorageKey() []byte { diff --git a/packages/binary/messagelayer/payload/data.go b/packages/binary/messagelayer/payload/data.go index 26929cf79531dbadeb6511ccb855ff8dad9d52c5..6623a7f503687410fbd47a077b020481e61bde68 100644 --- a/packages/binary/messagelayer/payload/data.go +++ b/packages/binary/messagelayer/payload/data.go @@ -23,32 +23,23 @@ func NewData(data []byte) *Data { } // DataFromBytes creates a new data payload from the given bytes. -func DataFromBytes(bytes []byte, optionalTargetObject ...*Data) (result *Data, consumedBytes int, err error) { +func DataFromBytes(bytes []byte) (result *Data, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseData(marshalUtil, optionalTargetObject...) + result, err = ParseData(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseData parses a new data payload out of the given marshal util. -func ParseData(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Data) (result *Data, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Data{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ParseData") - } - +func ParseData(marshalUtil *marshalutil.MarshalUtil) (result *Data, err error) { // parse information - result.payloadType, err = marshalUtil.ReadUint32() + result = &Data{} + payloadBytes, err := marshalUtil.ReadUint32() if err != nil { return } - payloadBytes, err := marshalUtil.ReadUint32() + result.payloadType, err = marshalUtil.ReadUint32() if err != nil { return } @@ -76,21 +67,14 @@ func (dataPayload *Data) Bytes() []byte { marshalUtil := marshalutil.New() // marshal the payload specific information - marshalUtil.WriteUint32(dataPayload.Type()) marshalUtil.WriteUint32(uint32(len(dataPayload.data))) + marshalUtil.WriteUint32(dataPayload.Type()) marshalUtil.WriteBytes(dataPayload.data[:]) // return result return marshalUtil.Bytes() } -// Unmarshal unmarshalls the byte array to a data payload. -func (dataPayload *Data) Unmarshal(data []byte) (err error) { - _, _, err = DataFromBytes(data, dataPayload) - - return -} - func (dataPayload *Data) String() string { return stringify.Struct("Data", stringify.StructField("type", int(dataPayload.Type())), @@ -98,11 +82,9 @@ func (dataPayload *Data) String() string { ) } -// GenericPayloadUnmarshalerFactory is an unmarshaler for the generic data payload type. -func GenericPayloadUnmarshalerFactory(payloadType Type) Unmarshaler { - return func(data []byte) (payload Payload, err error) { - payload = &Data{payloadType: payloadType} - err = payload.Unmarshal(data) - return - } +// GenericPayloadUnmarshaler is an unmarshaler for the generic data payload type. +func GenericPayloadUnmarshaler(data []byte) (payload Payload, err error) { + payload, _, err = DataFromBytes(data) + + return } diff --git a/packages/binary/messagelayer/payload/payload.go b/packages/binary/messagelayer/payload/payload.go index fdaab2e5f685820e1686e07739f166e762d44ca9..bdf235ecc7854694caf23982a5d8c384ece2cd79 100644 --- a/packages/binary/messagelayer/payload/payload.go +++ b/packages/binary/messagelayer/payload/payload.go @@ -25,9 +25,10 @@ var ( func init() { // register the generic unmarshaler - SetGenericUnmarshalerFactory(GenericPayloadUnmarshalerFactory) + SetGenericUnmarshaler(GenericPayloadUnmarshaler) + // register the generic data payload type - RegisterType(DataType, ObjectName, GenericPayloadUnmarshalerFactory(DataType)) + RegisterType(DataType, ObjectName, GenericPayloadUnmarshaler) } // Payload represents some kind of payload of data which only gains meaning by having @@ -35,10 +36,10 @@ func init() { type Payload interface { // Type returns the type of the payload. Type() Type + // Bytes returns the payload bytes. Bytes() []byte - // Unmarshal unmarshals the payload from the given bytes. - Unmarshal(bytes []byte) error + // String returns a human-friendly representation of the payload. String() string } @@ -49,11 +50,6 @@ func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) // calculate result - payloadType, err := marshalUtil.ReadUint32() - if err != nil { - return - } - payloadSize, err := marshalUtil.ReadUint32() if err != nil { return @@ -64,6 +60,11 @@ func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) { return } + payloadType, err := marshalUtil.ReadUint32() + if err != nil { + return + } + marshalUtil.ReadSeek(marshalUtil.ReadOffset() - marshalutil.UINT32_SIZE*2) payloadBytes, err := marshalUtil.ReadBytes(int(payloadSize) + 8) if err != nil { @@ -75,7 +76,7 @@ func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) { if err != nil { // fallback to the generic unmarshaler if registered type fails to unmarshal marshalUtil.ReadSeek(readOffset) - result, err = GenericPayloadUnmarshalerFactory(payloadType)(payloadBytes) + result, err = genericUnmarshaler(payloadBytes) if err != nil { return } diff --git a/packages/binary/messagelayer/payload/type_register.go b/packages/binary/messagelayer/payload/type_register.go index eb22e51eca3eeb6d2f5e3342be35de3edb33d9bf..728119f25cb73e2b3efebe78f041915c5d8037c6 100644 --- a/packages/binary/messagelayer/payload/type_register.go +++ b/packages/binary/messagelayer/payload/type_register.go @@ -14,9 +14,9 @@ type Definition struct { } var ( - typeRegister = make(map[Type]Definition) - typeRegisterMutex sync.RWMutex - genericUnmarshalerFactory func(payloadType Type) Unmarshaler + typeRegister = make(map[Type]Definition) + typeRegisterMutex sync.RWMutex + genericUnmarshaler Unmarshaler ) // RegisterType registers a payload type with the given unmarshaler. @@ -34,15 +34,17 @@ func RegisterType(payloadType Type, payloadName string, unmarshaler Unmarshaler) func GetUnmarshaler(payloadType Type) Unmarshaler { typeRegisterMutex.RLock() defer typeRegisterMutex.RUnlock() + if definition, exists := typeRegister[payloadType]; exists { return definition.Unmarshaler } - return genericUnmarshalerFactory(payloadType) + + return genericUnmarshaler } -// SetGenericUnmarshalerFactory sets the generic unmarshaler. -func SetGenericUnmarshalerFactory(unmarshalerFactory func(payloadType Type) Unmarshaler) { - genericUnmarshalerFactory = unmarshalerFactory +// SetGenericUnmarshaler sets the generic unmarshaler. +func SetGenericUnmarshaler(unmarshaler Unmarshaler) { + genericUnmarshaler = unmarshaler } // Name returns the name of a given payload type. diff --git a/packages/binary/messagelayer/tangle/approver.go b/packages/binary/messagelayer/tangle/approver.go index 8dc3a6ff8ef4ff7640f09a31410e4b60ecfd05f2..e5d162de400e4f4abad512533ced10b282924390 100644 --- a/packages/binary/messagelayer/tangle/approver.go +++ b/packages/binary/messagelayer/tangle/approver.go @@ -27,54 +27,30 @@ func NewApprover(referencedMessageID message.ID, approverMessageID message.ID) * } // ApproverFromBytes parses the given bytes into an approver. -func ApproverFromBytes(bytes []byte, optionalTargetObject ...*Approver) (result *Approver, consumedBytes int, err error) { +func ApproverFromBytes(bytes []byte) (result *Approver, consumedBytes int, err error) { marshalUtil := marshalutil.New(bytes) - result, err = ParseApprover(marshalUtil, optionalTargetObject...) + result, err = ParseApprover(marshalUtil) consumedBytes = marshalUtil.ReadOffset() return } // ParseApprover parses a new approver from the given marshal util. -func ParseApprover(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Approver) (result *Approver, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return ApproverFromStorageKey(data, optionalTargetObject...) - }) - if parseErr != nil { - err = parseErr +func ParseApprover(marshalUtil *marshalutil.MarshalUtil) (result *Approver, err error) { + result = &Approver{} + + if result.referencedMessageID, err = message.ParseID(marshalUtil); err != nil { return } - result = parsedObject.(*Approver) - - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.approverMessageID, err = message.ParseID(marshalUtil); err != nil { return - }) + } return } -// ApproverFromStorageKey returns an approver for the given key. -func ApproverFromStorageKey(key []byte, optionalTargetObject ...*Approver) (result objectstorage.StorableObject, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Approver{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to ApproverFromStorageKey") - } - - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - if result.(*Approver).referencedMessageID, err = message.ParseID(marshalUtil); err != nil { - return - } - if result.(*Approver).approverMessageID, err = message.ParseID(marshalUtil); err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() +// ApproverFromObjectStorage returns an approver for the given key. +func ApproverFromObjectStorage(key []byte, _ []byte) (result objectstorage.StorableObject, err error) { + result, _, err = ApproverFromBytes(key) return } @@ -116,11 +92,6 @@ func (approver *Approver) ObjectStorageValue() (result []byte) { return } -// UnmarshalObjectStorageValue unmarshals the stored bytes into an approver. -func (approver *Approver) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - return -} - // Update updates the approver. // This should should never happen and will panic if attempted. func (approver *Approver) Update(other objectstorage.StorableObject) { diff --git a/packages/binary/messagelayer/tangle/messagemetadata.go b/packages/binary/messagelayer/tangle/messagemetadata.go index cea4d89dde5c406be71249d0fb8ea921c175ef60..840d1837ca4a58292022d6de9496057126f52d9d 100644 --- a/packages/binary/messagelayer/tangle/messagemetadata.go +++ b/packages/binary/messagelayer/tangle/messagemetadata.go @@ -4,6 +4,7 @@ import ( "sync" "time" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" @@ -41,36 +42,32 @@ func MessageMetadataFromBytes(bytes []byte) (result *MessageMetadata, consumedBy } // ParseMessageMetadata parses the marshalUtil into a MessageMetadata. -// If it successfully parses the marshalUtil, it delegates to MessageMetadataFromStorageKey. +// If it successfully parses the marshalUtil, it delegates to MessageMetadataFromObjectStorage. // Else, delegates to UnmarshalObjectStorageValue. func ParseMessageMetadata(marshalUtil *marshalutil.MarshalUtil) (result *MessageMetadata, err error) { - parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { - return MessageMetadataFromStorageKey(data, nil) - }) - if parseErr != nil { - err = parseErr + result = &MessageMetadata{} + + if result.messageID, err = message.ParseID(marshalUtil); err != nil { return } - result = parsedObject.(*MessageMetadata) - _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) { - parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data) - + if result.receivedTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.solidificationTime, err = marshalUtil.ReadTime(); err != nil { + return + } + if result.solid, err = marshalUtil.ReadBool(); err != nil { return - }) + } return } -// MessageMetadataFromStorageKey unmarshals the stored bytes into a MessageMetadata. -func MessageMetadataFromStorageKey(key []byte, _ []byte) (result objectstorage.StorableObject, consumedBytes int, err error) { - result = &MessageMetadata{} - - marshalUtil := marshalutil.New(key) - result.(*MessageMetadata).messageID, err = message.ParseID(marshalUtil) - if err != nil { +// MessageMetadataFromObjectStorage unmarshals the stored bytes into a MessageMetadata. +func MessageMetadataFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + if result, _, err = MessageMetadataFromBytes(byteutils.ConcatBytes(key, data)); err != nil { return } - consumedBytes = marshalUtil.ReadOffset() return } @@ -126,6 +123,11 @@ func (messageMetadata *MessageMetadata) SolidificationTime() time.Time { return messageMetadata.solidificationTime } +// Bytes returns a marshaled version of the whole MessageMetadata object. +func (messageMetadata *MessageMetadata) Bytes() []byte { + return byteutils.ConcatBytes(messageMetadata.ObjectStorageKey(), messageMetadata.ObjectStorageValue()) +} + // ObjectStorageKey returns the key of the stored message metadata object. // This returns the bytes of the messageID. func (messageMetadata *MessageMetadata) ObjectStorageKey() []byte { @@ -142,25 +144,6 @@ func (messageMetadata *MessageMetadata) ObjectStorageValue() []byte { Bytes() } -// UnmarshalObjectStorageValue unmarshals the stored bytes into a messageMetadata. -func (messageMetadata *MessageMetadata) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - - if messageMetadata.receivedTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if messageMetadata.solidificationTime, err = marshalUtil.ReadTime(); err != nil { - return - } - if messageMetadata.solid, err = marshalUtil.ReadBool(); err != nil { - return - } - - consumedBytes = marshalUtil.ReadOffset() - - return -} - // Update updates the message metadata. // This should never happen and will panic if attempted. func (messageMetadata *MessageMetadata) Update(other objectstorage.StorableObject) { diff --git a/packages/binary/messagelayer/tangle/missingmessage.go b/packages/binary/messagelayer/tangle/missingmessage.go index f8ba9f2983b6433c4b3cd3a749bfa8545fe62187..5d691576f7a2073f2778c192aeff23d946e0f7fc 100644 --- a/packages/binary/messagelayer/tangle/missingmessage.go +++ b/packages/binary/messagelayer/tangle/missingmessage.go @@ -3,6 +3,7 @@ package tangle import ( "time" + "github.com/iotaledger/hive.go/byteutils" "github.com/iotaledger/hive.go/marshalutil" "github.com/iotaledger/hive.go/objectstorage" @@ -25,27 +26,31 @@ func NewMissingMessage(messageID message.ID) *MissingMessage { } } -// MissingMessageFromStorageKey unmarshals the stored key into a desirable target specified by 0 or 1 optional argument. -// The default target is MissingMessage. -// It unmarshals into the target specified or panics if more than 1 target is specified. -func MissingMessageFromStorageKey(key []byte, optionalTargetObject ...*MissingMessage) (result objectstorage.StorableObject, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &MissingMessage{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to MissingMessageFromStorageKey") - } +// MissingMessageFromBytes parses the given bytes into a MissingMessage. +func MissingMessageFromBytes(bytes []byte) (result *MissingMessage, consumedBytes int, err error) { + marshalUtil := marshalutil.New(bytes) + result, err = ParseMissingMessage(marshalUtil) + consumedBytes = marshalUtil.ReadOffset() + return +} - // parse the properties that are stored in the key - marshalUtil := marshalutil.New(key) - result.(*MissingMessage).messageID, err = message.ParseID(marshalUtil) - if err != nil { +// MissingMessageFromObjectStorage creates a MissingMessage from the ObjectStorage. +func MissingMessageFromObjectStorage(key []byte, data []byte) (result objectstorage.StorableObject, err error) { + result, _, err = MissingMessageFromBytes(byteutils.ConcatBytes(key, data)) + + return +} + +// ParseMissingMessage parses a MissingMessage from the given marshal util. +func ParseMissingMessage(marshalUtil *marshalutil.MarshalUtil) (result *MissingMessage, err error) { + result = &MissingMessage{} + + if result.messageID, err = message.ParseID(marshalUtil); err != nil { + return + } + if result.missingSince, err = marshalUtil.ReadTime(); err != nil { return } - consumedBytes = marshalUtil.ReadOffset() return } @@ -60,6 +65,11 @@ func (missingMessage *MissingMessage) MissingSince() time.Time { return missingMessage.missingSince } +// Bytes returns a marshaled version of this MissingMessage. +func (missingMessage *MissingMessage) Bytes() []byte { + return byteutils.ConcatBytes(missingMessage.ObjectStorageKey(), missingMessage.ObjectStorageValue()) +} + // Update update the missing message. // It should never happen and will panic if called. func (missingMessage *MissingMessage) Update(other objectstorage.StorableObject) { @@ -81,15 +91,3 @@ func (missingMessage *MissingMessage) ObjectStorageValue() (result []byte) { return } - -// UnmarshalObjectStorageValue unmarshals the stored bytes into a missing message. -func (missingMessage *MissingMessage) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) { - marshalUtil := marshalutil.New(data) - missingMessage.missingSince, err = marshalUtil.ReadTime() - if err != nil { - return - } - consumedBytes = marshalUtil.ReadOffset() - - return -} diff --git a/packages/binary/messagelayer/tangle/tangle.go b/packages/binary/messagelayer/tangle/tangle.go index 6c394ef6aade9a663c3f9c9def9b2d1ed4e85c2b..95e21f0870912c56f97e4daee749b527542cda0e 100644 --- a/packages/binary/messagelayer/tangle/tangle.go +++ b/packages/binary/messagelayer/tangle/tangle.go @@ -30,28 +30,16 @@ type Tangle struct { shutdown chan struct{} } -func messageFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return message.StorableObjectFromKey(key) -} - -func approverFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return ApproverFromStorageKey(key) -} - -func missingMessageFactory(key []byte, _ []byte) (objectstorage.StorableObject, int, error) { - return MissingMessageFromStorageKey(key) -} - // New creates a new Tangle. func New(store kvstore.KVStore) (result *Tangle) { osFactory := objectstorage.NewFactory(store, storageprefix.MessageLayer) result = &Tangle{ shutdown: make(chan struct{}), - messageStorage: osFactory.New(PrefixMessage, messageFactory, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), - messageMetadataStorage: osFactory.New(PrefixMessageMetadata, MessageMetadataFromStorageKey, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), - approverStorage: osFactory.New(PrefixApprovers, approverFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(message.IDLength, message.IDLength), objectstorage.LeakDetectionEnabled(false)), - missingMessageStorage: osFactory.New(PrefixMissingMessage, missingMessageFactory, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + messageStorage: osFactory.New(PrefixMessage, message.FromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + messageMetadataStorage: osFactory.New(PrefixMessageMetadata, MessageMetadataFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), + approverStorage: osFactory.New(PrefixApprovers, ApproverFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(message.IDLength, message.IDLength), objectstorage.LeakDetectionEnabled(false)), + missingMessageStorage: osFactory.New(PrefixMissingMessage, MissingMessageFromObjectStorage, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)), Events: newEvents(), } diff --git a/packages/binary/messagelayer/tangle/tangle_test.go b/packages/binary/messagelayer/tangle/tangle_test.go index 5cff80696c84d4cc26f8dd6911ed5db0f5d32ade..1d1ad4caa5d5298ab43dc970df4c67e9deca1dec 100644 --- a/packages/binary/messagelayer/tangle/tangle_test.go +++ b/packages/binary/messagelayer/tangle/tangle_test.go @@ -94,7 +94,7 @@ func TestTangle_AttachMessage(t *testing.T) { func TestTangle_MissingMessages(t *testing.T) { // test parameters - messageCount := 200000 + messageCount := 2000 widthOfTheTangle := 2500 // variables required for the test diff --git a/packages/binary/messagelayer/test/message_test.go b/packages/binary/messagelayer/test/message_test.go index 1a59e9b4185a8d54089ff7c3478b7a65b2ae8605..8fd3551f5a853cdfff8e7058703389927621b204 100644 --- a/packages/binary/messagelayer/test/message_test.go +++ b/packages/binary/messagelayer/test/message_test.go @@ -17,21 +17,6 @@ import ( "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" ) -func TestMessage_StorableObjectFromKey(t *testing.T) { - key, err := message.NewID("2DYebCqnZ8PS5PyXBEvAvLB1fCF77Rn9RtofNHjEb2pSTujKi889d31FmguAs5DgL7YURw4GP2Y28JdJ7K4bjudG") - if err != nil { - panic(err) - } - - messageFromKey, consumedBytes, err := message.StorableObjectFromKey(key.Bytes()) - if err != nil { - panic(err) - } - - assert.Equal(t, message.IDLength, consumedBytes) - assert.Equal(t, key, messageFromKey.(*message.Message).ID()) -} - func TestMessage_VerifySignature(t *testing.T) { keyPair := ed25519.GenerateKeyPair() pl := payload.NewData([]byte("test")) @@ -57,6 +42,7 @@ func TestMessage_MarshalUnmarshal(t *testing.T) { t.Log(testMessage) restoredMessage, _, err := message.FromBytes(testMessage.Bytes()) + if assert.NoError(t, err, err) { assert.Equal(t, testMessage.ID(), restoredMessage.ID()) assert.Equal(t, testMessage.Parent1ID(), restoredMessage.Parent1ID()) diff --git a/plugins/syncbeacon/payload/payload.go b/plugins/syncbeacon/payload/payload.go index 8f4731f3ba7fc206fa2264e72ed04aad1e8f9102..f4319d61456ccfee93326dfc651aff8984357b3e 100644 --- a/plugins/syncbeacon/payload/payload.go +++ b/plugins/syncbeacon/payload/payload.go @@ -30,26 +30,17 @@ func NewSyncBeaconPayload(sentTime int64) *Payload { // FromBytes parses the marshaled version of a Payload into an object. // It either returns a new Payload or fills an optionally provided Payload with the parsed information. -func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, consumedBytes int, err error) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Payload{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to FromBytes") - } - +func FromBytes(bytes []byte) (result *Payload, consumedBytes int, err error) { // initialize helper marshalUtil := marshalutil.New(bytes) // read data - result.payloadType, err = marshalUtil.ReadUint32() + result = &Payload{} + _, err = marshalUtil.ReadUint32() if err != nil { return } - _, err = marshalUtil.ReadUint32() + result.payloadType, err = marshalUtil.ReadUint32() if err != nil { return } @@ -81,21 +72,14 @@ func (p *Payload) Bytes() []byte { objectLength := marshalutil.INT64_SIZE // marshal the p specific information - marshalUtil.WriteUint32(Type) marshalUtil.WriteUint32(uint32(objectLength)) + marshalUtil.WriteUint32(Type) marshalUtil.WriteInt64(p.sentTime) // return result return marshalUtil.Bytes() } -// Unmarshal unmarshals a given slice of bytes and fills the object. -func (p *Payload) Unmarshal(data []byte) (err error) { - _, _, err = FromBytes(data, p) - - return -} - // String returns a human readable version of syncbeacon payload (for debug purposes). func (p *Payload) String() string { return stringify.Struct("syncBeaconPayload", @@ -109,8 +93,7 @@ func IsSyncBeaconPayload(p *Payload) bool { func init() { payload.RegisterType(Type, ObjectName, func(data []byte) (payload payload.Payload, err error) { - payload = &Payload{} - err = payload.Unmarshal(data) + payload, _, err = FromBytes(data) return }) diff --git a/tools/integration-tests/runTests.sh b/tools/integration-tests/runTests.sh index 5783cc458cb9abdda0436ec2138422f78b09e8e9..0c2029fc9ba40e7d0c849b61e8a71097c8ede793 100755 --- a/tools/integration-tests/runTests.sh +++ b/tools/integration-tests/runTests.sh @@ -6,7 +6,7 @@ echo "Build GoShimmer image" docker build -t iotaledger/goshimmer ../../. echo "Pull additional Docker images" -docker pull angelocapossele/drand:1.1.1 +docker pull angelocapossele/drand:1.1.3 docker pull gaiaadm/pumba:0.7.2 docker pull gaiadocker/iproute2:latest diff --git a/tools/integration-tests/tester/framework/docker.go b/tools/integration-tests/tester/framework/docker.go index 1275d21b1cfb99fea821e16f7e57d76fd170c9c9..e7e0ec9405580b108a24cf0d214ae5178dac51e2 100644 --- a/tools/integration-tests/tester/framework/docker.go +++ b/tools/integration-tests/tester/framework/docker.go @@ -142,7 +142,7 @@ func (d *DockerContainer) CreateDrandMember(name string, goShimmerAPI string, le } env = append(env, "GOSHIMMER=http://"+goShimmerAPI) containerConfig := &container.Config{ - Image: "angelocapossele/drand:1.1.1", + Image: "angelocapossele/drand:1.1.3", ExposedPorts: nat.PortSet{ nat.Port("8000/tcp"): {}, }, diff --git a/tools/integration-tests/tester/go.mod b/tools/integration-tests/tester/go.mod index 59217fa244b040c79587540a371fe717fd723a9d..a6aa9ac729d7484df6f2c6fd8cc1a256d30916f0 100644 --- a/tools/integration-tests/tester/go.mod +++ b/tools/integration-tests/tester/go.mod @@ -10,7 +10,7 @@ require ( github.com/docker/go-units v0.4.0 // indirect github.com/drand/drand v1.1.1 github.com/iotaledger/goshimmer v0.1.3 - github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21 + github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6 github.com/mr-tron/base58 v1.2.0 github.com/opencontainers/go-digest v1.0.0 // indirect github.com/stretchr/testify v1.6.1 diff --git a/tools/integration-tests/tester/go.sum b/tools/integration-tests/tester/go.sum index bcc0347749aacb626c8210ad1e4178b0ad7a7c86..7c9ae207769be3f77520048e1676dc6be108b7e5 100644 --- a/tools/integration-tests/tester/go.sum +++ b/tools/integration-tests/tester/go.sum @@ -340,8 +340,10 @@ github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7 github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21 h1:ZbVqGAVePnHgTSF4ZuXXH9G+UBQcp1/KUbqpTBMaapg= -github.com/iotaledger/hive.go v0.0.0-20200909085811-5700df262e21/go.mod h1:tLI+HS0amqY5YqClfFZDHlFM7eeIZjoU25Oj1u9jCzQ= +github.com/iotaledger/hive.go v0.0.0-20200910095757-d9faf5386bb9 h1:/HxV4+EUwvM0b5rq8UkMSIOvgEpwIfWriexNoZPrYxs= +github.com/iotaledger/hive.go v0.0.0-20200910095757-d9faf5386bb9/go.mod h1:tLI+HS0amqY5YqClfFZDHlFM7eeIZjoU25Oj1u9jCzQ= +github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6 h1:fYKwzYCzewzTLFb/hCEnJtopHL7Qm+Ztvki+6Z2bVXo= +github.com/iotaledger/hive.go v0.0.0-20200910101329-33de3e2e05c6/go.mod h1:tLI+HS0amqY5YqClfFZDHlFM7eeIZjoU25Oj1u9jCzQ= github.com/iotaledger/iota.go v1.0.0-beta.15/go.mod h1:Rn6v5hLAn8YBaJlRu1ZQdPAgKlshJR1PTeLQaft2778= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/tools/integration-tests/tester/tests/drng/drng_test.go b/tools/integration-tests/tester/tests/drng/drng_test.go index dea82b0676afece108be3d9dd01a8906b15de0cc..f223aaded6df78f3747cf096be90706fa7a62d99 100644 --- a/tools/integration-tests/tester/tests/drng/drng_test.go +++ b/tools/integration-tests/tester/tests/drng/drng_test.go @@ -31,7 +31,10 @@ func TestDRNG(t *testing.T) { // randomness starts at round = 2 firstRound := uint64(2) - _, err = waitForRound(t, drng.Peers()[0], firstRound, 200) + resp, err := waitForRound(t, drng.Peers()[0], firstRound, 200) + if err != nil { + t.Log(resp) + } require.NoError(t, err) log.Printf("Waiting for randomness generation to be started... done\n")