diff --git a/packages/binary/transaction/data_payload.go b/packages/binary/transaction/data_payload.go new file mode 100644 index 0000000000000000000000000000000000000000..4b0de177444ea8ddb6344465383203938f520b80 --- /dev/null +++ b/packages/binary/transaction/data_payload.go @@ -0,0 +1,48 @@ +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 + } +} diff --git a/packages/binary/transaction/payload.go b/packages/binary/transaction/payload.go index 13cb0d6160cf0cc45163fc70ff4f60c30bcc4884..be68f2d9487e626f4b6deeacd5357e96a4a032a0 100644 --- a/packages/binary/transaction/payload.go +++ b/packages/binary/transaction/payload.go @@ -8,5 +8,5 @@ type Payload interface { encoding.BinaryMarshaler encoding.BinaryUnmarshaler - GetType() int + GetType() PayloadType } diff --git a/packages/binary/transaction/payload_type.go b/packages/binary/transaction/payload_type.go new file mode 100644 index 0000000000000000000000000000000000000000..23d4ca12ad28a451d6dd7b1ef0a802a606b88da1 --- /dev/null +++ b/packages/binary/transaction/payload_type.go @@ -0,0 +1,3 @@ +package transaction + +type PayloadType = uint32 diff --git a/packages/binary/transaction/payload_type_register.go b/packages/binary/transaction/payload_type_register.go new file mode 100644 index 0000000000000000000000000000000000000000..5dcb24ab5565c5514db820f6451328e2bc194e68 --- /dev/null +++ b/packages/binary/transaction/payload_type_register.go @@ -0,0 +1,31 @@ +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) + } +} diff --git a/packages/binary/transaction/transaction.go b/packages/binary/transaction/transaction.go index a5b24d8db40f222d9db297794b20056cf74ce137..f3e4f4fb7b1f09954bd5ce49622ae5919b255eeb 100644 --- a/packages/binary/transaction/transaction.go +++ b/packages/binary/transaction/transaction.go @@ -1,6 +1,7 @@ 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 diff --git a/packages/binary/transaction/transaction_test.go b/packages/binary/transaction/transaction_test.go index e2082701357893ba3ce4d153c1fd2abdd7a995d5..8d930a050c95557315d540cc54088cc783cc99e8 100644 --- a/packages/binary/transaction/transaction_test.go +++ b/packages/binary/transaction/transaction_test.go @@ -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())