From 7c67647f448cef15001cbff9c441b8bf54847d00 Mon Sep 17 00:00:00 2001 From: jkrvivian Date: Wed, 13 Jul 2022 14:48:08 +0800 Subject: [PATCH 1/3] Add an endpoint to fetch current EC --- packages/database/prefix.go | 3 + plugins/epochstorage/plugin.go | 125 ++++++++++++++++++++++++++++++--- plugins/webapi/epoch/plugin.go | 17 ++++- 3 files changed, 133 insertions(+), 12 deletions(-) diff --git a/packages/database/prefix.go b/packages/database/prefix.go index 2de863d715..e46baa2f93 100644 --- a/packages/database/prefix.go +++ b/packages/database/prefix.go @@ -27,4 +27,7 @@ const ( // PrefixNotarization defines the storage prefix for the epochs package. PrefixNotarization + + // PrefixEpochsStorage defines the storage prefix for the epoch storage plugin. + PrefixEpochsStorage ) diff --git a/plugins/epochstorage/plugin.go b/plugins/epochstorage/plugin.go index c2a8f96784..1d3da98d08 100644 --- a/plugins/epochstorage/plugin.go +++ b/plugins/epochstorage/plugin.go @@ -32,6 +32,8 @@ var ( Plugin *node.Plugin deps = new(dependencies) + baseStore kvstore.KVStore + epochContentsMutex sync.RWMutex epochContents = make(map[epoch.Index]*epochContentStorages, 0) committableEpochsMutex sync.RWMutex @@ -66,6 +68,7 @@ type dependencies struct { Tangle *tangle.Tangle NotarizationMgr *notarization.Manager + Storage kvstore.KVStore } func init() { @@ -84,6 +87,7 @@ func configure(plugin *node.Plugin) { // get the last committed epoch EI as minEpochIndex snapshotEC, _ := deps.NotarizationMgr.GetLatestEC() minEpochIndex = snapshotEC.EI() + baseStore = deps.Storage deps.NotarizationMgr.Events.TangleTreeInserted.Attach(event.NewClosure(func(event *notarization.TangleTreeUpdatedEvent) { epochOrderMutex.Lock() @@ -144,6 +148,12 @@ func configure(plugin *node.Plugin) { func run(*node.Plugin) { if err := daemon.BackgroundWorker("EpochStorage", func(ctx context.Context) { <-ctx.Done() + // flush all epoch contents to disc + epochContentsMutex.Lock() + for _, c := range epochContents { + c.flushAndCloseStorage() + } + epochContentsMutex.Unlock() }, shutdown.PriorityNotarization); err != nil { Plugin.Panicf("Failed to start as daemon: %s", err) } @@ -173,6 +183,9 @@ func checkEpochContentLimit() { epochContentsMutex.Lock() for _, i := range epochToRemove { + if c, ok := epochContents[i]; ok { + c.flushAndCloseStorage() + } delete(epochContents, i) } epochContentsMutex.Unlock() @@ -195,6 +208,18 @@ func checkEpochContentLimit() { committableEpochsMutex.Unlock() } +func (c *epochContentStorages) flushAndCloseStorage() { + c.createdOutputs.Flush() + c.spentOutputs.Flush() + c.blockIDs.Flush() + c.transactionIDs.Flush() + + c.createdOutputs.Close() + c.spentOutputs.Close() + c.blockIDs.Close() + c.transactionIDs.Close() +} + func GetCommittableEpochs() (ecRecords map[epoch.Index]*epoch.ECRecord) { ecRecords = make(map[epoch.Index]*epoch.ECRecord, 0) @@ -214,7 +239,7 @@ func GetPendingConflictCount() map[epoch.Index]uint64 { func GetEpochblocks(ei epoch.Index) ([]tangle.BlockID, error) { stores, err := getEpochContentStorage(ei) if err != nil { - return []tangle.BlockID{}, err + return getMessagesFromDisc(ei), nil } var blkIDs []tangle.BlockID @@ -233,7 +258,7 @@ func GetEpochblocks(ei epoch.Index) ([]tangle.BlockID, error) { func GetEpochTransactions(ei epoch.Index) ([]utxo.TransactionID, error) { stores, err := getEpochContentStorage(ei) if err != nil { - return []utxo.TransactionID{}, err + return getTransactionsFromDisc(ei), nil } var txIDs []utxo.TransactionID @@ -252,7 +277,8 @@ func GetEpochTransactions(ei epoch.Index) ([]utxo.TransactionID, error) { func GetEpochUTXOs(ei epoch.Index) (spent, created []utxo.OutputID, err error) { stores, err := getEpochContentStorage(ei) if err != nil { - return []utxo.OutputID{}, []utxo.OutputID{}, err + spent, created = getUTXOsFromDisc(ei) + return spent, created, nil } stores.createdOutputs.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool { @@ -296,6 +322,56 @@ func GetEpochVotersWeight(ei epoch.Index) (weights map[epoch.ECR]map[identity.ID return weights } +func getUTXOsFromDisc(ei epoch.Index) (spent, created []utxo.OutputID) { + baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...), func(key kvstore.Key) bool { + var outputID utxo.OutputID + if err := outputID.FromBytes(key); err != nil { + panic(err) + } + spent = append(spent, outputID) + + return true + }) + + baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...), func(key kvstore.Key) bool { + var outputID utxo.OutputID + if err := outputID.FromBytes(key); err != nil { + panic(err) + } + created = append(created, outputID) + + return true + }) + + return +} + +func getTransactionsFromDisc(ei epoch.Index) (txIDs []utxo.TransactionID) { + baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...), func(key kvstore.Key) bool { + var txID utxo.TransactionID + if _, err := txID.Decode(key); err != nil { + panic("TransactionID could not be parsed!") + } + txIDs = append(txIDs, txID) + return true + }) + + return +} + +func getMessagesFromDisc(ei epoch.Index) (blockIDs []tangle.BlockID) { + baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixMessageIDs}, ei.Bytes()...), func(key kvstore.Key) bool { + var blockID tangle.BlockID + if _, err := blockID.Decode(key); err != nil { + panic("MessageID could not be parsed!") + } + blockIDs = append(blockIDs, blockID) + return true + }) + + return +} + func getEpochContentStorage(ei epoch.Index) (*epochContentStorages, error) { if ei < minEpochIndex { return nil, errors.New("Epoch storage no longer exists") @@ -306,7 +382,7 @@ func getEpochContentStorage(ei epoch.Index) (*epochContentStorages, error) { epochContentsMutex.RUnlock() if !ok { - stores = newEpochContentStorage() + stores = newEpochContentStorage(ei) epochContentsMutex.Lock() epochContents[ei] = stores epochContentsMutex.Unlock() @@ -315,15 +391,30 @@ func getEpochContentStorage(ei epoch.Index) (*epochContentStorages, error) { return stores, nil } -func newEpochContentStorage() *epochContentStorages { - db, _ := database.NewMemDB() +func newEpochContentStorage(ei epoch.Index) *epochContentStorages { + spent, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } + created, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } + blockIDs, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixMessageIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } + txIDs, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } // keep data in temporary storage return &epochContentStorages{ - spentOutputs: db.NewStore(), - createdOutputs: db.NewStore(), - transactionIDs: db.NewStore(), - blockIDs: db.NewStore(), + spentOutputs: spent, + createdOutputs: created, + transactionIDs: txIDs, + blockIDs: blockIDs, } } @@ -441,3 +532,17 @@ func saveEpochVotersWeight(block *tangle.Block) { epochVotersLatestVote[voter] = &latestVote{ei: epochIndex, ecr: ecr, issuedTime: block.M.IssuingTime} epochVotersWeight[epochIndex][ecr][voter] = activeWeights[voter] } + +// region db prefixes ////////////////////////////////////////////////////////////////////////////////////////////////// + +const ( + prefixSpentOutput byte = iota + + prefixCreatedOutput + + prefixMessageIDs + + prefixTransactionIDs +) + +// region Options ////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/webapi/epoch/plugin.go b/plugins/webapi/epoch/plugin.go index 7c0a76468a..ef7fe47a6e 100644 --- a/plugins/webapi/epoch/plugin.go +++ b/plugins/webapi/epoch/plugin.go @@ -12,6 +12,7 @@ import ( "github.com/iotaledger/goshimmer/packages/epoch" "github.com/iotaledger/goshimmer/packages/jsonmodels" + "github.com/iotaledger/goshimmer/packages/notarization" "github.com/iotaledger/goshimmer/plugins/epochstorage" ) @@ -27,8 +28,9 @@ var ( type dependencies struct { dig.In - Server *echo.Echo - EpochStorage *node.Plugin `name:"epochstorage"` + Server *echo.Echo + EpochStorage *node.Plugin `name:"epochstorage"` + NotarizationMgr *notarization.Manager } func init() { @@ -37,6 +39,7 @@ func init() { func configure(_ *node.Plugin) { deps.Server.GET("epochs", getAllCommittedEpochs) + deps.Server.GET("ec", getCurrentEC) deps.Server.GET("epoch/:ei", getCommittedEpoch) deps.Server.GET("epoch/:ei/utxos", getUTXOs) deps.Server.GET("epoch/:ei/blocks", getBlocks) @@ -57,6 +60,16 @@ func getAllCommittedEpochs(c echo.Context) error { return c.JSON(http.StatusOK, allEpochsInfos) } +func getCurrentEC(c echo.Context) error { + ecRecord, err := deps.NotarizationMgr.GetLatestEC() + if err != nil { + return c.JSON(http.StatusInternalServerError, jsonmodels.NewErrorResponse(err)) + } + ec := notarization.EC(ecRecord) + + return c.JSON(http.StatusOK, ec.Base58()) +} + func getCommittedEpoch(c echo.Context) error { ei, err := getEI(c) if err != nil { From 85be5913801a89364307fdc271dd261c6b7d9f39 Mon Sep 17 00:00:00 2001 From: jkrvivian Date: Wed, 13 Jul 2022 14:51:11 +0800 Subject: [PATCH 2/3] Keep epoch contents in permanent storage --- plugins/epochstorage/plugin.go | 249 ++++++--------------------------- plugins/webapi/epoch/plugin.go | 15 +- 2 files changed, 42 insertions(+), 222 deletions(-) diff --git a/plugins/epochstorage/plugin.go b/plugins/epochstorage/plugin.go index 1d3da98d08..98c3e715cb 100644 --- a/plugins/epochstorage/plugin.go +++ b/plugins/epochstorage/plugin.go @@ -34,8 +34,6 @@ var ( baseStore kvstore.KVStore - epochContentsMutex sync.RWMutex - epochContents = make(map[epoch.Index]*epochContentStorages, 0) committableEpochsMutex sync.RWMutex committableEpochs = make([]*epoch.ECRecord, 0) epochVotersWeightMutex sync.RWMutex @@ -44,20 +42,12 @@ var ( maxEpochContentsToKeep = 100 numEpochContentsToRemove = 20 - minEpochIndex = epoch.Index(0) epochOrderMutex sync.RWMutex epochOrderMap = make(map[epoch.Index]types.Empty, 0) epochOrder = make([]epoch.Index, 0) ) -type epochContentStorages struct { - spentOutputs kvstore.KVStore - createdOutputs kvstore.KVStore - blockIDs kvstore.KVStore - transactionIDs kvstore.KVStore -} - type latestVote struct { ei epoch.Index ecr epoch.ECR @@ -84,9 +74,6 @@ func init() { } func configure(plugin *node.Plugin) { - // get the last committed epoch EI as minEpochIndex - snapshotEC, _ := deps.NotarizationMgr.GetLatestEC() - minEpochIndex = snapshotEC.EI() baseStore = deps.Storage deps.NotarizationMgr.Events.TangleTreeInserted.Attach(event.NewClosure(func(event *notarization.TangleTreeUpdatedEvent) { @@ -94,9 +81,9 @@ func configure(plugin *node.Plugin) { if _, ok := epochOrderMap[event.EI]; !ok { epochOrderMap[event.EI] = types.Void epochOrder = append(epochOrder, event.EI) + checkEpochContentLimit() } epochOrderMutex.Unlock() - checkEpochContentLimit() err := insertblockToEpoch(event.EI, event.BlockID) if err != nil { @@ -148,21 +135,13 @@ func configure(plugin *node.Plugin) { func run(*node.Plugin) { if err := daemon.BackgroundWorker("EpochStorage", func(ctx context.Context) { <-ctx.Done() - // flush all epoch contents to disc - epochContentsMutex.Lock() - for _, c := range epochContents { - c.flushAndCloseStorage() - } - epochContentsMutex.Unlock() }, shutdown.PriorityNotarization); err != nil { Plugin.Panicf("Failed to start as daemon: %s", err) } } func checkEpochContentLimit() { - epochOrderMutex.Lock() if len(epochOrder) <= maxEpochContentsToKeep { - epochOrderMutex.Unlock() return } @@ -179,16 +158,6 @@ func checkEpochContentLimit() { for _, i := range epochToRemove { delete(epochOrderMap, i) } - epochOrderMutex.Unlock() - - epochContentsMutex.Lock() - for _, i := range epochToRemove { - if c, ok := epochContents[i]; ok { - c.flushAndCloseStorage() - } - delete(epochContents, i) - } - epochContentsMutex.Unlock() epochVotersWeightMutex.Lock() for _, i := range epochToRemove { @@ -196,9 +165,6 @@ func checkEpochContentLimit() { } epochVotersWeightMutex.Unlock() - // update minEpochIndex - minEpochIndex = epochOrder[0] - committableEpochsMutex.Lock() if len(committableEpochs) < maxEpochContentsToKeep { committableEpochsMutex.Unlock() @@ -208,18 +174,6 @@ func checkEpochContentLimit() { committableEpochsMutex.Unlock() } -func (c *epochContentStorages) flushAndCloseStorage() { - c.createdOutputs.Flush() - c.spentOutputs.Flush() - c.blockIDs.Flush() - c.transactionIDs.Flush() - - c.createdOutputs.Close() - c.spentOutputs.Close() - c.blockIDs.Close() - c.transactionIDs.Close() -} - func GetCommittableEpochs() (ecRecords map[epoch.Index]*epoch.ECRecord) { ecRecords = make(map[epoch.Index]*epoch.ECRecord, 0) @@ -236,33 +190,24 @@ func GetPendingConflictCount() map[epoch.Index]uint64 { return deps.NotarizationMgr.PendingConflictsCountAll() } -func GetEpochblocks(ei epoch.Index) ([]tangle.BlockID, error) { - stores, err := getEpochContentStorage(ei) - if err != nil { - return getMessagesFromDisc(ei), nil - } +func GetEpochblocks(ei epoch.Index) (blockIDs []tangle.BlockID) { + prefix := append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...) - var blkIDs []tangle.BlockID - stores.blockIDs.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool { - var blkID tangle.BlockID - if _, err := blkID.Decode(key); err != nil { + baseStore.IterateKeys(prefix, func(key kvstore.Key) bool { + var blockID tangle.BlockID + if _, err := blockID.Decode(key); err != nil { panic("BlockID could not be parsed!") } - blkIDs = append(blkIDs, blkID) + blockIDs = append(blockIDs, blockID) return true }) - - return blkIDs, nil + return } -func GetEpochTransactions(ei epoch.Index) ([]utxo.TransactionID, error) { - stores, err := getEpochContentStorage(ei) - if err != nil { - return getTransactionsFromDisc(ei), nil - } +func GetEpochTransactions(ei epoch.Index) (txIDs []utxo.TransactionID) { + prefix := append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...) - var txIDs []utxo.TransactionID - stores.transactionIDs.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool { + baseStore.IterateKeys(prefix, func(key kvstore.Key) bool { var txID utxo.TransactionID if _, err := txID.Decode(key); err != nil { panic("TransactionID could not be parsed!") @@ -271,37 +216,33 @@ func GetEpochTransactions(ei epoch.Index) ([]utxo.TransactionID, error) { return true }) - return txIDs, nil + return } -func GetEpochUTXOs(ei epoch.Index) (spent, created []utxo.OutputID, err error) { - stores, err := getEpochContentStorage(ei) - if err != nil { - spent, created = getUTXOsFromDisc(ei) - return spent, created, nil - } +func GetEpochUTXOs(ei epoch.Index) (spent, created []utxo.OutputID) { + createdPrefix := append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...) + spentPrefix := append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...) - stores.createdOutputs.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool { + baseStore.IterateKeys(spentPrefix, func(key kvstore.Key) bool { var outputID utxo.OutputID - if err = outputID.FromBytes(key); err != nil { + if err := outputID.FromBytes(key); err != nil { panic(err) } - created = append(created, outputID) + spent = append(spent, outputID) return true }) - stores.spentOutputs.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool { + baseStore.IterateKeys(createdPrefix, func(key kvstore.Key) bool { var outputID utxo.OutputID - if err = outputID.FromBytes(key); err != nil { + if err := outputID.FromBytes(key); err != nil { panic(err) } - spent = append(spent, outputID) + created = append(created, outputID) return true }) - - return spent, created, nil + return } func GetEpochVotersWeight(ei epoch.Index) (weights map[epoch.ECR]map[identity.ID]float64) { @@ -322,164 +263,54 @@ func GetEpochVotersWeight(ei epoch.Index) (weights map[epoch.ECR]map[identity.ID return weights } -func getUTXOsFromDisc(ei epoch.Index) (spent, created []utxo.OutputID) { - baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...), func(key kvstore.Key) bool { - var outputID utxo.OutputID - if err := outputID.FromBytes(key); err != nil { - panic(err) - } - spent = append(spent, outputID) - - return true - }) - - baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...), func(key kvstore.Key) bool { - var outputID utxo.OutputID - if err := outputID.FromBytes(key); err != nil { - panic(err) - } - created = append(created, outputID) - - return true - }) - - return -} - -func getTransactionsFromDisc(ei epoch.Index) (txIDs []utxo.TransactionID) { - baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...), func(key kvstore.Key) bool { - var txID utxo.TransactionID - if _, err := txID.Decode(key); err != nil { - panic("TransactionID could not be parsed!") - } - txIDs = append(txIDs, txID) - return true - }) - - return -} - -func getMessagesFromDisc(ei epoch.Index) (blockIDs []tangle.BlockID) { - baseStore.IterateKeys(append([]byte{database.PrefixEpochsStorage, prefixMessageIDs}, ei.Bytes()...), func(key kvstore.Key) bool { - var blockID tangle.BlockID - if _, err := blockID.Decode(key); err != nil { - panic("MessageID could not be parsed!") - } - blockIDs = append(blockIDs, blockID) - return true - }) - - return -} - -func getEpochContentStorage(ei epoch.Index) (*epochContentStorages, error) { - if ei < minEpochIndex { - return nil, errors.New("Epoch storage no longer exists") - } - - epochContentsMutex.RLock() - stores, ok := epochContents[ei] - epochContentsMutex.RUnlock() - - if !ok { - stores = newEpochContentStorage(ei) - epochContentsMutex.Lock() - epochContents[ei] = stores - epochContentsMutex.Unlock() - } - - return stores, nil -} - -func newEpochContentStorage(ei epoch.Index) *epochContentStorages { - spent, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...)) - if err != nil { - panic(err) - } - created, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...)) - if err != nil { - panic(err) - } - blockIDs, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixMessageIDs}, ei.Bytes()...)) - if err != nil { - panic(err) - } - txIDs, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...)) - if err != nil { - panic(err) - } - - // keep data in temporary storage - return &epochContentStorages{ - spentOutputs: spent, - createdOutputs: created, - transactionIDs: txIDs, - blockIDs: blockIDs, - } -} - func insertblockToEpoch(ei epoch.Index, blkID tangle.BlockID) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + prefix := append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...) - if err := epochContentStorage.blockIDs.Set(blkID.Bytes(), blkID.Bytes()); err != nil { + if err := baseStore.Set(append(prefix, blkID.Bytes()...), blkID.Bytes()); err != nil { return errors.New("Fail to insert block to epoch store") } return nil } func removeblockFromEpoch(ei epoch.Index, blkID tangle.BlockID) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + prefix := append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...) - if err := epochContentStorage.blockIDs.Delete(blkID.Bytes()); err != nil { + if err := baseStore.Delete(append(prefix, blkID.Bytes()...)); err != nil { return errors.New("Fail to remove block from epoch store") } return nil } func insertTransactionToEpoch(ei epoch.Index, txID utxo.TransactionID) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + prefix := append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...) - if err := epochContentStorage.transactionIDs.Set(txID.Bytes(), txID.Bytes()); err != nil { + if err := baseStore.Set(append(prefix, txID.Bytes()...), txID.Bytes()); err != nil { return errors.New("Fail to insert Transaction to epoch store") } return nil } func removeTransactionFromEpoch(ei epoch.Index, txID utxo.TransactionID) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + prefix := append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...) - if err := epochContentStorage.transactionIDs.Delete(txID.Bytes()); err != nil { + if err := baseStore.Delete(append(prefix, txID.Bytes()...)); err != nil { return errors.New("Fail to remove Transaction from epoch store") } return nil } func insertOutputsToEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMetadata) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + createdPrefix := append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...) + spentPrefix := append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...) for _, s := range spent { - if err := epochContentStorage.spentOutputs.Set(s.ID().Bytes(), s.ID().Bytes()); err != nil { + if err := baseStore.Set(append(spentPrefix, s.ID().Bytes()...), s.ID().Bytes()); err != nil { return errors.New("Fail to insert spent output to epoch store") } } for _, c := range created { - if err := epochContentStorage.createdOutputs.Set(c.ID().Bytes(), c.ID().Bytes()); err != nil { + if err := baseStore.Set(append(createdPrefix, c.ID().Bytes()...), c.ID().Bytes()); err != nil { return errors.New("Fail to insert created output to epoch store") } } @@ -488,19 +319,17 @@ func insertOutputsToEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMet } func removeOutputsFromEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMetadata) error { - epochContentStorage, err := getEpochContentStorage(ei) - if err != nil { - return err - } + createdPrefix := append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...) + spentPrefix := append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...) for _, s := range spent { - if err := epochContentStorage.spentOutputs.Delete(s.ID().Bytes()); err != nil { + if err := baseStore.Delete(append(spentPrefix, s.ID().Bytes()...)); err != nil { return errors.New("Fail to remove spent output from epoch store") } } for _, c := range created { - if err := epochContentStorage.createdOutputs.Delete(c.ID().Bytes()); err != nil { + if err := baseStore.Delete(append(createdPrefix, c.ID().Bytes()...)); err != nil { return errors.New("Fail to remove created output from epoch store") } } @@ -540,7 +369,7 @@ const ( prefixCreatedOutput - prefixMessageIDs + prefixBlockIDs prefixTransactionIDs ) diff --git a/plugins/webapi/epoch/plugin.go b/plugins/webapi/epoch/plugin.go index ef7fe47a6e..7c29d87a5d 100644 --- a/plugins/webapi/epoch/plugin.go +++ b/plugins/webapi/epoch/plugin.go @@ -86,10 +86,7 @@ func getUTXOs(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) } - spentIDs, createdIDs, err := epochstorage.GetEpochUTXOs(ei) - if err != nil { - return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) - } + spentIDs, createdIDs := epochstorage.GetEpochUTXOs(ei) spent := make([]string, len(spentIDs)) for i, o := range spentIDs { @@ -110,10 +107,7 @@ func getBlocks(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) } - blockIDs, err := epochstorage.GetEpochblocks(ei) - if err != nil { - return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) - } + blockIDs := epochstorage.GetEpochblocks(ei) blocks := make([]string, len(blockIDs)) for i, m := range blockIDs { @@ -129,10 +123,7 @@ func getTransactions(c echo.Context) error { if err != nil { return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) } - transactionIDs, err := epochstorage.GetEpochTransactions(ei) - if err != nil { - return c.JSON(http.StatusBadRequest, jsonmodels.NewErrorResponse(err)) - } + transactionIDs := epochstorage.GetEpochTransactions(ei) transactions := make([]string, len(transactionIDs)) for i, t := range transactionIDs { From 5faea531b3ee911140c15ad13a61905f6366fe76 Mon Sep 17 00:00:00 2001 From: jkrvivian Date: Wed, 13 Jul 2022 15:57:33 +0800 Subject: [PATCH 3/3] Make use of WithRealm --- plugins/epochstorage/plugin.go | 58 ++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/plugins/epochstorage/plugin.go b/plugins/epochstorage/plugin.go index 98c3e715cb..0809464cb7 100644 --- a/plugins/epochstorage/plugin.go +++ b/plugins/epochstorage/plugin.go @@ -264,53 +264,72 @@ func GetEpochVotersWeight(ei epoch.Index) (weights map[epoch.ECR]map[identity.ID } func insertblockToEpoch(ei epoch.Index, blkID tangle.BlockID) error { - prefix := append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...) + blockStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } - if err := baseStore.Set(append(prefix, blkID.Bytes()...), blkID.Bytes()); err != nil { + if err := blockStore.Set(blkID.Bytes(), blkID.Bytes()); err != nil { return errors.New("Fail to insert block to epoch store") } return nil } func removeblockFromEpoch(ei epoch.Index, blkID tangle.BlockID) error { - prefix := append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...) + blockStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixBlockIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } - if err := baseStore.Delete(append(prefix, blkID.Bytes()...)); err != nil { + if err := blockStore.Delete(blkID.Bytes()); err != nil { return errors.New("Fail to remove block from epoch store") } return nil } func insertTransactionToEpoch(ei epoch.Index, txID utxo.TransactionID) error { - prefix := append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...) + txStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } - if err := baseStore.Set(append(prefix, txID.Bytes()...), txID.Bytes()); err != nil { + if err := txStore.Set(txID.Bytes(), txID.Bytes()); err != nil { return errors.New("Fail to insert Transaction to epoch store") } return nil } func removeTransactionFromEpoch(ei epoch.Index, txID utxo.TransactionID) error { - prefix := append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...) + txStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixTransactionIDs}, ei.Bytes()...)) + if err != nil { + panic(err) + } - if err := baseStore.Delete(append(prefix, txID.Bytes()...)); err != nil { + if err := txStore.Delete(txID.Bytes()); err != nil { return errors.New("Fail to remove Transaction from epoch store") } return nil } func insertOutputsToEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMetadata) error { - createdPrefix := append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...) - spentPrefix := append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...) + createdStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } + + spentStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } for _, s := range spent { - if err := baseStore.Set(append(spentPrefix, s.ID().Bytes()...), s.ID().Bytes()); err != nil { + if err := spentStore.Set(s.ID().Bytes(), s.ID().Bytes()); err != nil { return errors.New("Fail to insert spent output to epoch store") } } for _, c := range created { - if err := baseStore.Set(append(createdPrefix, c.ID().Bytes()...), c.ID().Bytes()); err != nil { + if err := createdStore.Set(c.ID().Bytes(), c.ID().Bytes()); err != nil { return errors.New("Fail to insert created output to epoch store") } } @@ -319,17 +338,24 @@ func insertOutputsToEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMet } func removeOutputsFromEpoch(ei epoch.Index, spent, created []*ledger.OutputWithMetadata) error { - createdPrefix := append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...) - spentPrefix := append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...) + createdStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixCreatedOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } + + spentStore, err := baseStore.WithRealm(append([]byte{database.PrefixEpochsStorage, prefixSpentOutput}, ei.Bytes()...)) + if err != nil { + panic(err) + } for _, s := range spent { - if err := baseStore.Delete(append(spentPrefix, s.ID().Bytes()...)); err != nil { + if err := spentStore.Delete(s.ID().Bytes()); err != nil { return errors.New("Fail to remove spent output from epoch store") } } for _, c := range created { - if err := baseStore.Delete(append(createdPrefix, c.ID().Bytes()...)); err != nil { + if err := createdStore.Delete(c.ID().Bytes()); err != nil { return errors.New("Fail to remove created output from epoch store") } }