From ba6b873bc58433e161b9eac10b0076d918cbc5c6 Mon Sep 17 00:00:00 2001 From: Hans Moog <3293976+hmoog@users.noreply.github.com> Date: Wed, 6 Apr 2022 10:49:44 +0200 Subject: [PATCH] Refactor: refactored some code --- packages/ledger/branchdag/branchdag.go | 4 ++++ packages/ledger/branchdag/events.go | 7 +++++++ packages/ledger/branchdag/models.go | 11 +++++++++++ packages/ledger/branchdag/options.go | 22 +++++----------------- packages/ledger/branchdag/storage.go | 21 +++++++-------------- packages/ledger/branchdag/types.go | 20 +++++++++++--------- packages/ledger/branchdag/utils.go | 1 + packages/ledger/utxo/interfaces.go | 6 ------ packages/ledger/vm/vm.go | 3 --- 9 files changed, 46 insertions(+), 49 deletions(-) diff --git a/packages/ledger/branchdag/branchdag.go b/packages/ledger/branchdag/branchdag.go index 764486c2dc..e46c5f46de 100644 --- a/packages/ledger/branchdag/branchdag.go +++ b/packages/ledger/branchdag/branchdag.go @@ -12,12 +12,16 @@ import ( type BranchDAG struct { // Events is a dictionary for BranchDAG related events. Events *Events + // Storage is a dictionary for storage related API endpoints. Storage *Storage + // Utils is a dictionary for utility methods that simplify the interaction with the BranchDAG. Utils *Utils + // options is a dictionary for configuration parameters of the BranchDAG. options *options + // inclusionStateMutex is a mutex that prevents that two processes simultaneously write the InclusionState. inclusionStateMutex sync.RWMutex } diff --git a/packages/ledger/branchdag/events.go b/packages/ledger/branchdag/events.go index 448dd45957..a21c01e30c 100644 --- a/packages/ledger/branchdag/events.go +++ b/packages/ledger/branchdag/events.go @@ -10,8 +10,10 @@ import ( type Events struct { // BranchCreated is an event that gets triggered whenever a new Branch is created. BranchCreated *event.Event[*BranchCreatedEvent] + // BranchConflictsUpdated is an event that gets triggered whenever the ConflictIDs of a Branch are updated. BranchConflictsUpdated *event.Event[*BranchConflictsUpdatedEvent] + // BranchParentsUpdated is an event that gets triggered whenever the parent BranchIDs of a Branch are updated. BranchParentsUpdated *event.Event[*BranchParentsUpdatedEvent] } @@ -33,8 +35,10 @@ func newEvents() *Events { type BranchCreatedEvent struct { // BranchID contains the identifier of the newly created Branch. BranchID BranchID + // ParentBranchIDs contains the parent Branches of the newly created Branch. ParentBranchIDs BranchIDs + // ConflictIDs contains the set of conflicts that this Branch is involved with. ConflictIDs ConflictIDs } @@ -48,6 +52,7 @@ type BranchCreatedEvent struct { type BranchConflictsUpdatedEvent struct { // BranchID contains the identifier of the updated Branch. BranchID BranchID + // NewConflictIDs contains the set of conflicts that this Branch was added to. NewConflictIDs ConflictIDs } @@ -61,8 +66,10 @@ type BranchConflictsUpdatedEvent struct { type BranchParentsUpdatedEvent struct { // BranchID contains the identifier of the updated Branch. BranchID BranchID + // AddedBranch contains the forked parent Branch that replaces the removed parents. AddedBranch BranchID + // RemovedBranches contains the parent BranchIDs that were replaced by the newly forked Branch. RemovedBranches BranchIDs } diff --git a/packages/ledger/branchdag/models.go b/packages/ledger/branchdag/models.go index 1626d739da..6198c91d87 100644 --- a/packages/ledger/branchdag/models.go +++ b/packages/ledger/branchdag/models.go @@ -16,18 +16,25 @@ import ( type Branch struct { // id contains the identifier of the Branch. id BranchID + // parents contains the parent BranchIDs that this Branch depends on. parents BranchIDs + // parentsMutex contains a mutex that is used to synchronize parallel access to the parents. parentsMutex sync.RWMutex + // conflictIDs contains the identifiers of the conflicts that this Branch is part of. conflictIDs ConflictIDs + // conflictIDsMutex contains a mutex that is used to synchronize parallel access to the conflictIDs. conflictIDsMutex sync.RWMutex + // inclusionState contains the InclusionState of the Branch. inclusionState InclusionState + // inclusionStateMutex contains a mutex that is used to synchronize parallel access to the inclusionState. inclusionStateMutex sync.RWMutex + // StorableObjectFlags embeds the properties and methods required to manage to object storage related flags. objectstorage.StorableObjectFlags } @@ -192,8 +199,10 @@ var _ objectstorage.StorableObject = new(Branch) type ChildBranch struct { // parentBranchID contains the identifier of the parent Branch. parentBranchID BranchID + // childBranchID contains the identifier of the child Branch. childBranchID BranchID + // StorableObjectFlags embeds the properties and methods required to manage to object storage related flags. objectstorage.StorableObjectFlags } @@ -291,8 +300,10 @@ var childBranchKeyPartition = objectstorage.PartitionKey(BranchIDLength, BranchI type ConflictMember struct { // conflictID contains the identifier of the conflict. conflictID ConflictID + // branchID contains the identifier of the Branch. branchID BranchID + // StorableObjectFlags embeds the properties and methods required to manage to object storage related flags. objectstorage.StorableObjectFlags } diff --git a/packages/ledger/branchdag/options.go b/packages/ledger/branchdag/options.go index c5646f4537..a899b9e2be 100644 --- a/packages/ledger/branchdag/options.go +++ b/packages/ledger/branchdag/options.go @@ -57,18 +57,6 @@ func WithChildBranchCacheTime(childBranchCacheTime time.Duration) Option { // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// -// region WithConflictCacheTime //////////////////////////////////////////////////////////////////////////////////////// - -// WithConflictCacheTime is an Option for the BranchDAG that allows to configure how long Conflict objects stay cached -// after they have been released. -func WithConflictCacheTime(conflictCacheTime time.Duration) Option { - return func(options *options) { - options.conflictCacheTime = conflictCacheTime - } -} - -// endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// - // region WithConflictMemberCacheTime ////////////////////////////////////////////////////////////////////////////////// // WithConflictMemberCacheTime is an Option for the BranchDAG that allows to configure how long ConflictMember objects @@ -83,8 +71,7 @@ func WithConflictMemberCacheTime(conflictMemberCacheTime time.Duration) Option { // region Option /////////////////////////////////////////////////////////////////////////////////////////////////////// -// Option represents the return type of optional parameters that can be handed into the constructor of the BranchDAG to -// configure its behavior. +// Option represents a configurable parameter for the BranchDAG that modifies its behavior. type Option func(*options) // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -95,14 +82,16 @@ type Option func(*options) type options struct { // store contains the KVStore that is used to persist data. store kvstore.KVStore + // cacheTimeProvider contains the CacheTimeProvider that overrides the local cache times. cacheTimeProvider *database.CacheTimeProvider + // branchCacheTime contains the duration that Branch objects stay cached after they have been released. branchCacheTime time.Duration + // childBranchCacheTime contains the duration that ChildBranch objects stay cached after they have been released. childBranchCacheTime time.Duration - // conflictCacheTime contains the duration that Conflict objects stay cached after they have been released. - conflictCacheTime time.Duration + // conflictMemberCacheTime contains the duration that ConflictMember objects stay cached after they have been // released. conflictMemberCacheTime time.Duration @@ -116,7 +105,6 @@ func newOptions(option ...Option) (new *options) { cacheTimeProvider: database.NewCacheTimeProvider(0), branchCacheTime: 60 * time.Second, childBranchCacheTime: 60 * time.Second, - conflictCacheTime: 60 * time.Second, conflictMemberCacheTime: 10 * time.Second, }).apply(option...) } diff --git a/packages/ledger/branchdag/storage.go b/packages/ledger/branchdag/storage.go index 1bb53ce975..dfe432a329 100644 --- a/packages/ledger/branchdag/storage.go +++ b/packages/ledger/branchdag/storage.go @@ -2,7 +2,6 @@ package branchdag import ( "sync" - "time" "github.com/cockroachdb/errors" "github.com/iotaledger/hive.go/byteutils" @@ -18,10 +17,13 @@ import ( type Storage struct { // branchStorage is an object storage used to persist Branch objects. branchStorage *objectstorage.ObjectStorage[*Branch] + // childBranchStorage is an object storage used to persist ChildBranch objects. childBranchStorage *objectstorage.ObjectStorage[*ChildBranch] + // conflictMemberStorage is an object storage used to persist ConflictMember objects. conflictMemberStorage *objectstorage.ObjectStorage[*ConflictMember] + // shutdownOnce is used to ensure that the shutdown routine is executed only a single time. shutdownOnce sync.Once } @@ -32,29 +34,20 @@ func newStorage(options *options) (new *Storage) { branchStorage: objectstorage.New[*Branch]( options.store.WithRealm([]byte{database.PrefixBranchDAG, PrefixBranchStorage}), options.cacheTimeProvider.CacheTime(options.branchCacheTime), - objectstorage.LeakDetectionEnabled(true, objectstorage.LeakDetectionOptions{ - MaxConsumersPerObject: 10, - MaxConsumerHoldTime: 5 * time.Second, - }), + objectstorage.LeakDetectionEnabled(false), ), childBranchStorage: objectstorage.New[*ChildBranch]( options.store.WithRealm([]byte{database.PrefixBranchDAG, PrefixChildBranchStorage}), childBranchKeyPartition, options.cacheTimeProvider.CacheTime(options.childBranchCacheTime), - objectstorage.LeakDetectionEnabled(true, objectstorage.LeakDetectionOptions{ - MaxConsumersPerObject: 10, - MaxConsumerHoldTime: 5 * time.Second, - }), + objectstorage.LeakDetectionEnabled(false), objectstorage.StoreOnCreation(true), ), conflictMemberStorage: objectstorage.New[*ConflictMember]( options.store.WithRealm([]byte{database.PrefixBranchDAG, PrefixConflictMemberStorage}), conflictMemberKeyPartition, - options.cacheTimeProvider.CacheTime(options.conflictCacheTime), - objectstorage.LeakDetectionEnabled(true, objectstorage.LeakDetectionOptions{ - MaxConsumersPerObject: 10, - MaxConsumerHoldTime: 5 * time.Second, - }), + options.cacheTimeProvider.CacheTime(options.conflictMemberCacheTime), + objectstorage.LeakDetectionEnabled(false), objectstorage.StoreOnCreation(true), ), } diff --git a/packages/ledger/branchdag/types.go b/packages/ledger/branchdag/types.go index 6671f38e2b..11c3f64b91 100644 --- a/packages/ledger/branchdag/types.go +++ b/packages/ledger/branchdag/types.go @@ -201,15 +201,6 @@ func NewConflictIDs(ids ...ConflictID) (new ConflictIDs) { // InclusionState represents the confirmation status of branches in the BranchDAG. type InclusionState uint8 -const ( - // Pending represents elements that have neither been confirmed nor rejected. - Pending InclusionState = iota - // Confirmed represents elements that have been confirmed and will stay part of the ledger state forever. - Confirmed - // Rejected represents elements that have been rejected and will not be included in the ledger state. - Rejected -) - // FromMarshalUtil un-serializes an InclusionState using a MarshalUtil. func (i *InclusionState) FromMarshalUtil(marshalUtil *marshalutil.MarshalUtil) (err error) { untypedInclusionState, err := marshalUtil.ReadUint8() @@ -242,4 +233,15 @@ func (i InclusionState) Bytes() []byte { return marshalutil.New(marshalutil.Uint8Size).WriteUint8(uint8(i)).Bytes() } +const ( + // Pending represents elements that have neither been confirmed nor rejected. + Pending InclusionState = iota + + // Confirmed represents elements that have been confirmed and will stay part of the ledger state forever. + Confirmed + + // Rejected represents elements that have been rejected and will not be included in the ledger state. + Rejected +) + // endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/packages/ledger/branchdag/utils.go b/packages/ledger/branchdag/utils.go index c00f1472be..6f1fab0594 100644 --- a/packages/ledger/branchdag/utils.go +++ b/packages/ledger/branchdag/utils.go @@ -8,6 +8,7 @@ import ( // Utils is a BranchDAG component that bundles utility related API to simplify common interactions with the BranchDAG. type Utils struct { + // branchDAG contains a reference to the BranchDAG instance that created these Utils. branchDAG *BranchDAG } diff --git a/packages/ledger/utxo/interfaces.go b/packages/ledger/utxo/interfaces.go index c83c58ef4c..ea1ef8c713 100644 --- a/packages/ledger/utxo/interfaces.go +++ b/packages/ledger/utxo/interfaces.go @@ -49,12 +49,6 @@ type Output interface { ID() (id OutputID) // SetID sets the identifier of the Output. - // - // Note: Since determining the identifier of an Output is an operation that requires at least a few hashing - // operations, we allow the ID to be set from the outside. - // - // This allows us to potentially skip the ID calculation in cases where the ID is known upfront (e.g. when loading - // Outputs from the object storage). SetID(id OutputID) // TransactionID returns the identifier of the Transaction that created this Output. diff --git a/packages/ledger/vm/vm.go b/packages/ledger/vm/vm.go index a068a0cdab..aff2fa6f02 100644 --- a/packages/ledger/vm/vm.go +++ b/packages/ledger/vm/vm.go @@ -9,13 +9,10 @@ type VM interface { // ExecuteTransaction executes the Transaction and determines the Outputs from the given Inputs. It returns an error // if the execution fails. ExecuteTransaction(transaction utxo.Transaction, inputs []utxo.Output, gasLimit ...uint64) (outputs []utxo.Output, err error) - // ParseTransaction un-serializes a Transaction from the given sequence of bytes. ParseTransaction([]byte) (transaction utxo.Transaction, err error) - // ParseOutput un-serializes an Output from the given sequence of bytes. ParseOutput([]byte) (output utxo.Output, err error) - // ResolveInput translates the Input into an OutputID. ResolveInput(input utxo.Input) (outputID utxo.OutputID) }