diff --git a/go.mod b/go.mod index bbe4a07eade49b1b9dda5c04e1e2d3e919beafdb..f0c5e1ebb725e9622202e8376b15c69a77f0da3d 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/googollee/go-engine.io v1.4.3-0.20190924125625-798118fc0dd2 github.com/googollee/go-socket.io v1.4.3-0.20191204093753-683f8725b6d0 github.com/gorilla/websocket v1.4.1 - github.com/iotaledger/hive.go v0.0.0-20200328153852-4d06dcf6bf29 + github.com/iotaledger/hive.go v0.0.0-20200330121034-e4a505bcf2cd github.com/iotaledger/iota.go v1.0.0-beta.14 github.com/labstack/echo v3.3.10+incompatible github.com/labstack/gommon v0.3.0 // indirect diff --git a/go.sum b/go.sum index 06874594975f900add465032d03412e5b4bb0618..4faabd5a7c4372c60275144650b70deefcbbfe06 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,7 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -130,8 +131,10 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/iotaledger/hive.go v0.0.0-20200328153852-4d06dcf6bf29 h1:rKw/dp9FnM15e4lzEYwcpxX1lHE0Q06XeIgPskzF9vA= -github.com/iotaledger/hive.go v0.0.0-20200328153852-4d06dcf6bf29/go.mod h1:4sloxRutRhCuXgAgtOu1ZxVM95Na+ovK9MRDEQGZlzw= +github.com/iotaledger/hive.go v0.0.0-20200329235804-a34899d73dc0 h1:15y1xve54VKQbtt27BYBTsPeGsUQ0vqg96AtS7lRLss= +github.com/iotaledger/hive.go v0.0.0-20200329235804-a34899d73dc0/go.mod h1:4sloxRutRhCuXgAgtOu1ZxVM95Na+ovK9MRDEQGZlzw= +github.com/iotaledger/hive.go v0.0.0-20200330121034-e4a505bcf2cd h1:GZ9zGBj+tK1jHqTD5+OoPLVVlk/sB2pkKmQt9vjR8uY= +github.com/iotaledger/hive.go v0.0.0-20200330121034-e4a505bcf2cd/go.mod h1:LYUD1U+BxF+OY6zCZ4xp38vzjp/QWbUdCw9iwmxkGnc= github.com/iotaledger/iota.go v1.0.0-beta.9/go.mod h1:F6WBmYd98mVjAmmPVYhnxg8NNIWCjjH8VWT9qvv3Rc8= github.com/iotaledger/iota.go v1.0.0-beta.14 h1:Oeb28MfBuJEeXcGrLhTCJFtbsnc8y1u7xidsAmiOD5A= github.com/iotaledger/iota.go v1.0.0-beta.14/go.mod h1:F6WBmYd98mVjAmmPVYhnxg8NNIWCjjH8VWT9qvv3Rc8= @@ -184,6 +187,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e h1:85L+lUTJHx4O7UP9y/65XV8iq7oaA2Uqe5WiUSB8XE4= +github.com/oasislabs/ed25519 v0.0.0-20200302143042-29f6767a7c3e/go.mod h1:xIpCyrK2ouGA4QBGbiNbkoONrvJ00u9P3QOkXSOAC0c= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= diff --git a/packages/binary/messagelayer/message/message.go b/packages/binary/messagelayer/message/message.go index 87f0fc8b1a8ceb32c3c061d5c830f2dd2098f7bf..9794eab520407bc6bdc7257cf66cf4caefdc8ed1 100644 --- a/packages/binary/messagelayer/message/message.go +++ b/packages/binary/messagelayer/message/message.go @@ -9,7 +9,6 @@ import ( "github.com/iotaledger/hive.go/marshalutil" "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/messagelayer/payload" @@ -22,16 +21,16 @@ type Message struct { objectstorage.StorableObjectFlags // core properties (they are part of the transaction when being sent) - trunkTransactionId Id - branchTransactionId Id - issuerPublicKey ed25519.PublicKey - issuingTime time.Time - sequenceNumber uint64 - payload payload.Payload - bytes []byte - bytesMutex sync.RWMutex - signature ed25519.Signature - signatureMutex sync.RWMutex + trunkId Id + branchId Id + issuerPublicKey ed25519.PublicKey + issuingTime time.Time + sequenceNumber uint64 + payload payload.Payload + bytes []byte + bytesMutex sync.RWMutex + signature ed25519.Signature + signatureMutex sync.RWMutex // derived properties id *Id @@ -44,14 +43,14 @@ type Message struct { } // New creates a new transaction with the details provided by the issuer. -func New(trunkTransactionId Id, branchTransactionId Id, issuerPublicKey ed25519.PublicKey, issuingTime time.Time, sequenceNumber uint64, payload payload.Payload, localIdentity *identity.LocalIdentity) (result *Message) { +func New(trunkTransactionId Id, branchTransactionId Id, localIdentity *identity.LocalIdentity, issuingTime time.Time, sequenceNumber uint64, payload payload.Payload) (result *Message) { return &Message{ - trunkTransactionId: trunkTransactionId, - branchTransactionId: branchTransactionId, - issuerPublicKey: issuerPublicKey, - issuingTime: issuingTime, - sequenceNumber: sequenceNumber, - payload: payload, + trunkId: trunkTransactionId, + branchId: branchTransactionId, + issuerPublicKey: localIdentity.PublicKey(), + issuingTime: issuingTime, + sequenceNumber: sequenceNumber, + payload: payload, issuerLocalIdentity: localIdentity, } @@ -76,15 +75,6 @@ func Parse(marshalUtil *marshalutil.MarshalUtil, optionalTargetObject ...*Messag panic("too many arguments in call to Parse") } - if parsedObject, parseErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { - return StorableObjectFromKey(data) - }); parseErr != nil { - err = parseErr - - return - } else { - result = parsedObject.(*Message) - } if _, err = marshalUtil.Parse(func(data []byte) (parseResult interface{}, parseErr error, parsedBytes int) { parseErr, parsedBytes = result.UnmarshalObjectStorageValue(data) @@ -110,170 +100,188 @@ func StorableObjectFromKey(key []byte, optionalTargetObject ...*Message) (result } marshalUtil := marshalutil.New(key) - *result.(*Message).id, err = ParseId(marshalUtil) - if err != nil { + if id, idErr := ParseId(marshalUtil); idErr != nil { + err = idErr + return + } else { + result.(*Message).id = &id } consumedBytes = marshalUtil.ReadOffset() return } -func (transaction *Message) VerifySignature() (result bool) { - transactionBytes := transaction.Bytes() +func (message *Message) VerifySignature() (result bool) { + transactionBytes := message.Bytes() - transaction.signatureMutex.RLock() - result = transaction.issuerPublicKey.VerifySignature(transactionBytes[:len(transactionBytes)-ed25519.SignatureSize], transaction.signature) - transaction.signatureMutex.RUnlock() + message.signatureMutex.RLock() + result = message.issuerPublicKey.VerifySignature(transactionBytes[:len(transactionBytes)-ed25519.SignatureSize], message.Signature()) + message.signatureMutex.RUnlock() return } -func (transaction *Message) GetId() (result Id) { - transaction.idMutex.RLock() - if transaction.id == nil { - transaction.idMutex.RUnlock() +func (message *Message) Id() (result Id) { + message.idMutex.RLock() + if message.id == nil { + message.idMutex.RUnlock() - transaction.idMutex.Lock() - if transaction.id == nil { - result = transaction.calculateTransactionId() + message.idMutex.Lock() + if message.id == nil { + result = message.calculateId() - transaction.id = &result + message.id = &result } else { - result = *transaction.id + result = *message.id } - transaction.idMutex.Unlock() + message.idMutex.Unlock() } else { - result = *transaction.id + result = *message.id - transaction.idMutex.RUnlock() + message.idMutex.RUnlock() } return } -func (transaction *Message) GetTrunkTransactionId() Id { - return transaction.trunkTransactionId +func (message *Message) TrunkId() Id { + return message.trunkId } -func (transaction *Message) GetBranchTransactionId() Id { - return transaction.branchTransactionId +func (message *Message) BranchId() Id { + return message.branchId +} + +func (message *Message) IssuerPublicKey() ed25519.PublicKey { + return message.issuerPublicKey } // IssuingTime returns the time when the transaction was created. -func (transaction *Message) IssuingTime() time.Time { - return transaction.issuingTime +func (message *Message) IssuingTime() time.Time { + return message.issuingTime } // SequenceNumber returns the sequence number of this transaction. -func (transaction *Message) SequenceNumber() uint64 { - return transaction.sequenceNumber +func (message *Message) SequenceNumber() uint64 { + return message.sequenceNumber +} + +func (message *Message) Signature() ed25519.Signature { + message.signatureMutex.RLock() + defer message.signatureMutex.RUnlock() + + if message.signature == ed25519.EmptySignature { + // unlock the signatureMutex so Bytes() can write the Signature + message.signatureMutex.RUnlock() + message.Bytes() + message.signatureMutex.RLock() + } + + return message.signature } -func (transaction *Message) GetPayload() payload.Payload { - return transaction.payload +func (message *Message) Payload() payload.Payload { + return message.payload } -func (transaction *Message) GetPayloadId() (result payload.Id) { - transaction.payloadIdMutex.RLock() - if transaction.payloadId == nil { - transaction.payloadIdMutex.RUnlock() +func (message *Message) PayloadId() (result payload.Id) { + message.payloadIdMutex.RLock() + if message.payloadId == nil { + message.payloadIdMutex.RUnlock() - transaction.payloadIdMutex.Lock() - if transaction.payloadId == nil { - result = transaction.calculatePayloadId() + message.payloadIdMutex.Lock() + if message.payloadId == nil { + result = message.calculatePayloadId() - transaction.payloadId = &result + message.payloadId = &result } else { - result = *transaction.payloadId + result = *message.payloadId } - transaction.payloadIdMutex.Unlock() + message.payloadIdMutex.Unlock() } else { - result = *transaction.payloadId + result = *message.payloadId - transaction.payloadIdMutex.RUnlock() + message.payloadIdMutex.RUnlock() } return } -func (transaction *Message) calculateTransactionId() Id { - payloadId := transaction.GetPayloadId() - - hashBase := make([]byte, IdLength+IdLength+payload.IdLength) - offset := 0 - - copy(hashBase[offset:], transaction.trunkTransactionId[:]) - offset += IdLength - - copy(hashBase[offset:], transaction.branchTransactionId[:]) - offset += IdLength - - copy(hashBase[offset:], payloadId[:]) - // offset += payloadIdLength - - return blake2b.Sum512(hashBase) +func (message *Message) calculateId() Id { + return blake2b.Sum512( + marshalutil.New(IdLength + IdLength + payload.IdLength). + WriteBytes(message.trunkId.Bytes()). + WriteBytes(message.branchId.Bytes()). + WriteBytes(message.PayloadId().Bytes()). + Bytes(), + ) } -func (transaction *Message) calculatePayloadId() payload.Id { - bytes := transaction.Bytes() - - return blake2b.Sum512(bytes[2*IdLength:]) +func (message *Message) calculatePayloadId() payload.Id { + return blake2b.Sum512(message.Bytes()[2*IdLength:]) } -func (transaction *Message) Bytes() []byte { - transaction.bytesMutex.RLock() - if transaction.bytes != nil { - defer transaction.bytesMutex.RUnlock() +func (message *Message) Bytes() []byte { + message.bytesMutex.RLock() + if message.bytes != nil { + defer message.bytesMutex.RUnlock() - return transaction.bytes + return message.bytes } - transaction.bytesMutex.RUnlock() - transaction.bytesMutex.RLock() - defer transaction.bytesMutex.RUnlock() + message.bytesMutex.RUnlock() + message.bytesMutex.RLock() + defer message.bytesMutex.RUnlock() - if transaction.bytes != nil { - return transaction.bytes + if message.bytes != nil { + return message.bytes } // marshal result marshalUtil := marshalutil.New() - marshalUtil.WriteBytes(transaction.trunkTransactionId.Bytes()) - marshalUtil.WriteBytes(transaction.branchTransactionId.Bytes()) - marshalUtil.WriteBytes(transaction.issuerPublicKey.Bytes()) - marshalUtil.WriteTime(transaction.issuingTime) - marshalUtil.WriteUint64(transaction.sequenceNumber) - marshalUtil.WriteBytes(transaction.payload.Bytes()) - marshalUtil.WriteBytes(transaction.issuerLocalIdentity.Sign(marshalUtil.Bytes()).Bytes()) - - return marshalUtil.Bytes() + marshalUtil.WriteBytes(message.trunkId.Bytes()) + marshalUtil.WriteBytes(message.branchId.Bytes()) + marshalUtil.WriteBytes(message.issuerPublicKey.Bytes()) + marshalUtil.WriteTime(message.issuingTime) + marshalUtil.WriteUint64(message.sequenceNumber) + marshalUtil.WriteBytes(message.payload.Bytes()) + + message.signatureMutex.Lock() + message.signature = message.issuerLocalIdentity.Sign(marshalUtil.Bytes()) + message.signatureMutex.Unlock() + + marshalUtil.WriteBytes(message.signature.Bytes()) + + message.bytes = marshalUtil.Bytes() + + return message.bytes } -func (transaction *Message) UnmarshalObjectStorageValue(data []byte) (err error, consumedBytes int) { +func (message *Message) UnmarshalObjectStorageValue(data []byte) (err error, consumedBytes int) { // initialize helper marshalUtil := marshalutil.New(data) // parse information - if transaction.trunkTransactionId, err = ParseId(marshalUtil); err != nil { + if message.trunkId, err = ParseId(marshalUtil); err != nil { return } - if transaction.branchTransactionId, err = ParseId(marshalUtil); err != nil { + if message.branchId, err = ParseId(marshalUtil); err != nil { return } - if transaction.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil { + if message.issuerPublicKey, err = ed25519.ParsePublicKey(marshalUtil); err != nil { return } - if transaction.issuingTime, err = marshalUtil.ReadTime(); err != nil { + if message.issuingTime, err = marshalUtil.ReadTime(); err != nil { return } - if transaction.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil { + if message.sequenceNumber, err = marshalUtil.ReadUint64(); err != nil { return } - if transaction.payload, err = payload.Parse(marshalUtil); err != nil { + if message.payload, err = payload.Parse(marshalUtil); err != nil { return } - if transaction.signature, err = ed25519.ParseSignature(marshalUtil); err != nil { + if message.signature, err = ed25519.ParseSignature(marshalUtil); err != nil { return } @@ -281,33 +289,35 @@ func (transaction *Message) UnmarshalObjectStorageValue(data []byte) (err error, consumedBytes = marshalUtil.ReadOffset() // store marshaled version - transaction.bytes = make([]byte, consumedBytes) - copy(transaction.bytes, data) + message.bytes = make([]byte, consumedBytes) + copy(message.bytes, data) return } -func (transaction *Message) ObjectStorageKey() []byte { - return transaction.GetId().Bytes() +func (message *Message) ObjectStorageKey() []byte { + return message.Id().Bytes() } // Since transactions are immutable and do not get changed after being created, we cache the result of the marshaling. -func (transaction *Message) ObjectStorageValue() []byte { - return transaction.Bytes() +func (message *Message) ObjectStorageValue() []byte { + return message.Bytes() } -func (transaction *Message) Update(other objectstorage.StorableObject) { +func (message *Message) Update(other objectstorage.StorableObject) { panic("transactions should never be overwritten and only stored once to optimize IO") } -func (transaction *Message) String() string { - transactionId := transaction.GetId() - +func (message *Message) String() string { return stringify.Struct("Message", - 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), + stringify.StructField("id", message.Id()), + stringify.StructField("trunkMessageId", message.TrunkId()), + stringify.StructField("branchMessageId", message.BranchId()), + stringify.StructField("issuer", message.IssuerPublicKey()), + stringify.StructField("issuingTime", message.IssuingTime()), + stringify.StructField("sequenceNumber", message.SequenceNumber()), + stringify.StructField("payload", message.Payload()), + stringify.StructField("signature", message.Signature()), ) } diff --git a/packages/binary/messagelayer/messagefactory/messagefactory.go b/packages/binary/messagelayer/messagefactory/messagefactory.go index 25529c4607622de53b424f5689c8242e174c807a..faf720b76b788b1a98b2338235ee917b68e127b6 100644 --- a/packages/binary/messagelayer/messagefactory/messagefactory.go +++ b/packages/binary/messagelayer/messagefactory/messagefactory.go @@ -51,11 +51,10 @@ func (m *MessageFactory) IssuePayload(payload payload.Payload) *message.Message tx := message.New( trunkTransaction, branchTransaction, - m.localIdentity.PublicKey(), + m.localIdentity, time.Now(), sequenceNumber, payload, - m.localIdentity, ) m.Events.MessageConstructed.Trigger(tx) diff --git a/packages/binary/messagelayer/messagefactory/messagefactory_test.go b/packages/binary/messagelayer/messagefactory/messagefactory_test.go index 8e2d3cbe13f2056edb0a154057f1a991323f4b97..5c8466cceefd5c60196d49a400e445dc3acecae4 100644 --- a/packages/binary/messagelayer/messagefactory/messagefactory_test.go +++ b/packages/binary/messagelayer/messagefactory/messagefactory_test.go @@ -54,15 +54,15 @@ func TestMessageFactory_BuildMessage(t *testing.T) { var p payload.Payload = NewMockPayload(data) msg := msgFactory.IssuePayload(p) - assert.NotNil(t, msg.GetTrunkTransactionId()) - assert.NotNil(t, msg.GetBranchTransactionId()) + assert.NotNil(t, msg.TrunkId()) + assert.NotNil(t, msg.BranchId()) // time in range of 0.1 seconds assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000) // check payload - assert.Same(t, p, msg.GetPayload()) - assert.Equal(t, data, msg.GetPayload().Bytes()) + assert.Same(t, p, msg.Payload()) + assert.Equal(t, data, msg.Payload().Bytes()) // check total events and sequence number assert.EqualValues(t, 1, countEvents) @@ -80,15 +80,15 @@ func TestMessageFactory_BuildMessage(t *testing.T) { var p payload.Payload = NewMockPayload(data) msg := msgFactory.IssuePayload(p) - assert.NotNil(t, msg.GetTrunkTransactionId()) - assert.NotNil(t, msg.GetBranchTransactionId()) + assert.NotNil(t, msg.TrunkId()) + assert.NotNil(t, msg.BranchId()) // time in range of 0.1 seconds assert.InDelta(t, time.Now().UnixNano(), msg.IssuingTime().UnixNano(), 100000000) // check payload - assert.Same(t, p, msg.GetPayload()) - assert.Equal(t, data, msg.GetPayload().Bytes()) + assert.Same(t, p, msg.Payload()) + assert.Equal(t, data, msg.Payload().Bytes()) sequenceNumbers.Store(msg.SequenceNumber(), true) }) diff --git a/packages/binary/messagelayer/payload/id.go b/packages/binary/messagelayer/payload/id.go index a20ce75f2b069a4299bf70a633deafd1c41c2f93..fd2cb205b6e0475860b38542b12daf290b923bf2 100644 --- a/packages/binary/messagelayer/payload/id.go +++ b/packages/binary/messagelayer/payload/id.go @@ -1,5 +1,15 @@ package payload +import "github.com/mr-tron/base58" + type Id [IdLength]byte +func (id Id) Bytes() []byte { + return id[:] +} + +func (id Id) String() string { + return base58.Encode(id[:]) +} + const IdLength = 64 diff --git a/packages/binary/messagelayer/tangle/tangle.go b/packages/binary/messagelayer/tangle/tangle.go index 8dc9477f6362012cd685baff7b7a497be17dd234..be3877532e711d6184a91f87b0fd53e702a59783 100644 --- a/packages/binary/messagelayer/tangle/tangle.go +++ b/packages/binary/messagelayer/tangle/tangle.go @@ -98,10 +98,10 @@ func (tangle *Tangle) Approvers(transactionId message.Id) CachedApprovers { // Deletes a transaction from the tangle (i.e. for local snapshots) func (tangle *Tangle) DeleteMessage(messageId message.Id) { tangle.Message(messageId).Consume(func(currentTransaction *message.Message) { - trunkTransactionId := currentTransaction.GetTrunkTransactionId() + trunkTransactionId := currentTransaction.TrunkId() tangle.deleteApprover(trunkTransactionId, messageId) - branchTransactionId := currentTransaction.GetBranchTransactionId() + branchTransactionId := currentTransaction.BranchId() if branchTransactionId != trunkTransactionId { tangle.deleteApprover(branchTransactionId, messageId) } @@ -154,15 +154,15 @@ func (tangle *Tangle) storeMessageWorker(tx *message.Message) { } // store transaction metadata - transactionId := tx.GetId() + transactionId := tx.Id() cachedTransactionMetadata := &CachedMessageMetadata{CachedObject: tangle.messageMetadataStorage.Store(NewMessageMetadata(transactionId))} // store trunk approver - trunkTransactionID := tx.GetTrunkTransactionId() + trunkTransactionID := tx.TrunkId() tangle.approverStorage.Store(NewApprover(trunkTransactionID, transactionId)).Release() // store branch approver - if branchTransactionID := tx.GetBranchTransactionId(); branchTransactionID != trunkTransactionID { + if branchTransactionID := tx.BranchId(); branchTransactionID != trunkTransactionID { tangle.approverStorage.Store(NewApprover(branchTransactionID, transactionId)).Release() } @@ -220,7 +220,7 @@ func (tangle *Tangle) solidifyMessageWorker(cachedTransaction *message.CachedMes return true } - return isTransactionMarkedAsSolid(transaction.GetTrunkTransactionId()) && isTransactionMarkedAsSolid(transaction.GetBranchTransactionId()) + return isTransactionMarkedAsSolid(transaction.TrunkId()) && isTransactionMarkedAsSolid(transaction.BranchId()) } popElementsFromStack := func(stack *list.List) (*message.CachedMessage, *CachedMessageMetadata) { @@ -253,7 +253,7 @@ func (tangle *Tangle) solidifyMessageWorker(cachedTransaction *message.CachedMes if isTransactionSolid(currentTransaction, currentTransactionMetadata) && currentTransactionMetadata.SetSolid(true) { tangle.Events.TransactionSolid.Trigger(currentCachedTransaction, currentCachedTransactionMetadata) - tangle.Approvers(currentTransaction.GetId()).Consume(func(approver *Approver) { + tangle.Approvers(currentTransaction.Id()).Consume(func(approver *Approver) { approverTransactionId := approver.ReferencedMessageId() solidificationStack.PushBack([2]interface{}{ diff --git a/packages/binary/messagelayer/tangle/tangle_test.go b/packages/binary/messagelayer/tangle/tangle_test.go index b8ca052137454bd9c5c11d3d0f0b2c9295e793db..e16243a2ee94f022bc0bbec17791eddbc41022f6 100644 --- a/packages/binary/messagelayer/tangle/tangle_test.go +++ b/packages/binary/messagelayer/tangle/tangle_test.go @@ -35,7 +35,7 @@ func BenchmarkTangle_AttachTransaction(b *testing.B) { transactionBytes := make([]*message.Message, b.N) for i := 0; i < b.N; i++ { - transactionBytes[i] = message.New(message.EmptyId, message.EmptyId, testIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("some data")), testIdentity) + transactionBytes[i] = message.New(message.EmptyId, message.EmptyId, testIdentity, time.Now(), 0, payload.NewData([]byte("some data"))) transactionBytes[i].Bytes() } @@ -66,7 +66,7 @@ func TestTangle_AttachTransaction(t *testing.T) { cachedTransactionMetadata.Release() cachedTransaction.Consume(func(transaction *message.Message) { - fmt.Println("ATTACHED:", transaction.GetId()) + fmt.Println("ATTACHED:", transaction.Id()) }) })) @@ -74,7 +74,7 @@ func TestTangle_AttachTransaction(t *testing.T) { cachedTransactionMetadata.Release() cachedTransaction.Consume(func(transaction *message.Message) { - fmt.Println("SOLID:", transaction.GetId()) + fmt.Println("SOLID:", transaction.Id()) }) })) @@ -92,8 +92,8 @@ func TestTangle_AttachTransaction(t *testing.T) { localIdentity1 := identity.GenerateLocalIdentity() localIdentity2 := identity.GenerateLocalIdentity() - newTransaction1 := message.New(message.EmptyId, message.EmptyId, localIdentity1.PublicKey(), time.Now(), 0, payload.NewData([]byte("some data")), localIdentity1) - newTransaction2 := message.New(newTransaction1.GetId(), newTransaction1.GetId(), localIdentity2.PublicKey(), time.Now(), 0, payload.NewData([]byte("some other data")), localIdentity2) + newTransaction1 := message.New(message.EmptyId, message.EmptyId, localIdentity1, time.Now(), 0, payload.NewData([]byte("some data"))) + newTransaction2 := message.New(newTransaction1.Id(), newTransaction1.Id(), localIdentity2, time.Now(), 0, payload.NewData([]byte("some other data"))) messageTangle.AttachMessage(newTransaction2) diff --git a/packages/binary/messagelayer/test/message_test.go b/packages/binary/messagelayer/test/message_test.go new file mode 100644 index 0000000000000000000000000000000000000000..13e65502e8945b90cf729a4d35e3e30567c2ecd8 --- /dev/null +++ b/packages/binary/messagelayer/test/message_test.go @@ -0,0 +1,47 @@ +package test + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/message" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/payload" + "github.com/iotaledger/goshimmer/packages/binary/testutil" +) + +func TestMessage_StorableObjectFromKey(t *testing.T) { + key, err := message.NewId("2DYebCqnZ8PS5PyXBEvAvLB1fCF77Rn9RtofNHjEb2pSTujKi889d31FmguAs5DgL7YURw4GP2Y28JdJ7K4bjudG") + if err != nil { + panic(err) + } + + messageFromKey, err, consumedBytes := 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_MarshalUnmarshal(t *testing.T) { + testMessage := testutil.MessageFactory(t).IssuePayload(payload.NewData([]byte("sth"))) + assert.Equal(t, true, testMessage.VerifySignature()) + + fmt.Print(testMessage) + + restoredMessage, err, _ := message.FromBytes(testMessage.Bytes()) + if assert.NoError(t, err, err) { + assert.Equal(t, testMessage.Id(), restoredMessage.Id()) + assert.Equal(t, testMessage.TrunkId(), restoredMessage.TrunkId()) + assert.Equal(t, testMessage.BranchId(), restoredMessage.BranchId()) + assert.Equal(t, testMessage.IssuerPublicKey(), restoredMessage.IssuerPublicKey()) + assert.Equal(t, testMessage.IssuingTime().Round(time.Second), restoredMessage.IssuingTime().Round(time.Second)) + assert.Equal(t, testMessage.SequenceNumber(), restoredMessage.SequenceNumber()) + assert.Equal(t, testMessage.Signature(), restoredMessage.Signature()) + assert.Equal(t, true, restoredMessage.VerifySignature()) + } +} diff --git a/packages/binary/messagelayer/test/transaction_test.go b/packages/binary/messagelayer/test/transaction_test.go index 9153245835a19fc56fbc11ebf2887efb17d27791..10b361bd132376534014f48bc22aecd2f681f6f3 100644 --- a/packages/binary/messagelayer/test/transaction_test.go +++ b/packages/binary/messagelayer/test/transaction_test.go @@ -23,7 +23,7 @@ func BenchmarkVerifyDataTransactions(b *testing.B) { transactions := make([][]byte, b.N) for i := 0; i < b.N; i++ { - tx := message.New(message.EmptyId, message.EmptyId, localIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("some data")), localIdentity) + tx := message.New(message.EmptyId, message.EmptyId, localIdentity, time.Now(), 0, payload.NewData([]byte("some data"))) transactions[i] = tx.Bytes() } @@ -51,7 +51,7 @@ func BenchmarkVerifySignature(b *testing.B) { transactions := make([]*message.Message, b.N) for i := 0; i < b.N; i++ { - transactions[i] = message.New(message.EmptyId, message.EmptyId, localIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("test")), localIdentity) + transactions[i] = message.New(message.EmptyId, message.EmptyId, localIdentity, time.Now(), 0, payload.NewData([]byte("test"))) transactions[i].Bytes() } diff --git a/packages/binary/messagelayer/tipselector/tipselector.go b/packages/binary/messagelayer/tipselector/tipselector.go index 84e447d8661d165f0a0b390937e44ae9274d65fe..8f6b768a7d94a603a19d05b0d9a9bee06bd1f037 100644 --- a/packages/binary/messagelayer/tipselector/tipselector.go +++ b/packages/binary/messagelayer/tipselector/tipselector.go @@ -23,17 +23,17 @@ func New() *TipSelector { } func (tipSelector *TipSelector) AddTip(transaction *message.Message) { - transactionId := transaction.GetId() + transactionId := transaction.Id() if tipSelector.tips.Set(transactionId, transactionId) { tipSelector.Events.TipAdded.Trigger(transactionId) } - trunkTransactionId := transaction.GetTrunkTransactionId() + trunkTransactionId := transaction.TrunkId() if _, deleted := tipSelector.tips.Delete(trunkTransactionId); deleted { tipSelector.Events.TipRemoved.Trigger(trunkTransactionId) } - branchTransactionId := transaction.GetBranchTransactionId() + branchTransactionId := transaction.BranchId() if _, deleted := tipSelector.tips.Delete(branchTransactionId); deleted { tipSelector.Events.TipRemoved.Trigger(branchTransactionId) } diff --git a/packages/binary/messagelayer/tipselector/tipselector_test.go b/packages/binary/messagelayer/tipselector/tipselector_test.go index 929d515c4555b5f08c4b5bf713f13f64292cdcde..8c50e9e6a1120afd91e174fc8edc8742aec888b6 100644 --- a/packages/binary/messagelayer/tipselector/tipselector_test.go +++ b/packages/binary/messagelayer/tipselector/tipselector_test.go @@ -22,7 +22,7 @@ func Test(t *testing.T) { // create a transaction and attach it localIdentity1 := identity.GenerateLocalIdentity() - transaction1 := message.New(trunk1, branch1, localIdentity1.PublicKey(), time.Now(), 0, payload.NewData([]byte("testtransaction")), localIdentity1) + transaction1 := message.New(trunk1, branch1, localIdentity1, time.Now(), 0, payload.NewData([]byte("testtransaction"))) tipSelector.AddTip(transaction1) // check if the tip shows up in the tip count @@ -30,12 +30,12 @@ func Test(t *testing.T) { // check if next tips point to our first transaction trunk2, branch2 := tipSelector.GetTips() - assert.Equal(t, transaction1.GetId(), trunk2) - assert.Equal(t, transaction1.GetId(), branch2) + assert.Equal(t, transaction1.Id(), trunk2) + assert.Equal(t, transaction1.Id(), branch2) // create a 2nd transaction and attach it localIdentity2 := identity.GenerateLocalIdentity() - transaction2 := message.New(message.EmptyId, message.EmptyId, localIdentity2.PublicKey(), time.Now(), 0, payload.NewData([]byte("testtransaction")), localIdentity2) + transaction2 := message.New(message.EmptyId, message.EmptyId, localIdentity2, time.Now(), 0, payload.NewData([]byte("testtransaction"))) tipSelector.AddTip(transaction2) // check if the tip shows up in the tip count @@ -44,12 +44,12 @@ func Test(t *testing.T) { // attach a transaction to our two tips localIdentity3 := identity.GenerateLocalIdentity() trunk3, branch3 := tipSelector.GetTips() - transaction3 := message.New(trunk3, branch3, localIdentity3.PublicKey(), time.Now(), 0, payload.NewData([]byte("testtransaction")), localIdentity3) + transaction3 := message.New(trunk3, branch3, localIdentity3, time.Now(), 0, payload.NewData([]byte("testtransaction"))) tipSelector.AddTip(transaction3) // check if the tip shows replaces the current tips trunk4, branch4 := tipSelector.GetTips() assert.Equal(t, 1, tipSelector.GetTipCount()) - assert.Equal(t, transaction3.GetId(), trunk4) - assert.Equal(t, transaction3.GetId(), branch4) + assert.Equal(t, transaction3.Id(), trunk4) + assert.Equal(t, transaction3.Id(), branch4) } diff --git a/packages/binary/messagelayer/transactionparser/transactionparser_test.go b/packages/binary/messagelayer/transactionparser/transactionparser_test.go index b1493d5cc7690d8ffe121873d352f268f84722e0..82666ea85dde4c3622d71840c070d6623bdf1caa 100644 --- a/packages/binary/messagelayer/transactionparser/transactionparser_test.go +++ b/packages/binary/messagelayer/transactionparser/transactionparser_test.go @@ -15,7 +15,7 @@ import ( func BenchmarkTransactionParser_ParseBytesSame(b *testing.B) { localIdentity := identity.GenerateLocalIdentity() - txBytes := message.New(message.EmptyId, message.EmptyId, localIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("Test")), localIdentity).Bytes() + txBytes := message.New(message.EmptyId, message.EmptyId, localIdentity, time.Now(), 0, payload.NewData([]byte("Test"))).Bytes() txParser := New() b.ResetTimer() @@ -31,7 +31,7 @@ func BenchmarkTransactionParser_ParseBytesDifferent(b *testing.B) { transactionBytes := make([][]byte, b.N) localIdentity := identity.GenerateLocalIdentity() for i := 0; i < b.N; i++ { - transactionBytes[i] = message.New(message.EmptyId, message.EmptyId, localIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("Test"+strconv.Itoa(i))), localIdentity).Bytes() + transactionBytes[i] = message.New(message.EmptyId, message.EmptyId, localIdentity, time.Now(), 0, payload.NewData([]byte("Test"+strconv.Itoa(i)))).Bytes() } txParser := New() @@ -47,7 +47,7 @@ func BenchmarkTransactionParser_ParseBytesDifferent(b *testing.B) { func TestTransactionParser_ParseTransaction(t *testing.T) { localIdentity := identity.GenerateLocalIdentity() - tx := message.New(message.EmptyId, message.EmptyId, localIdentity.PublicKey(), time.Now(), 0, payload.NewData([]byte("Test")), localIdentity) + tx := message.New(message.EmptyId, message.EmptyId, localIdentity, time.Now(), 0, payload.NewData([]byte("Test"))) txParser := New() txParser.Parse(tx.Bytes(), nil) diff --git a/packages/binary/testutil/db.go b/packages/binary/testutil/db.go new file mode 100644 index 0000000000000000000000000000000000000000..554512a166a0ba332163debe51fb1fd14829ec30 --- /dev/null +++ b/packages/binary/testutil/db.go @@ -0,0 +1,36 @@ +package testutil + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/dgraph-io/badger/v2" + "github.com/stretchr/testify/require" + + "github.com/iotaledger/goshimmer/packages/database" + "github.com/iotaledger/goshimmer/plugins/config" +) + +var dbInstance *badger.DB + +func DB(t *testing.T) *badger.DB { + if dbInstance == nil { + // Set up DB for testing + dir, err := ioutil.TempDir("", t.Name()) + require.NoError(t, err) + + t.Cleanup(func() { + os.Remove(dir) + + dbInstance = nil + }) + + // use the tempdir for the database + config.Node.Set(database.CFG_DIRECTORY, dir) + + dbInstance = database.GetBadgerInstance() + } + + return dbInstance +} diff --git a/packages/binary/testutil/messagefactory.go b/packages/binary/testutil/messagefactory.go new file mode 100644 index 0000000000000000000000000000000000000000..093ee86934a36ed3a2264e82dc505e4d42c03e9a --- /dev/null +++ b/packages/binary/testutil/messagefactory.go @@ -0,0 +1,29 @@ +package testutil + +import ( + "testing" + + "github.com/iotaledger/hive.go/identity" + + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagefactory" + "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tipselector" +) + +const sequenceKey = "seq" + +var messageFactoryInstance *messagefactory.MessageFactory + +func MessageFactory(t *testing.T) *messagefactory.MessageFactory { + if messageFactoryInstance == nil { + localIdentity := identity.GenerateLocalIdentity() + tipSelector := tipselector.New() + + t.Cleanup(func() { + messageFactoryInstance = nil + }) + + messageFactoryInstance = messagefactory.New(DB(t), localIdentity, tipSelector, []byte(sequenceKey)) + } + + return messageFactoryInstance +} diff --git a/packages/binary/valuetransfer/payload/payload_test.go b/packages/binary/valuetransfer/payload/payload_test.go index 46d445cfe6b5fd2552488404263d85b1cfdd8857..f13f8c89a76ceb105fd3ffe546a6e96aa229d095 100644 --- a/packages/binary/valuetransfer/payload/payload_test.go +++ b/packages/binary/valuetransfer/payload/payload_test.go @@ -55,7 +55,7 @@ func ExamplePayload() { message.EmptyId, // issuer of the transaction (signs automatically) - localIdentity.PublicKey(), + localIdentity, // the time when the transaction was created time.Now(), @@ -65,8 +65,6 @@ func ExamplePayload() { // payload valuePayload, - - localIdentity, ) fmt.Println(tx) diff --git a/plugins/messagelayer/plugin.go b/plugins/messagelayer/plugin.go index d9faebe1c6859d2622ab2e8fd4fb59ee06e72d81..1957f750d66ee2a73200b2381542fb2dc10a25d8 100644 --- a/plugins/messagelayer/plugin.go +++ b/plugins/messagelayer/plugin.go @@ -68,7 +68,7 @@ func configure(*node.Plugin) { cachedTransactionMetadata.Release() cachedTransaction.Consume(func(transaction *message.Message) { - TransactionRequester.StopRequest(transaction.GetId()) + TransactionRequester.StopRequest(transaction.Id()) }) })) diff --git a/plugins/spa/explorer_routes.go b/plugins/spa/explorer_routes.go index e42e3f2673e1969f7de4fad4c461d727f200a9c9..7d4c3a4c4931b58c0ea44644a12b3399e427f351 100644 --- a/plugins/spa/explorer_routes.go +++ b/plugins/spa/explorer_routes.go @@ -24,7 +24,7 @@ type ExplorerTx struct { } func createExplorerTx(tx *message.Message) (*ExplorerTx, error) { - transactionId := tx.GetId() + transactionId := tx.Id() txMetadata := messagelayer.Tangle.MessageMetadata(transactionId) @@ -34,8 +34,8 @@ func createExplorerTx(tx *message.Message) (*ExplorerTx, error) { Address: "", Timestamp: 0, Value: 0, - Trunk: tx.GetTrunkTransactionId().String(), - Branch: tx.GetBranchTransactionId().String(), + Trunk: tx.TrunkId().String(), + Branch: tx.BranchId().String(), Solid: txMetadata.Unwrap().IsSolid(), } diff --git a/plugins/spa/livefeed.go b/plugins/spa/livefeed.go index 34851c6f03a583705c3cb6bd82e4fd12ea444a65..a9405a0176901baabd490b604e9b283d9acb646c 100644 --- a/plugins/spa/livefeed.go +++ b/plugins/spa/livefeed.go @@ -20,7 +20,7 @@ var liveFeedWorkerPool *workerpool.WorkerPool func configureLiveFeed() { liveFeedWorkerPool = workerpool.New(func(task workerpool.Task) { task.Param(0).(*message.CachedMessage).Consume(func(transaction *message.Message) { - sendToAllWSClient(&msg{MsgTypeTx, &tx{transaction.GetId().String(), 0}}) + sendToAllWSClient(&msg{MsgTypeTx, &tx{transaction.Id().String(), 0}}) }) task.Return(nil) diff --git a/plugins/webapi/broadcastData/plugin.go b/plugins/webapi/broadcastData/plugin.go index c0cb7a5042e0461bbbca47cb1e47b67bef7b3191..5b854be601f187a57d74a302a6b0fad5b737d1af 100644 --- a/plugins/webapi/broadcastData/plugin.go +++ b/plugins/webapi/broadcastData/plugin.go @@ -30,7 +30,7 @@ func broadcastData(c echo.Context) error { tx := messagelayer.MessageFactory.IssuePayload(payload.NewData([]byte(request.Data))) - return c.JSON(http.StatusOK, Response{Hash: tx.GetId().String()}) + return c.JSON(http.StatusOK, Response{Hash: tx.Id().String()}) } type Response struct {