Skip to content
Snippets Groups Projects
Commit 6917bc13 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: transactions support generic payload

parent e4f4c6ff
No related branches found
No related tags found
No related merge requests found
package transaction
type DataPayload struct {
payloadType PayloadType
data []byte
}
var DataPayloadType = PayloadType(0)
func NewDataPayload(data []byte) *DataPayload {
return &DataPayload{
payloadType: DataPayloadType,
data: data,
}
}
func (dataPayload *DataPayload) GetType() PayloadType {
return dataPayload.payloadType
}
func (dataPayload *DataPayload) GetData() []byte {
return dataPayload.data
}
func (dataPayload *DataPayload) UnmarshalBinary(data []byte) error {
dataPayload.data = make([]byte, len(data))
copy(dataPayload.data, data)
return nil
}
func (dataPayload *DataPayload) MarshalBinary() (data []byte, err error) {
data = make([]byte, len(dataPayload.data))
copy(data, dataPayload.data)
return
}
func createGenericDataPayloadUnmarshaler(payloadType PayloadType) PayloadUnmarshaler {
return func(data []byte) (payload Payload, err error) {
payload = &DataPayload{
payloadType: payloadType,
}
err = payload.UnmarshalBinary(data)
return
}
}
......@@ -8,5 +8,5 @@ type Payload interface {
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
GetType() int
GetType() PayloadType
}
package transaction
type PayloadType = uint32
package transaction
import (
"sync"
)
type PayloadUnmarshaler func(data []byte) (Payload, error)
var (
payloadTypeRegister map[PayloadType]PayloadUnmarshaler
payloadTypeRegisterMutex sync.RWMutex
)
func RegisterPayloadType(payloadType PayloadType, unmarshaler PayloadUnmarshaler) {
payloadTypeRegisterMutex.Lock()
payloadTypeRegister[payloadType] = unmarshaler
payloadTypeRegisterMutex.Unlock()
}
func GetPayloadUnmarshaler(payloadType PayloadType) PayloadUnmarshaler {
payloadTypeRegisterMutex.RLock()
if unmarshaler, exists := payloadTypeRegister[payloadType]; exists {
payloadTypeRegisterMutex.RUnlock()
return unmarshaler
} else {
payloadTypeRegisterMutex.RUnlock()
return createGenericDataPayloadUnmarshaler(payloadType)
}
}
package transaction
import (
"encoding/binary"
"sync"
"github.com/iotaledger/goshimmer/packages/binary/identity"
......@@ -22,16 +23,16 @@ type Transaction struct {
branchTransactionId Id
issuer *identity.Identity
payload Payload
bytes []byte
bytesMutex sync.RWMutex
signature [identity.SignatureSize]byte
signatureMutex sync.RWMutex
// derived properties
id *Id
idMutex sync.RWMutex
payloadId *PayloadId
payloadIdMutex sync.RWMutex
bytes []byte
bytesMutex sync.RWMutex
signature [identity.SignatureSize]byte
signatureMutex sync.RWMutex
}
// Allows us to "issue" a transaction.
......@@ -97,6 +98,10 @@ func (transaction *Transaction) GetId() (result Id) {
return
}
func (transaction *Transaction) GetPayload() Payload {
return transaction.payload
}
func (transaction *Transaction) GetPayloadId() (result PayloadId) {
transaction.payloadIdMutex.RLock()
if transaction.payloadId == nil {
......@@ -168,7 +173,7 @@ func (transaction *Transaction) MarshalBinary() (result []byte, err error) {
}
serializedPayloadLength := len(serializedPayload)
result = make([]byte, transactionIdLength+transactionIdLength+identity.PublicKeySize+serializedPayloadLength+identity.SignatureSize)
result = make([]byte, transactionIdLength+transactionIdLength+identity.PublicKeySize+4+serializedPayloadLength+identity.SignatureSize)
offset := 0
copy(result[offset:], transaction.trunkTransactionId[:])
......@@ -180,7 +185,8 @@ func (transaction *Transaction) MarshalBinary() (result []byte, err error) {
copy(result[offset:], transaction.issuer.PublicKey)
offset += identity.PublicKeySize
// TODO: MARSHAL PAYLOAD LENGTH
binary.LittleEndian.PutUint32(result[offset:], transaction.payload.GetType())
offset += 4
if serializedPayloadLength != 0 {
copy(result[offset:], serializedPayload)
......@@ -219,7 +225,13 @@ func (transaction *Transaction) UnmarshalBinary(data []byte) (err error) {
transaction.issuer = identity.New(data[offset : offset+identity.PublicKeySize])
offset += identity.PublicKeySize
// TODO: UNMARSHAL PAYLOAD LENGTH + CONTENT
payloadType := binary.LittleEndian.Uint32(data[offset:])
offset += 4
if transaction.payload, err = GetPayloadUnmarshaler(payloadType)(data[offset : len(data)-identity.SignatureSize]); err != nil {
return
}
offset += len(data) - identity.SignatureSize - offset
copy(transaction.signature[:], data[offset:])
// offset += identity.SignatureSize
......
......@@ -10,10 +10,10 @@ import (
)
func TestNew(t *testing.T) {
newTransaction1 := New(Id{}, Id{}, identity.Generate(), nil)
newTransaction1 := New(Id{}, Id{}, identity.Generate(), NewDataPayload([]byte("test")))
assert.Equal(t, newTransaction1.VerifySignature(), true)
newTransaction2 := New(newTransaction1.GetId(), Id{}, identity.Generate(), nil)
newTransaction2 := New(newTransaction1.GetId(), Id{}, identity.Generate(), NewDataPayload([]byte("test1")))
assert.Equal(t, newTransaction2.VerifySignature(), true)
newTransaction3, _ := FromBytes(newTransaction2.GetBytes())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment