From e4f4c6ffb15be692f65ce08d943a7f6b33463e79 Mon Sep 17 00:00:00 2001 From: Hans Moog <hm@mkjc.net> Date: Wed, 18 Dec 2019 19:10:39 +0100 Subject: [PATCH] Feat: added approvers model for the tangle --- packages/binary/approvers/approvers.go | 111 ++++++++++++++++++++++ packages/binary/approvers/types.go | 5 + packages/binary/identity/identity.go | 4 +- packages/binary/identity/identity_test.go | 3 - packages/binary/identity/type.go | 4 +- packages/binary/tangle/tangle.go | 9 ++ 6 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 packages/binary/approvers/approvers.go create mode 100644 packages/binary/approvers/types.go diff --git a/packages/binary/approvers/approvers.go b/packages/binary/approvers/approvers.go new file mode 100644 index 00000000..f9ba5afe --- /dev/null +++ b/packages/binary/approvers/approvers.go @@ -0,0 +1,111 @@ +package approvers + +import ( + "sync" + + "github.com/iotaledger/goshimmer/packages/binary/transaction" + "github.com/iotaledger/hive.go/objectstorage" +) + +type Approvers struct { + objectstorage.StorableObjectFlags + + transactionId transaction.Id + approvers map[transaction.Id]empty + approversMutex sync.RWMutex +} + +func New(transactionId transaction.Id) *Approvers { + return &Approvers{ + transactionId: transactionId, + approvers: make(map[transaction.Id]empty), + } +} + +// Get's called when we restore the approvers from storage. The bytes and the content will be unmarshaled by an external +// caller (the objectStorage factory). +func FromStorage(id []byte) (result *Approvers) { + var transactionId transaction.Id + copy(transactionId[:], id) + + result = &Approvers{ + transactionId: transactionId, + } + + return +} + +func (approvers *Approvers) GetTransactionId() transaction.Id { + return approvers.transactionId +} + +func (approvers *Approvers) Get() (result map[transaction.Id]empty) { + approvers.approversMutex.RLock() + result = make(map[transaction.Id]empty, len(approvers.approvers)) + for approverId := range approvers.approvers { + result[approverId] = void + } + approvers.approversMutex.RUnlock() + + return +} + +func (approvers *Approvers) Add(transactionId transaction.Id) (modified bool) { + approvers.approversMutex.RLock() + if _, exists := approvers.approvers[transactionId]; !exists { + approvers.approversMutex.RUnlock() + + approvers.approversMutex.Lock() + if _, exists := approvers.approvers[transactionId]; !exists { + approvers.approvers[transactionId] = void + + modified = true + + approvers.SetModified() + } + approvers.approversMutex.Unlock() + } else { + approvers.approversMutex.RUnlock() + } + + return +} + +func (approvers *Approvers) Remove(transactionId transaction.Id) (modified bool) { + approvers.approversMutex.RLock() + if _, exists := approvers.approvers[transactionId]; exists { + approvers.approversMutex.RUnlock() + + approvers.approversMutex.Lock() + if _, exists := approvers.approvers[transactionId]; exists { + delete(approvers.approvers, transactionId) + + modified = true + + approvers.SetModified() + } + approvers.approversMutex.Unlock() + } else { + approvers.approversMutex.RUnlock() + } + + return +} + +func (approvers *Approvers) GetStorageKey() []byte { + transactionId := approvers.GetTransactionId() + + return transactionId[:] +} + +func (approvers *Approvers) Update(other objectstorage.StorableObject) { + panic("approvers should never be overwritten and only stored once to optimize IO") +} + +func (approvers *Approvers) MarshalBinary() (result []byte, err error) { + return +} + +func (approvers *Approvers) UnmarshalBinary(data []byte) (err error) { + return +} diff --git a/packages/binary/approvers/types.go b/packages/binary/approvers/types.go new file mode 100644 index 00000000..99c78a42 --- /dev/null +++ b/packages/binary/approvers/types.go @@ -0,0 +1,5 @@ +package approvers + +type empty struct{} + +var void empty diff --git a/packages/binary/identity/identity.go b/packages/binary/identity/identity.go index 8cf7ce3a..fd52c6f3 100644 --- a/packages/binary/identity/identity.go +++ b/packages/binary/identity/identity.go @@ -20,9 +20,9 @@ func New(publicKey []byte, optionalPrivateKey ...[]byte) *Identity { copy(this.PublicKey, publicKey) if len(optionalPrivateKey) == 0 { - this.Type = PUBLIC_TYPE + this.Type = Public } else { - this.Type = PRIVATE_TYPE + this.Type = Private this.PrivateKey = optionalPrivateKey[0] } diff --git a/packages/binary/identity/identity_test.go b/packages/binary/identity/identity_test.go index f53ed760..f5fc0d52 100644 --- a/packages/binary/identity/identity_test.go +++ b/packages/binary/identity/identity_test.go @@ -1,7 +1,6 @@ package identity import ( - "fmt" "sync" "testing" @@ -37,8 +36,6 @@ func Test(t *testing.T) { signature := identity.Sign([]byte("TESTDATA1")) - fmt.Println(len(signature)) - assert.Equal(t, true, identity.VerifySignature([]byte("TESTDATA1"), signature)) assert.Equal(t, false, identity.VerifySignature([]byte("TESTDATA2"), signature)) } diff --git a/packages/binary/identity/type.go b/packages/binary/identity/type.go index f89c4769..cc207b02 100644 --- a/packages/binary/identity/type.go +++ b/packages/binary/identity/type.go @@ -3,6 +3,6 @@ package identity type Type int const ( - PRIVATE_TYPE = Type(0) - PUBLIC_TYPE = Type(1) + Private = Type(0) + Public = Type(1) ) diff --git a/packages/binary/tangle/tangle.go b/packages/binary/tangle/tangle.go index 2d6210fc..1b4bbd41 100644 --- a/packages/binary/tangle/tangle.go +++ b/packages/binary/tangle/tangle.go @@ -1,17 +1,20 @@ package tangle import ( + "github.com/iotaledger/goshimmer/packages/binary/approvers" "github.com/iotaledger/goshimmer/packages/binary/transaction" "github.com/iotaledger/hive.go/objectstorage" ) type Tangle struct { transactionStorage *objectstorage.ObjectStorage + approversStorage *objectstorage.ObjectStorage } func New(storageId string) *Tangle { return &Tangle{ transactionStorage: objectstorage.New(storageId+"TANGLE_TRANSACTION_STORAGE", transactionFactory), + approversStorage: objectstorage.New(storageId+"TANGLE_APPROVERS_STORAGE", approversFactory), } } @@ -20,3 +23,9 @@ func transactionFactory(key []byte) objectstorage.StorableObject { return result } + +func approversFactory(key []byte) objectstorage.StorableObject { + result := approvers.FromStorage(key) + + return result +} -- GitLab