-
Wolfgang Welz authoredWolfgang Welz authored
missingoutput.go 4.79 KiB
package tangle
import (
"time"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
"github.com/iotaledger/hive.go/marshalutil"
"github.com/iotaledger/hive.go/objectstorage"
)
// MissingOutputKeyPartitions defines the "layout" of the key. This enables prefix iterations in the objectstorage.
var MissingOutputKeyPartitions = objectstorage.PartitionKey([]int{address.Length, transaction.IDLength}...)
// MissingOutput represents an Output that was referenced by a Transaction, but that is missing in our object storage.
type MissingOutput struct {
objectstorage.StorableObjectFlags
outputID transaction.OutputID
missingSince time.Time
}
// NewMissingOutput creates a new MissingOutput object, that .
func NewMissingOutput(outputID transaction.OutputID) *MissingOutput {
return &MissingOutput{
outputID: outputID,
missingSince: time.Now(),
}
}
// MissingOutputFromBytes unmarshals a MissingOutput from a sequence of bytes - it either creates a new object or fills
// the optionally provided one with the parsed information.
func MissingOutputFromBytes(bytes []byte, optionalTargetObject ...*MissingOutput) (result *MissingOutput, consumedBytes int, err error) {
marshalUtil := marshalutil.New(bytes)
result, err = ParseMissingOutput(marshalUtil, optionalTargetObject...)
consumedBytes = marshalUtil.ReadOffset()
return
}
// ParseMissingOutput unmarshals a MissingOutput using the given marshalUtil (for easier marshaling/unmarshaling).
func ParseMissingOutput(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*MissingOutput) (result *MissingOutput, err error) {
parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, int, error) {
return MissingOutputFromStorageKey(data, optionalTargetObject...)
})
if parseErr != nil {
err = parseErr
return
}
result = parsedObject.(*MissingOutput)
_, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parsedBytes int, parseErr error) {
parsedBytes, parseErr = result.UnmarshalObjectStorageValue(data)
return
})
return
}
// MissingOutputFromStorageKey gets called when we restore a MissingOutput from the storage. The content will be
// unmarshaled by an external caller using the binary.ObjectStorageValue interface.
func MissingOutputFromStorageKey(key []byte, optionalTargetObject ...*MissingOutput) (result *MissingOutput, consumedBytes int, err error) {
// determine the target object that will hold the unmarshaled information
switch len(optionalTargetObject) {
case 0:
result = &MissingOutput{}
case 1:
result = optionalTargetObject[0]
default:
panic("too many arguments in call to MissingOutputFromStorageKey")
}
// parse the properties that are stored in the key
marshalUtil := marshalutil.New(key)
if result.outputID, err = transaction.ParseOutputID(marshalUtil); err != nil {
return
}
return
}
// ID returns the id of the Output that is missing.
func (missingOutput *MissingOutput) ID() transaction.OutputID {
return missingOutput.outputID
}
// MissingSince returns the Time since the transaction was first reported as being missing.
func (missingOutput *MissingOutput) MissingSince() time.Time {
return missingOutput.missingSince
}
// Bytes marshals the MissingOutput into a sequence of bytes.
func (missingOutput *MissingOutput) Bytes() []byte {
return marshalutil.New(transaction.OutputIDLength + marshalutil.TIME_SIZE).
WriteBytes(missingOutput.ObjectStorageKey()).
WriteBytes(missingOutput.ObjectStorageValue()).
Bytes()
}
// ObjectStorageKey returns the key that is used to store the object in the object storage.
func (missingOutput *MissingOutput) ObjectStorageKey() []byte {
return missingOutput.outputID.Bytes()
}
// ObjectStorageValue returns a bytes representation of the Transaction by implementing the encoding.BinaryMarshaler
// interface.
func (missingOutput *MissingOutput) ObjectStorageValue() []byte {
return marshalutil.New(marshalutil.TIME_SIZE).
WriteTime(missingOutput.MissingSince()).
Bytes()
}
// UnmarshalObjectStorageValue restores the values of a MissingOutput from a sequence of bytes using the encoding.BinaryUnmarshaler
// interface.
func (missingOutput *MissingOutput) UnmarshalObjectStorageValue(data []byte) (consumedBytes int, err error) {
marshalUtil := marshalutil.New(data)
if missingOutput.missingSince, err = marshalUtil.ReadTime(); err != nil {
return
}
consumedBytes = marshalUtil.ReadOffset()
return
}
// Update is disabled and panics if it ever gets called - updates are supposed to happen through the setters.
func (missingOutput *MissingOutput) Update(other objectstorage.StorableObject) {
panic("implement me")
}
// Interface contract: make compiler warn if the interface is not implemented correctly.
var _ objectstorage.StorableObject = &MissingOutput{}