diff --git a/packages/binary/tangle/model/transaction/transaction.go b/packages/binary/tangle/model/transaction/transaction.go index de18ffc47ed6514c4883dc1382da60d23184d758..227b30954db9086f9f640dcf954bdaa7c44c9ffe 100644 --- a/packages/binary/tangle/model/transaction/transaction.go +++ b/packages/binary/tangle/model/transaction/transaction.go @@ -273,5 +273,6 @@ func (transaction *Transaction) String() string { stringify.StructField("id", base58.Encode(transactionId[:])), stringify.StructField("trunkTransactionId", base58.Encode(transaction.trunkTransactionId[:])), stringify.StructField("trunkTransactionId", base58.Encode(transaction.branchTransactionId[:])), + stringify.StructField("payload", transaction.payload), ) } diff --git a/packages/binary/valuetransfers/address.go b/packages/binary/valuetransfers/address.go deleted file mode 100644 index ecf5f38739da463d601b2682eb13d38710f3490f..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/address.go +++ /dev/null @@ -1,35 +0,0 @@ -package valuetransfers - -import ( - "github.com/mr-tron/base58" -) - -type AddressVersion = byte - -type AddressDigest = []byte - -type Address [AddressLength]byte - -func NewAddress(bytes []byte) (address Address) { - copy(address[:], bytes) - - return -} - -func (address *Address) GetVersion() AddressVersion { - return address[0] -} - -func (address *Address) GetDigest() AddressDigest { - return address[1:] -} - -func (address Address) ToBytes() []byte { - return address[:] -} - -func (address Address) String() string { - return "Address(" + base58.Encode(address.ToBytes()) + ")" -} - -const AddressLength = 33 diff --git a/packages/binary/valuetransfers/payload/transfer/address/address.go b/packages/binary/valuetransfers/address/address.go similarity index 100% rename from packages/binary/valuetransfers/payload/transfer/address/address.go rename to packages/binary/valuetransfers/address/address.go diff --git a/packages/binary/valuetransfers/color.go b/packages/binary/valuetransfers/color.go deleted file mode 100644 index 29150eb215d1b8a6a00467944cf9038969c0eb7c..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/color.go +++ /dev/null @@ -1,37 +0,0 @@ -package valuetransfers - -import ( - "github.com/mr-tron/base58" - - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" -) - -type Color [ColorLength]byte - -func ColorFromBytes(bytes []byte) (result Color, err error, consumedBytes int) { - colorBytes, err := marshalutil.New(bytes).ReadBytes(ColorLength) - if err != nil { - return - } - copy(result[:], colorBytes) - - consumedBytes = ColorLength - - return -} - -const ColorLength = 32 - -func (color Color) Bytes() []byte { - return color[:] -} - -func (color Color) String() string { - if color == COLOR_IOTA { - return "IOTA" - } - - return base58.Encode(color[:]) -} - -var COLOR_IOTA Color = [32]byte{} diff --git a/packages/binary/valuetransfers/coloredbalance.go b/packages/binary/valuetransfers/coloredbalance.go deleted file mode 100644 index 2a9a5f6620fac323c784e7d4c4f26e9a1ecd640a..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/coloredbalance.go +++ /dev/null @@ -1,57 +0,0 @@ -package valuetransfers - -import ( - "strconv" - - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" -) - -type ColoredBalance struct { - color Color - balance int64 -} - -func NewColoredBalance(color Color, balance int64) (result *ColoredBalance) { - result = &ColoredBalance{ - color: color, - balance: balance, - } - - return -} - -func ColoredBalanceFromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes int) { - result = &ColoredBalance{} - - marshalUtil := marshalutil.New(bytes) - - if color, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { - return ColorFromBytes(data) - }); colorErr != nil { - return nil, colorErr, marshalUtil.ReadOffset() - } else { - result.color = color.(Color) - } - - result.balance, err = marshalUtil.ReadInt64() - if err != nil { - return - } - - consumedBytes = marshalUtil.ReadOffset() - - return -} - -func (balance *ColoredBalance) ToBytes() []byte { - marshalUtil := marshalutil.New(ColorLength + marshalutil.UINT32_SIZE) - - marshalUtil.WriteBytes(balance.color.Bytes()) - marshalUtil.WriteInt64(balance.balance) - - return marshalUtil.Bytes() -} - -func (balance *ColoredBalance) String() string { - return strconv.FormatInt(balance.balance, 10) + " " + balance.color.String() -} diff --git a/packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go b/packages/binary/valuetransfers/coloredbalance/color/color.go similarity index 90% rename from packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go rename to packages/binary/valuetransfers/coloredbalance/color/color.go index a06aa5536462519ec0c33236854fb99fbd5cd3cc..5afcc6915849ad52e53c4b31a814797225b935a0 100644 --- a/packages/binary/valuetransfers/payload/transfer/coloredbalance/color/color.go +++ b/packages/binary/valuetransfers/coloredbalance/color/color.go @@ -27,11 +27,11 @@ func (color Color) Bytes() []byte { } func (color Color) String() string { - if color == COLOR_IOTA { + if color == IOTA { return "IOTA" } return base58.Encode(color[:]) } -var COLOR_IOTA Color = [32]byte{} +var IOTA Color = [32]byte{} diff --git a/packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go b/packages/binary/valuetransfers/coloredbalance/coloredbalance.go similarity index 74% rename from packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go rename to packages/binary/valuetransfers/coloredbalance/coloredbalance.go index 1cae2c86ef6178b58c18b5b0df0453375c81f8cb..26b0a485207480e384c52f644299daf5c55649a3 100644 --- a/packages/binary/valuetransfers/payload/transfer/coloredbalance/coloredbalance.go +++ b/packages/binary/valuetransfers/coloredbalance/coloredbalance.go @@ -4,15 +4,15 @@ import ( "strconv" "github.com/iotaledger/goshimmer/packages/binary/marshalutil" - color2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance/color" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance/color" ) type ColoredBalance struct { - color color2.Color + color color.Color balance int64 } -func New(color color2.Color, balance int64) (result *ColoredBalance) { +func New(color color.Color, balance int64) (result *ColoredBalance) { result = &ColoredBalance{ color: color, balance: balance, @@ -27,11 +27,11 @@ func FromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes i marshalUtil := marshalutil.New(bytes) if coinColor, colorErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { - return color2.FromBytes(data) + return color.FromBytes(data) }); colorErr != nil { return nil, colorErr, marshalUtil.ReadOffset() } else { - result.color = coinColor.(color2.Color) + result.color = coinColor.(color.Color) } result.balance, err = marshalUtil.ReadInt64() @@ -45,7 +45,7 @@ func FromBytes(bytes []byte) (result *ColoredBalance, err error, consumedBytes i } func (balance *ColoredBalance) ToBytes() []byte { - marshalUtil := marshalutil.New(color2.Length + marshalutil.UINT32_SIZE) + marshalUtil := marshalutil.New(color.Length + marshalutil.UINT32_SIZE) marshalUtil.WriteBytes(balance.color.Bytes()) marshalUtil.WriteInt64(balance.balance) diff --git a/packages/binary/valuetransfers/outputs.go b/packages/binary/valuetransfers/outputs.go deleted file mode 100644 index a672469734932ad92b33edb285845054bdd98444..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/outputs.go +++ /dev/null @@ -1,154 +0,0 @@ -package valuetransfers - -import ( - "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" -) - -type Outputs struct { - *orderedmap.OrderedMap -} - -func NewOutputs(outputs map[Address][]*ColoredBalance) (result *Outputs) { - result = &Outputs{orderedmap.New()} - for address, balances := range outputs { - result.Add(address, balances) - } - - return -} - -// OutputsFromBytes reads the bytes and unmarshals the given information into an *Outputs object. It either creates a -// new object, or uses the optional object provided in the arguments. -func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *Outputs, err error, consumedBytes int) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Outputs{orderedmap.New()} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to OutputFromBytes") - } - - // initialize helper - marshalUtil := marshalutil.New(bytes) - - // read number of addresses in the outputs - addressCount, addressCountErr := marshalUtil.ReadUint32() - if addressCountErr != nil { - err = addressCountErr - - return - } - - // iterate the corresponding times and collect addresses + their details - for i := uint32(0); i < addressCount; i++ { - // read address - addressBytes, addressErr := marshalUtil.ReadBytes(AddressLength) - if addressErr != nil { - err = addressErr - - return - } - address := NewAddress(addressBytes) - - // read number of balances in the outputs - balanceCount, balanceCountErr := marshalUtil.ReadUint32() - if balanceCountErr != nil { - err = balanceCountErr - - return - } - - // iterate the corresponding times and collect balances - coloredBalances := make([]*ColoredBalance, balanceCount) - for j := uint32(0); j < balanceCount; j++ { - coloredBalance, coloredBalanceErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return ColoredBalanceFromBytes(data) }) - if coloredBalanceErr != nil { - err = coloredBalanceErr - - return - } - - coloredBalances[j] = coloredBalance.(*ColoredBalance) - } - - // add the gathered information as an output - result.Add(address, coloredBalances) - } - - // return the number of bytes we processed - consumedBytes = marshalUtil.ReadOffset() - - return -} - -func (outputs *Outputs) Add(address Address, balances []*ColoredBalance) *Outputs { - outputs.Set(address, balances) - - return outputs -} - -func (outputs *Outputs) ForEach(consumer func(address Address, balances []*ColoredBalance)) { - outputs.OrderedMap.ForEach(func(key, value interface{}) bool { - consumer(key.(Address), value.([]*ColoredBalance)) - - return true - }) -} - -func (outputs *Outputs) Bytes() []byte { - marshalUtil := marshalutil.New() - - if outputs == nil { - marshalUtil.WriteUint32(0) - - return marshalUtil.Bytes() - } - - marshalUtil.WriteUint32(uint32(outputs.Size())) - outputs.ForEach(func(address Address, balances []*ColoredBalance) { - marshalUtil.WriteBytes(address.ToBytes()) - marshalUtil.WriteUint32(uint32(len(balances))) - - for _, balance := range balances { - marshalUtil.WriteBytes(balance.ToBytes()) - } - }) - - return marshalUtil.Bytes() -} - -func (outputs *Outputs) String() string { - if outputs == nil { - return "<nil>" - } - - result := "[\n" - empty := true - outputs.ForEach(func(address Address, balances []*ColoredBalance) { - empty = false - - result += " " + address.String() + ": [\n" - - balancesEmpty := true - for _, balance := range balances { - balancesEmpty = false - - result += " " + balance.String() + ",\n" - } - - if balancesEmpty { - result += " <empty>\n" - } - - result += " ]\n" - }) - - if empty { - result += " <empty>\n" - } - - return result + "]" -} diff --git a/packages/binary/valuetransfers/payload.go b/packages/binary/valuetransfers/payload.go deleted file mode 100644 index f613b37d0997b46a27d144dab962bfdea9df7d39..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/payload.go +++ /dev/null @@ -1,186 +0,0 @@ -package valuetransfers - -import ( - "sync" - - "github.com/iotaledger/hive.go/objectstorage" - "golang.org/x/crypto/blake2b" - - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" - "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload" -) - -type Payload struct { - objectstorage.StorableObjectFlags - - id *PayloadId - trunkPayloadId PayloadId - branchPayloadId PayloadId - transfer *Transfer - bytes []byte - - idMutex sync.RWMutex - bytesMutex sync.RWMutex -} - -func NewPayload(trunkPayloadId, branchPayloadId PayloadId, valueTransfer *Transfer) *Payload { - return &Payload{ - trunkPayloadId: trunkPayloadId, - branchPayloadId: branchPayloadId, - transfer: valueTransfer, - } -} - -func (payload *Payload) GetId() PayloadId { - // acquire lock for reading id - payload.idMutex.RLock() - - // return if id has been calculated already - if payload.id != nil { - defer payload.idMutex.RUnlock() - - return *payload.id - } - - // switch to write lock - payload.idMutex.RUnlock() - payload.idMutex.Lock() - defer payload.idMutex.Unlock() - - // return if id has been calculated in the mean time - if payload.id != nil { - return *payload.id - } - - // otherwise calculate the id - transferId := payload.GetTransfer().GetId() - marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength) - marshalUtil.WriteBytes(payload.trunkPayloadId[:]) - marshalUtil.WriteBytes(payload.branchPayloadId[:]) - marshalUtil.WriteBytes(transferId[:]) - var id PayloadId = blake2b.Sum256(marshalUtil.Bytes()) - payload.id = &id - - return id -} - -func (payload *Payload) GetTrunkPayloadId() PayloadId { - return payload.trunkPayloadId -} - -func (payload *Payload) GetBranchPayloadId() PayloadId { - return payload.branchPayloadId -} - -func (payload *Payload) GetTransfer() *Transfer { - return payload.transfer -} - -// region Payload implementation /////////////////////////////////////////////////////////////////////////////////////// - -var Type = payload.Type(1) - -func (payload *Payload) GetType() payload.Type { - return Type -} - -func (payload *Payload) MarshalBinary() (bytes []byte, err error) { - // acquire lock for reading bytes - payload.bytesMutex.RLock() - - // return if bytes have been determined already - if bytes = payload.bytes; bytes != nil { - defer payload.bytesMutex.RUnlock() - - return - } - - // switch to write lock - payload.bytesMutex.RUnlock() - payload.bytesMutex.Lock() - defer payload.bytesMutex.Unlock() - - // return if bytes have been determined in the mean time - if bytes = payload.bytes; bytes != nil { - return - } - - // retrieve bytes of transfer - transferBytes, err := payload.GetTransfer().MarshalBinary() - if err != nil { - return - } - - // marshal fields - marshalUtil := marshalutil.New(PayloadIdLength + PayloadIdLength + TransferIdLength) - marshalUtil.WriteBytes(payload.trunkPayloadId[:]) - marshalUtil.WriteBytes(payload.branchPayloadId[:]) - marshalUtil.WriteBytes(transferBytes) - bytes = marshalUtil.Bytes() - - // store result - payload.bytes = bytes - - return -} - -func (payload *Payload) UnmarshalBinary(data []byte) (err error) { - marshalUtil := marshalutil.New(data) - - trunkTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength) - if err != nil { - return - } - - branchTransactionIdBytes, err := marshalUtil.ReadBytes(PayloadIdLength) - if err != nil { - return - } - - valueTransfer := &Transfer{} - if err = valueTransfer.UnmarshalBinary(marshalUtil.ReadRemainingBytes()); err != nil { - return - } - - payload.trunkPayloadId = NewPayloadId(trunkTransactionIdBytes) - payload.branchPayloadId = NewPayloadId(branchTransactionIdBytes) - payload.transfer = valueTransfer - payload.bytes = data - - return -} - -func init() { - payload.RegisterType(Type, func(data []byte) (payload payload.Payload, err error) { - payload = &Payload{} - err = payload.UnmarshalBinary(data) - - return - }) -} - -// define contract (ensure that the struct fulfills the corresponding interface) -var _ payload.Payload = &Payload{} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region StorableObject implementation //////////////////////////////////////////////////////////////////////////////// - -// MarshalBinary() (bytes []byte, err error) already implemented by Payload - -// UnmarshalBinary(data []byte) (err error) already implemented by Payload - -func (payload *Payload) GetStorageKey() []byte { - id := payload.GetId() - - return id[:] -} - -func (payload *Payload) Update(other objectstorage.StorableObject) { - panic("a Payload should never be updated") -} - -// define contract (ensure that the struct fulfills the corresponding interface) -var _ objectstorage.StorableObject = &Payload{} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/binary/valuetransfers/payload/payload.go b/packages/binary/valuetransfers/payload/payload.go index 7ffe6aa80aba954d494e9421fd2a6efd91ee0c4b..39430b2179a54e991c57a15d19883c112ff7f153 100644 --- a/packages/binary/valuetransfers/payload/payload.go +++ b/packages/binary/valuetransfers/payload/payload.go @@ -36,6 +36,8 @@ func New(trunkPayloadId, branchPayloadId payloadid.Id, valueTransfer *transfer.T } } +// 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, err error, consumedBytes int) { // determine the target object that will hold the unmarshaled information switch len(optionalTargetObject) { diff --git a/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go b/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go index dd86096b4b397c071219667255560d8dede40bc8..d36935b03eb1a87859a4733605b841b488c88dce 100644 --- a/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go +++ b/packages/binary/valuetransfers/payload/transfer/inputs/inputs.go @@ -3,10 +3,10 @@ package inputs import ( "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" "github.com/iotaledger/goshimmer/packages/binary/marshalutil" - "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id" transferid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id" - transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/output/id" + transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/transferoutput/id" ) type Inputs struct { diff --git a/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go b/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go index f89c40ec1c84d4e2c9d9e5cb9a364358ea860b7d..4c66d7ef0a0d2dceeb3d61000691b5bde1d9cb49 100644 --- a/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go +++ b/packages/binary/valuetransfers/payload/transfer/outputs/outputs.go @@ -3,8 +3,8 @@ package outputs import ( "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" "github.com/iotaledger/goshimmer/packages/binary/marshalutil" - address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address" - coloredbalance2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance" + address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address" + coloredbalance2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance" ) type Outputs struct { diff --git a/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go b/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go new file mode 100644 index 0000000000000000000000000000000000000000..87f18aacd027ce65b3eafd1b9e772e489e324e93 --- /dev/null +++ b/packages/binary/valuetransfers/payload/transfer/signatures/signatures.go @@ -0,0 +1,4 @@ +package signatures + +type Signatures struct { +} diff --git a/packages/binary/valuetransfers/payload/transfer/transfer.go b/packages/binary/valuetransfers/payload/transfer/transfer.go index af9357069a881b95434914e8acd395f4ce81b8e8..ab9f3bfafc6002412e26c95729c49a8cf970b398 100644 --- a/packages/binary/valuetransfers/payload/transfer/transfer.go +++ b/packages/binary/valuetransfers/payload/transfer/transfer.go @@ -10,9 +10,11 @@ import ( "golang.org/x/crypto/blake2b" "github.com/iotaledger/goshimmer/packages/binary/marshalutil" + "github.com/iotaledger/goshimmer/packages/binary/signature/ed25119" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/inputs" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/outputs" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/signatures" ) // region IMPLEMENT Transfer /////////////////////////////////////////////////////////////////////////////////////////// @@ -20,12 +22,20 @@ import ( type Transfer struct { objectstorage.StorableObjectFlags + inputs *inputs.Inputs + outputs *outputs.Outputs + signatures *signatures.Signatures + id *id.Id - inputs *inputs.Inputs - outputs *outputs.Outputs - bytes []byte + idMutex sync.RWMutex + + essenceBytes []byte + essenceBytesMutex sync.RWMutex + + signatureBytes []byte + signatureBytesMutex sync.RWMutex - idMutex sync.RWMutex + bytes []byte bytesMutex sync.RWMutex } @@ -73,7 +83,7 @@ func FromBytes(bytes []byte, optionalTargetObject ...*Transfer) (result *Transfe return } -func TransferFromStorage(key []byte) *Transfer { +func FromStorage(key []byte) *Transfer { id := id.New(key) return &Transfer{ @@ -148,6 +158,10 @@ func (transfer *Transfer) Bytes() []byte { return transfer.bytes } +func (transfer *Transfer) Sign(pair ed25119.KeyPair) { + //transfer.signatures[pair.PublicKey] = pair.PrivateKey.Sign(transfer.Bytes()) +} + func (transfer *Transfer) String() string { id := transfer.GetId() diff --git a/packages/binary/valuetransfers/payload_id.go b/packages/binary/valuetransfers/payload_id.go deleted file mode 100644 index c596cfb0a794c0857abe340005b3015ccc7cf3f8..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/payload_id.go +++ /dev/null @@ -1,21 +0,0 @@ -package valuetransfers - -import ( - "github.com/mr-tron/base58" -) - -type PayloadId [PayloadIdLength]byte - -func NewPayloadId(idBytes []byte) (result PayloadId) { - copy(result[:], idBytes) - - return -} - -func (id PayloadId) String() string { - return base58.Encode(id[:]) -} - -var EmptyPayloadId PayloadId - -const PayloadIdLength = 32 diff --git a/packages/binary/valuetransfers/test/payload_test.go b/packages/binary/valuetransfers/test/payload_test.go index e7b023f666b63e6b37b440d6313fd4ae2d715b7d..ae7cc819511c3d4d7a9ea140afdca86508d679ae 100644 --- a/packages/binary/valuetransfers/test/payload_test.go +++ b/packages/binary/valuetransfers/test/payload_test.go @@ -4,20 +4,70 @@ import ( "fmt" "testing" - "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload" + "github.com/iotaledger/goshimmer/packages/binary/identity" + "github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance" + "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/coloredbalance/color" + valuepayload "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload" payloadid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/id" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer" - "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address" - "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance" - "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/coloredbalance/color" transferid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/inputs" - transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/output/id" "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/outputs" + transferoutputid "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/transferoutput/id" ) +func ExamplePayload() { + // 1. create value transfer (user provides this) + valueTransfer := transfer.New( + // inputs + inputs.New( + transferoutputid.New(address.New([]byte("input_address1")), transferid.New([]byte("transfer1"))), + transferoutputid.New(address.New([]byte("input_address2")), transferid.New([]byte("transfer2"))), + ), + + // outputs + outputs.New(map[address.Address][]*coloredbalance.ColoredBalance{ + address.New([]byte("output_address")): { + coloredbalance.New(color.IOTA, 1337), + }, + }), + ) + + // 2. create value payload (the ontology creates this and wraps the user provided transfer accordingly) + valuePayload := valuepayload.New( + // trunk in "value transfer ontology" (filled by ontology tipSelector) + payloadid.Empty, + + // branch in "value transfer ontology" (filled by ontology tipSelector) + payloadid.Empty, + + // value transfer + valueTransfer, + ) + + // 3. build actual transaction (the base layer creates this and wraps the ontology provided payload) + tx := transaction.New( + // trunk in "network tangle" ontology (filled by tipSelector) + transaction.EmptyId, + + // branch in "network tangle" ontology (filled by tipSelector) + transaction.EmptyId, + + // issuer of the transaction (signs automatically) + identity.Generate(), + + // payload + valuePayload, + ) + + fmt.Println(tx) +} + func TestPayload(t *testing.T) { - originalPayload := payload.New( + + originalPayload := valuepayload.New( payloadid.Empty, payloadid.Empty, transfer.New( @@ -28,13 +78,13 @@ func TestPayload(t *testing.T) { outputs.New(map[address.Address][]*coloredbalance.ColoredBalance{ address.New([]byte("output_address")): { - coloredbalance.New(color.COLOR_IOTA, 1337), + coloredbalance.New(color.IOTA, 1337), }, }), ), ) - clonedPayload, err, _ := payload.FromBytes(originalPayload.Bytes()) + clonedPayload, err, _ := valuepayload.FromBytes(originalPayload.Bytes()) if err != nil { panic(err) } diff --git a/packages/binary/valuetransfers/transfer.go b/packages/binary/valuetransfers/transfer.go deleted file mode 100644 index 6cd4df8cd471c33a6101b6f27b5e991ce4e56bcf..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/transfer.go +++ /dev/null @@ -1,190 +0,0 @@ -package valuetransfers - -import ( - "fmt" - "sync" - - "github.com/iotaledger/hive.go/objectstorage" - "github.com/iotaledger/hive.go/stringify" - "github.com/mr-tron/base58" - "golang.org/x/crypto/blake2b" - - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" -) - -// region IMPLEMENT Transfer /////////////////////////////////////////////////////////////////////////////////////////// - -type Transfer struct { - objectstorage.StorableObjectFlags - - id *TransferId - inputs *TransferInputs - outputs *Outputs - bytes []byte - - idMutex sync.RWMutex - bytesMutex sync.RWMutex -} - -func NewTransfer(inputs *TransferInputs, outputs *Outputs) *Transfer { - return &Transfer{ - inputs: inputs, - outputs: outputs, - } -} - -func TransferFromBytes(bytes []byte, optionalTargetObject ...*Transfer) (result *Transfer, err error, consumedBytes int) { - // determine the target object that will hold the unmarshaled information - switch len(optionalTargetObject) { - case 0: - result = &Transfer{} - case 1: - result = optionalTargetObject[0] - default: - panic("too many arguments in call to OutputFromBytes") - } - - // initialize helper - marshalUtil := marshalutil.New(bytes) - - // unmarshal inputs - if parseResult, inputsErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return TransferInputsFromBytes(data) }); inputsErr != nil { - err = inputsErr - - return - } else { - result.inputs = parseResult.(*TransferInputs) - } - - // unmarshal outputs - if parseResult, outputsErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return OutputsFromBytes(data) }); outputsErr != nil { - err = outputsErr - - return - } else { - result.outputs = parseResult.(*Outputs) - } - - // return the number of bytes we processed - consumedBytes = marshalUtil.ReadOffset() - - // store bytes, so we don't have to marshal manually - result.bytes = bytes[:consumedBytes] - - return -} - -func TransferFromStorage(key []byte) *Transfer { - id := NewTransferId(key) - - return &Transfer{ - id: &id, - } -} - -func (transfer *Transfer) GetId() TransferId { - // acquire lock for reading id - transfer.idMutex.RLock() - - // return if id has been calculated already - if transfer.id != nil { - defer transfer.idMutex.RUnlock() - - return *transfer.id - } - - // switch to write lock - transfer.idMutex.RUnlock() - transfer.idMutex.Lock() - defer transfer.idMutex.Unlock() - - // return if id has been calculated in the mean time - if transfer.id != nil { - return *transfer.id - } - - // otherwise calculate the id - idBytes := blake2b.Sum256(transfer.Bytes()) - transferId := NewTransferId(idBytes[:]) - - // cache result for later calls - transfer.id = &transferId - - return transferId -} - -func (transfer *Transfer) Bytes() []byte { - // acquired read lock on bytes - transfer.bytesMutex.RLock() - - // return bytes if the object has been marshaled already - if transfer.bytes != nil { - defer transfer.bytesMutex.RUnlock() - - return transfer.bytes - } - - // switch to write lock - transfer.bytesMutex.RUnlock() - transfer.bytesMutex.Lock() - defer transfer.bytesMutex.Unlock() - - // return bytes if the object has been marshaled in the mean time - if bytes := transfer.bytes; bytes != nil { - return bytes - } - - // create marshal helper - marshalUtil := marshalutil.New() - - // marshal inputs - marshalUtil.WriteBytes(transfer.inputs.ToBytes()) - - // marshal outputs - marshalUtil.WriteBytes(transfer.outputs.Bytes()) - - // store marshaled result - transfer.bytes = marshalUtil.Bytes() - - return transfer.bytes -} - -func (transfer *Transfer) String() string { - id := transfer.GetId() - - return stringify.Struct("Transfer"+fmt.Sprintf("(%p)", transfer), - stringify.StructField("id", base58.Encode(id[:])), - stringify.StructField("inputs", transfer.inputs), - stringify.StructField("outputs", transfer.outputs), - ) -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// region IMPLEMENT StorableObject interface /////////////////////////////////////////////////////////////////////////// - -// define contract (ensure that the struct fulfills the given interface) -var _ objectstorage.StorableObject = &Transfer{} - -func (transfer *Transfer) GetStorageKey() []byte { - id := transfer.GetId() - - return id[:] -} - -func (transfer *Transfer) Update(other objectstorage.StorableObject) { - panic("update forbidden") -} - -// MarshalBinary returns a bytes representation of the transfer by implementing the encoding.BinaryMarshaler interface. -func (transfer *Transfer) MarshalBinary() ([]byte, error) { - return transfer.Bytes(), nil -} - -func (transfer *Transfer) UnmarshalBinary(bytes []byte) (err error) { - _, err, _ = TransferFromBytes(bytes, transfer) - - return -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/binary/valuetransfers/transfer_id.go b/packages/binary/valuetransfers/transfer_id.go deleted file mode 100644 index ed2c198b418a4041c5abb81f39ea9674366e7a48..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/transfer_id.go +++ /dev/null @@ -1,19 +0,0 @@ -package valuetransfers - -import ( - "github.com/mr-tron/base58" -) - -type TransferId [TransferIdLength]byte - -func NewTransferId(idBytes []byte) (result TransferId) { - copy(result[:], idBytes) - - return -} - -func (id TransferId) String() string { - return base58.Encode(id[:]) -} - -const TransferIdLength = 32 diff --git a/packages/binary/valuetransfers/transfer_inputs.go b/packages/binary/valuetransfers/transfer_inputs.go deleted file mode 100644 index aaffde448d5dcc3dcb5895000c18d064b90ac6ff..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/transfer_inputs.go +++ /dev/null @@ -1,132 +0,0 @@ -package valuetransfers - -import ( - "github.com/iotaledger/goshimmer/packages/binary/datastructure/orderedmap" - "github.com/iotaledger/goshimmer/packages/binary/marshalutil" -) - -type TransferInputs struct { - *orderedmap.OrderedMap -} - -func NewTransferInputs(transferOutputIds ...TransferOutputId) (inputs *TransferInputs) { - inputs = &TransferInputs{orderedmap.New()} - for _, transferOutputId := range transferOutputIds { - inputs.Add(transferOutputId) - } - - return -} - -func TransferInputsFromBytes(bytes []byte) (inputs *TransferInputs, err error, consumedBytes int) { - inputs = NewTransferInputs() - - marshalUtil := marshalutil.New(bytes) - inputCount, err := marshalUtil.ReadUint32() - if err != nil { - return - } - - for i := uint32(0); i < inputCount; i++ { - addressBytes, readErr := marshalUtil.ReadBytes(AddressLength) - if readErr != nil { - err = readErr - - return - } - address := NewAddress(addressBytes) - - transferIdBytes, readErr := marshalUtil.ReadBytes(TransferIdLength) - if readErr != nil { - err = readErr - - return - } - transferId := NewTransferId(transferIdBytes) - - addressMap, addressExists := inputs.Get(address) - if !addressExists { - addressMap = orderedmap.New() - - inputs.Set(address, addressMap) - } - addressMap.(*orderedmap.OrderedMap).Set(transferId, NewTransferOutputId(address, transferId)) - } - - consumedBytes = marshalUtil.ReadOffset() - - return -} - -func (inputs *TransferInputs) Add(input TransferOutputId) *TransferInputs { - address := input.GetAddress() - transferId := input.GetTransferId() - - addressMap, addressExists := inputs.Get(address) - if !addressExists { - addressMap = orderedmap.New() - - inputs.Set(address, addressMap) - } - - addressMap.(*orderedmap.OrderedMap).Set(transferId, input) - - return inputs -} - -func (inputs *TransferInputs) ToBytes() (bytes []byte) { - marshalUtil := marshalutil.New() - - marshalUtil.WriteSeek(4) - var inputCounter uint32 - inputs.ForEach(func(transferOutputId TransferOutputId) { - marshalUtil.WriteBytes(transferOutputId.ToBytes()) - - inputCounter++ - }) - marshalUtil.WriteSeek(0) - marshalUtil.WriteUint32(inputCounter) - - return marshalUtil.Bytes() -} - -func (inputs *TransferInputs) ForEach(consumer func(transferOutputId TransferOutputId)) { - inputs.OrderedMap.ForEach(func(key, value interface{}) bool { - value.(*orderedmap.OrderedMap).ForEach(func(key, value interface{}) bool { - consumer(value.(TransferOutputId)) - - return true - }) - - return true - }) -} - -func (inputs *TransferInputs) ForEachAddress(consumer func(address Address)) { - inputs.OrderedMap.ForEach(func(key, value interface{}) bool { - consumer(key.(Address)) - - return true - }) -} - -func (inputs *TransferInputs) String() string { - if inputs == nil { - return "<nil>" - } - - result := "[\n" - - empty := true - inputs.ForEach(func(transferOutputId TransferOutputId) { - empty = false - - result += " " + transferOutputId.String() + ",\n" - }) - - if empty { - result += " <empty>\n" - } - - return result + "]" -} diff --git a/packages/binary/valuetransfers/payload/transfer/output/id/id.go b/packages/binary/valuetransfers/transferoutput/id/id.go similarity index 96% rename from packages/binary/valuetransfers/payload/transfer/output/id/id.go rename to packages/binary/valuetransfers/transferoutput/id/id.go index 159dd3d9d7ee0913bbbd8661ce2338e98072cab8..0d2c7e95c96aecb91d501886442760366d31ce69 100644 --- a/packages/binary/valuetransfers/payload/transfer/output/id/id.go +++ b/packages/binary/valuetransfers/transferoutput/id/id.go @@ -3,7 +3,7 @@ package id import ( "github.com/mr-tron/base58" - address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/address" + address2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/address" id2 "github.com/iotaledger/goshimmer/packages/binary/valuetransfers/payload/transfer/id" ) diff --git a/packages/binary/valuetransfers/transferoutput_id.go b/packages/binary/valuetransfers/transferoutput_id.go deleted file mode 100644 index cbb9c76d619888179404ac28e82a5e2ce592d635..0000000000000000000000000000000000000000 --- a/packages/binary/valuetransfers/transferoutput_id.go +++ /dev/null @@ -1,38 +0,0 @@ -package valuetransfers - -import ( - "github.com/mr-tron/base58" -) - -type TransferOutputId [TransferOutputIdLength]byte - -func NewTransferOutputId(address Address, transferId TransferId) (transferOutputId TransferOutputId) { - copy(transferOutputId[:AddressLength], address.ToBytes()) - copy(transferOutputId[AddressLength:], transferId[:]) - - return -} - -func TransferOutputIdFromBytes(bytes []byte) (transferOutputId TransferOutputId) { - copy(transferOutputId[:], bytes) - - return -} - -func (transferOutputId TransferOutputId) GetAddress() Address { - return NewAddress(transferOutputId[:AddressLength]) -} - -func (transferOutputId TransferOutputId) GetTransferId() TransferId { - return NewTransferId(transferOutputId[AddressLength:]) -} - -func (transferOutputId TransferOutputId) ToBytes() []byte { - return transferOutputId[:] -} - -func (transferOutputId TransferOutputId) String() string { - return "TransferOutputId(" + base58.Encode(transferOutputId[:]) + ")" -} - -const TransferOutputIdLength = AddressLength + TransferIdLength