Repository: kaspanet/kaspad
Pull request #1331 (2020-12-31 10:32:27)

Change SyncRateWindow to 15 minutes + update sync times on block headers as well


Patch:
diff --git a/app/protocol/flowcontext/blocks.go b/app/protocol/flowcontext/blocks.go
index 1ab87e81..96965d24 100644
--- a/app/protocol/flowcontext/blocks.go
+++ b/app/protocol/flowcontext/blocks.go
@@ -24,7 +24,7 @@ func (f *FlowContext) OnNewBlock(block *externalapi.DomainBlock,
 	log.Debugf("OnNewBlock start for block %s", hash)
 	defer log.Debugf("OnNewBlock end for block %s", hash)
 
-	f.updateRecentBlockAddedTimesWithLastBlock()
+	f.UpdateRecentBlockAddedTimesWithLastBlock()
 	unorphaningResults, err := f.UnorphanBlocks(block)
 	if err != nil {
 		return err
diff --git a/app/protocol/flowcontext/orphans.go b/app/protocol/flowcontext/orphans.go
index f655c4bc..d7a17ab5 100644
--- a/app/protocol/flowcontext/orphans.go
+++ b/app/protocol/flowcontext/orphans.go
@@ -156,7 +156,7 @@ func (f *FlowContext) unorphanBlock(orphanHash externalapi.DomainHash) (*externa
 		}
 		return nil, false, err
 	}
-	f.updateRecentBlockAddedTimesWithLastBlock()
+	f.UpdateRecentBlockAddedTimesWithLastBlock()
 
 	log.Infof("Unorphaned block %s", orphanHash)
 	return blockInsertionResult, true, nil
diff --git a/app/protocol/flowcontext/sync_rate.go b/app/protocol/flowcontext/sync_rate.go
index b7c0f2d2..fedbc27e 100644
--- a/app/protocol/flowcontext/sync_rate.go
+++ b/app/protocol/flowcontext/sync_rate.go
@@ -3,12 +3,14 @@ package flowcontext
 import "github.com/kaspanet/kaspad/util/mstime"
 
 const (
-	syncRateWindowInMilliSeconds                         = 60_000
+	syncRateWindowInMilliSeconds                         = 15 * 60 * 1000
 	syncRateMaxDeviation                                 = 0.05
 	maxSelectedParentTimeDiffToAllowMiningInMilliSeconds = 300_000
 )
 
-func (f *FlowContext) updateRecentBlockAddedTimesWithLastBlock() {
+// UpdateRecentBlockAddedTimesWithLastBlock adds current time to list of times when block was added.
+// We use this list to determine the current sync rate
+func (f *FlowContext) UpdateRecentBlockAddedTimesWithLastBlock() {
 	f.recentBlockAddedTimesMutex.Lock()
 	defer f.recentBlockAddedTimesMutex.Unlock()
 
@@ -44,7 +46,14 @@ func (f *FlowContext) isSyncRateBelowMinimum() bool {
 	}
 
 	expectedBlocks := float64(syncRateWindowInMilliSeconds) / float64(f.cfg.NetParams().TargetTimePerBlock.Milliseconds())
-	return 1-float64(len(f.recentBlockAddedTimes))/expectedBlocks > syncRateMaxDeviation
+	isSyncRateTooLow := 1-float64(len(f.recentBlockAddedTimes))/expectedBlocks > syncRateMaxDeviation
+
+	if isSyncRateTooLow {
+		log.Debugf("In the last %d seconds, got %d blocks, while at least %f were expected.",
+			syncRateWindowInMilliSeconds/1000, len(f.recentBlockAddedTimes), expectedBlocks*(1-syncRateMaxDeviation))
+	}
+
+	return isSyncRateTooLow
 }
 
 // ShouldMine returns whether it's ok to use block template from this node
diff --git a/app/protocol/flows/blockrelay/handle_relay_invs.go b/app/protocol/flows/blockrelay/handle_relay_invs.go
index 8b91c578..f4a81a52 100644
--- a/app/protocol/flows/blockrelay/handle_relay_invs.go
+++ b/app/protocol/flows/blockrelay/handle_relay_invs.go
@@ -33,6 +33,7 @@ type RelayInvsContext interface {
 	IsIBDRunning() bool
 	TrySetIBDRunning() bool
 	UnsetIBDRunning()
+	UpdateRecentBlockAddedTimesWithLastBlock()
 }
 
 type handleRelayInvsFlow struct {
diff --git a/app/protocol/flows/blockrelay/ibd.go b/app/protocol/flows/blockrelay/ibd.go
index 9d70cc3c..0e266d0e 100644
--- a/app/protocol/flows/blockrelay/ibd.go
+++ b/app/protocol/flows/blockrelay/ibd.go
@@ -1,6 +1,8 @@
 package blockrelay
 
 import (
+	"time"
+
 	"github.com/kaspanet/kaspad/app/appmessage"
 	"github.com/kaspanet/kaspad/app/protocol/common"
 	"github.com/kaspanet/kaspad/app/protocol/protocolerrors"
@@ -8,7 +10,6 @@ import (
 	"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
 	"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
 	"github.com/pkg/errors"
-	"time"
 )
 
 func (flow *handleRelayInvsFlow) runIBDIfNotRunning(highHash *externalapi.DomainHash) error {
@@ -257,6 +258,9 @@ func (flow *handleRelayInvsFlow) processHeader(msgBlockHeader *appmessage.MsgBlo
 
 		return protocolerrors.Wrapf(true, err, "got invalid block %s during IBD", blockHash)
 	}
+
+	flow.UpdateRecentBlockAddedTimesWithLastBlock()
+
 	return nil
 }
 
diff --git a/domain/consensus/database/serialization/acceptancedata.go b/domain/consensus/database/serialization/acceptancedata.go
index 40f38f7c..89e2a028 100644
--- a/domain/consensus/database/serialization/acceptancedata.go
+++ b/domain/consensus/database/serialization/acceptancedata.go
@@ -13,10 +13,17 @@ func DomainAcceptanceDataToDbAcceptanceData(domainAcceptanceData externalapi.Acc
 
 		for j, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData {
 			dbTransaction := DomainTransactionToDbTransaction(transactionAcceptanceData.Transaction)
+
+			dbTransactionInputUTXOEntries := make([]*DbUtxoEntry, len(transactionAcceptanceData.TransactionInputUTXOEntries))
+			for k, transactionInputUTXOEntry := range transactionAcceptanceData.TransactionInputUTXOEntries {
+				dbTransactionInputUTXOEntries[k] = UTXOEntryToDBUTXOEntry(transactionInputUTXOEntry)
+			}
+
 			dbTransactionAcceptanceData[j] = &DbTransactionAcceptanceData{
-				Transaction: dbTransaction,
-				Fee:         transactionAcceptanceData.Fee,
-				IsAccepted:  transactionAcceptanceData.IsAccepted,
+				Transaction:                 dbTransaction,
+				Fee:                         transactionAcceptanceData.Fee,
+				IsAccepted:                  transactionAcceptanceData.IsAccepted,
+				TransactionInputUtxoEntries: dbTransactionInputUTXOEntries,
 			}
 		}
 
@@ -45,10 +52,23 @@ func DbAcceptanceDataToDomainAcceptanceData(dbAcceptanceData *DbAcceptanceData)
 			if err != nil {
 				return nil, err
 			}
+
+			domainTransactionInputUTXOEntries := make([]externalapi.UTXOEntry, len(dbTransactionAcceptanceData.TransactionInputUtxoEntries))
+			for k, transactionInputUTXOEntry := range dbTransactionAcceptanceData.TransactionInputUtxoEntries {
+				domainTransactionInputUTXOEntry := DBUTXOEntryToUTXOEntry(transactionInputUTXOEntry)
+				domainTransactionInputUTXOEntries[k] = domainTransactionInputUTXOEntry
+
+				// For consistency's sake, we fill up the transaction input's
+				// UTXOEntry field as well, since that's how the acceptanceData
+				// must have arrived when it was originally serialized
+				domainTransaction.Inputs[k].UTXOEntry = domainTransactionInputUTXOEntry
+			}
+
 			domainTransactionAcceptanceData[j] = &externalapi.TransactionAcceptanceData{
-				Transaction: domainTransaction,
-				Fee:         dbTransactionAcceptanceData.Fee,
-				IsAccepted:  dbTransactionAcceptanceData.IsAccepted,
+				Transaction:                 domainTransaction,
+				Fee:                         dbTransactionAcceptanceData.Fee,
+				IsAccepted:                  dbTransactionAcceptanceData.IsAccepted,
+				TransactionInputUTXOEntries: domainTransactionInputUTXOEntries,
 			}
 		}
 
diff --git a/domain/consensus/database/serialization/dbobjects.pb.go b/domain/consensus/database/serialization/dbobjects.pb.go
index cd8a0912..f1e1fcaa 100644
--- a/domain/consensus/database/serialization/dbobjects.pb.go
+++ b/domain/consensus/database/serialization/dbobjects.pb.go
@@ -707,9 +707,10 @@ type DbTransactionAcceptanceData struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Transaction *DbTransaction `protobuf:"bytes,1,opt,name=transaction,proto3" json:"transaction,omitempty"`
-	Fee         uint64         `protobuf:"varint,2,opt,name=fee,proto3" json:"fee,omitempty"`
-	IsAccepted  bool           `protobuf:"varint,3,opt,name=isAccepted,proto3" json:"isAccepted,omitempty"`
+	Transaction                 *DbTransaction `protobuf:"bytes,1,opt,name=transaction,proto3" json:"transaction,omitempty"`
+	Fee                         uint64         `protobuf:"varint,2,opt,name=fee,proto3" json:"fee,omitempty"`
+	IsAccepted                  bool           `protobuf:"varint,3,opt,name=isAccepted,proto3" json:"isAccepted,omitempty"`
+	TransactionInputUtxoEntries []*DbUtxoEntry `protobuf:"bytes,4,rep,name=transactionInputUtxoEntries,proto3" json:"transactionInputUtxoEntries,omitempty"`
 }
 
 func (x *DbTransactionAcceptanceData) Reset() {
@@ -765,6 +766,13 @@ func (x *DbTransactionAcceptanceData) GetIsAccepted() bool {
 	return false
 }
 
+func (x *DbTransactionAcceptanceData) GetTransactionInputUtxoEntries() []*DbUtxoEntry {
+	if x != nil {
+		return x.TransactionInputUtxoEntries
+	}
+	return nil
+}
+
 type DbBlockRelations struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -1801,7 +1809,7 @@ var file_dbobjects_proto_rawDesc = []byte{
 	0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x09, 0x62, 0x6c, 0x6f,
 	0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73,
 	0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48,
-	0x61, 0x73, 0x68, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x8f,
+	0x61, 0x73, 0x68, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0xed,
 	0x01, 0x0a, 0x1b, 0x44, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
 	0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3e,
 	0x0a, 0x0b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
@@ -1811,124 +1819,130 @@ var file_dbobjects_proto_rawDesc = []byte{
 	0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x66, 0x65, 0x65,
 	0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x03,
 	0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64,
-	0x22, 0x76, 0x0a, 0x10, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18,
-	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x07, 0x70, 0x61,
-	0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65,
-	0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
-	0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x08,
-	0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x27, 0x0a, 0x0d, 0x44, 0x62, 0x42, 0x6c,
-	0x6f, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x22, 0xdb, 0x02, 0x0a, 0x13, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x47, 0x68, 0x6f,
-	0x73, 0x74, 0x64, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x6c, 0x75,
-	0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c,
-	0x75, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x57,
-	0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x57,
-	0x6f, 0x72, 0x6b, 0x12, 0x3d, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50,
-	0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65,
-	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61,
-	0x73, 0x68, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x65,
-	0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0d, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x42, 0x6c,
-	0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69,
-	0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68,
-	0x52, 0x0d, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x12,
-	0x39, 0x0a, 0x0c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x64, 0x73, 0x18,
-	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x0c, 0x6d, 0x65,
-	0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x64, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x62, 0x6c,
-	0x75, 0x65, 0x73, 0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73,
-	0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69,
-	0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x41, 0x6e,
-	0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x52, 0x12, 0x62, 0x6c, 0x75,
-	0x65, 0x73, 0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x22,
-	0x6d, 0x0a, 0x14, 0x44, 0x62, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f,
-	0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x48,
-	0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69,
+	0x12, 0x5c, 0x0a, 0x1b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
+	0x6e, 0x70, 0x75, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72,
+	0x79, 0x52, 0x1b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
+	0x70, 0x75, 0x74, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x76,
+	0x0a, 0x10, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x07, 0x70, 0x61, 0x72, 0x65,
+	0x6e, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18,
+	0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x08, 0x63, 0x68,
+	0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x27, 0x0a, 0x0d, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63,
+	0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
+	0xdb, 0x02, 0x0a, 0x13, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x47, 0x68, 0x6f, 0x73, 0x74,
+	0x64, 0x61, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x6c, 0x75, 0x65, 0x53,
+	0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x6c, 0x75, 0x65,
+	0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x57, 0x6f, 0x72,
+	0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x57, 0x6f, 0x72,
+	0x6b, 0x12, 0x3d, 0x0a, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72,
+	0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69,
 	0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68,
-	0x52, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x6e,
-	0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
-	0x52, 0x0c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x28,
-	0x0a, 0x0a, 0x44, 0x62, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08,
-	0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08,
-	0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x22, 0x46, 0x0a, 0x09, 0x44, 0x62, 0x55, 0x74,
-	0x78, 0x6f, 0x53, 0x65, 0x74, 0x12, 0x39, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01,
+	0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74,
+	0x12, 0x3b, 0x0a, 0x0d, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x42, 0x6c, 0x75, 0x65,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x0d,
+	0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x39, 0x0a,
+	0x0c, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x64, 0x73, 0x18, 0x05, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x0c, 0x6d, 0x65, 0x72, 0x67,
+	0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x64, 0x73, 0x12, 0x53, 0x0a, 0x12, 0x62, 0x6c, 0x75, 0x65,
+	0x73, 0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x18, 0x06,
 	0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
-	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
-	0x22, 0x87, 0x01, 0x0a, 0x14, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
-	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x35, 0x0a, 0x08, 0x6f, 0x75, 0x74,
-	0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65,
-	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x4f, 0x75,
-	0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74,
-	0x12, 0x38, 0x0a, 0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
-	0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x97, 0x01, 0x0a, 0x0b, 0x44,
-	0x62, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d,
-	0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75,
-	0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c,
-	0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e,
-	0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x53,
-	0x63, 0x6f, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61,
-	0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e,
-	0x62, 0x61, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x44, 0x62, 0x52, 0x65, 0x61, 0x63, 0x68,
-	0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x08, 0x63,
-	0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
-	0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62,
-	0x48, 0x61, 0x73, 0x68, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x2d,
-	0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
-	0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44,
-	0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a,
-	0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x25, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
-	0x44, 0x62, 0x52, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e,
-	0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
-	0x12, 0x43, 0x0a, 0x11, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x69,
-	0x6e, 0x67, 0x53, 0x65, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65,
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x41, 0x6e, 0x74, 0x69,
+	0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x52, 0x12, 0x62, 0x6c, 0x75, 0x65, 0x73,
+	0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x22, 0x6d, 0x0a,
+	0x14, 0x44, 0x62, 0x42, 0x6c, 0x75, 0x65, 0x73, 0x41, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65,
+	0x53, 0x69, 0x7a, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x65, 0x48, 0x61, 0x73,
+	0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x08,
+	0x62, 0x6c, 0x75, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x6e, 0x74, 0x69,
+	0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c,
+	0x61, 0x6e, 0x74, 0x69, 0x63, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x28, 0x0a, 0x0a,
+	0x44, 0x62, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x75,
+	0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x75,
+	0x6c, 0x74, 0x69, 0x73, 0x65, 0x74, 0x22, 0x46, 0x0a, 0x09, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f,
+	0x53, 0x65, 0x74, 0x12, 0x39, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+	0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x87,
+	0x01, 0x0a, 0x14, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+	0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x35, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f,
+	0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x69,
+	0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x4f, 0x75, 0x74, 0x70,
+	0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x38,
+	0x0a, 0x09, 0x75, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x75,
+	0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x97, 0x01, 0x0a, 0x0b, 0x44, 0x62, 0x55,
+	0x74, 0x78, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75,
+	0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
+	0x12, 0x28, 0x0a, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
+	0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x63, 0x72, 0x69, 0x70,
+	0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x6c,
+	0x6f, 0x63, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x53, 0x63, 0x6f,
+	0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61,
+	0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x44, 0x62, 0x52, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x68, 0x69,
+	0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65,
 	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61,
-	0x73, 0x68, 0x52, 0x11, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x69,
-	0x6e, 0x67, 0x53, 0x65, 0x74, 0x22, 0x40, 0x0a, 0x16, 0x44, 0x62, 0x52, 0x65, 0x61, 0x63, 0x68,
-	0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12,
-	0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
-	0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x88, 0x01, 0x0a, 0x0a, 0x44, 0x62, 0x55, 0x74,
-	0x78, 0x6f, 0x44, 0x69, 0x66, 0x66, 0x12, 0x39, 0x0a, 0x05, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x18,
-	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c,
-	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x74, 0x6f, 0x41, 0x64,
-	0x64, 0x12, 0x3f, 0x0a, 0x08, 0x74, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x02, 0x20,
+	0x73, 0x68, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x2d, 0x0a, 0x06,
+	0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73,
+	0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48,
+	0x61, 0x73, 0x68, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x69,
+	0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
+	0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62,
+	0x52, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x74, 0x65,
+	0x72, 0x76, 0x61, 0x6c, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x43,
+	0x0a, 0x11, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x69, 0x6e, 0x67,
+	0x53, 0x65, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69,
+	0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68,
+	0x52, 0x11, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x69, 0x6e, 0x67,
+	0x53, 0x65, 0x74, 0x22, 0x40, 0x0a, 0x16, 0x44, 0x62, 0x52, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x14, 0x0a,
+	0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74,
+	0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x88, 0x01, 0x0a, 0x0a, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f,
+	0x44, 0x69, 0x66, 0x66, 0x12, 0x39, 0x0a, 0x05, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x18, 0x01, 0x20,
 	0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
 	0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
-	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x74, 0x6f, 0x52, 0x65, 0x6d, 0x6f,
-	0x76, 0x65, 0x22, 0x32, 0x0a, 0x1a, 0x44, 0x62, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50,
-	0x6f, 0x69, 0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73,
-	0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
-	0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x39, 0x0a, 0x0c, 0x44, 0x62, 0x48, 0x65, 0x61, 0x64,
-	0x65, 0x72, 0x54, 0x69, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x69, 0x70, 0x73, 0x18, 0x01,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x74, 0x69, 0x70,
-	0x73, 0x22, 0x33, 0x0a, 0x06, 0x44, 0x62, 0x54, 0x69, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x74,
-	0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69,
-	0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68,
-	0x52, 0x04, 0x74, 0x69, 0x70, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x44, 0x62, 0x56, 0x69, 0x72, 0x74,
-	0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x45,
-	0x0a, 0x12, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72,
-	0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72,
-	0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73,
-	0x68, 0x52, 0x12, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61,
-	0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x24, 0x0a, 0x0c, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
-	0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2a, 0x0a, 0x12, 0x44,
-	0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e,
-	0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
-	0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75,
-	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b,
-	0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x12,
+	0x3f, 0x0a, 0x08, 0x74, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x23, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x2e, 0x44, 0x62, 0x55, 0x74, 0x78, 0x6f, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+	0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x74, 0x6f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
+	0x22, 0x32, 0x0a, 0x1a, 0x44, 0x62, 0x50, 0x72, 0x75, 0x6e, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x69,
+	0x6e, 0x74, 0x55, 0x54, 0x58, 0x4f, 0x53, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x14,
+	0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62,
+	0x79, 0x74, 0x65, 0x73, 0x22, 0x39, 0x0a, 0x0c, 0x44, 0x62, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
+	0x54, 0x69, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04, 0x74, 0x69, 0x70, 0x73, 0x22,
+	0x33, 0x0a, 0x06, 0x44, 0x62, 0x54, 0x69, 0x70, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x69, 0x70,
+	0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52, 0x04,
+	0x74, 0x69, 0x70, 0x73, 0x22, 0x5d, 0x0a, 0x14, 0x44, 0x62, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61,
+	0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x12,
+	0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65, 0x6e,
+	0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61,
+	0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x62, 0x48, 0x61, 0x73, 0x68, 0x52,
+	0x12, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x65,
+	0x6e, 0x74, 0x73, 0x22, 0x24, 0x0a, 0x0c, 0x44, 0x62, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f,
+	0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2a, 0x0a, 0x12, 0x44, 0x62, 0x42,
+	0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
+	0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73,
+	0x70, 0x61, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1992,30 +2006,31 @@ var file_dbobjects_proto_depIdxs = []int32{
 	11, // 13: serialization.DbBlockAcceptanceData.transactionAcceptanceData:type_name -> serialization.DbTransactionAcceptanceData
 	2,  // 14: serialization.DbBlockAcceptanceData.blockHash:type_name -> serialization.DbHash
 	3,  // 15: serialization.DbTransactionAcceptanceData.transaction:type_name -> serialization.DbTransaction
-	2,  // 16: serialization.DbBlockRelations.parents:type_name -> serialization.DbHash
-	2,  // 17: serialization.DbBlockRelations.children:type_name -> serialization.DbHash
-	2,  // 18: serialization.DbBlockGhostdagData.selectedParent:type_name -> serialization.DbHash
-	2,  // 19: serialization.DbBlockGhostdagData.mergeSetBlues:type_name -> serialization.DbHash
-	2,  // 20: serialization.DbBlockGhostdagData.mergeSetReds:type_name -> serialization.DbHash
-	15, // 21: serialization.DbBlockGhostdagData.bluesAnticoneSizes:type_name -> serialization.DbBluesAnticoneSizes
-	2,  // 22: serialization.DbBluesAnticoneSizes.blueHash:type_name -> serialization.DbHash
-	18, // 23: serialization.DbUtxoSet.items:type_name -> serialization.DbUtxoCollectionItem
-	5,  // 24: serialization.DbUtxoCollectionItem.outpoint:type_name -> serialization.DbOutpoint
-	19, // 25: serialization.DbUtxoCollectionItem.utxoEntry:type_name -> serialization.DbUtxoEntry
-	2,  // 26: serialization.DbReachabilityData.children:type_name -> serialization.DbHash
-	2,  // 27: serialization.DbReachabilityData.parent:type_name -> serialization.DbHash
-	21, // 28: serialization.DbReachabilityData.interval:type_name -> serialization.DbReachabilityInterval
-	2,  // 29: serialization.DbReachabilityData.futureCoveringSet:type_name -> serialization.DbHash
-	18, // 30: serialization.DbUtxoDiff.toAdd:type_name -> serialization.DbUtxoCollectionItem
-	18, // 31: serialization.DbUtxoDiff.toRemove:type_name -> serialization.DbUtxoCollectionItem
-	2,  // 32: serialization.DbHeaderTips.tips:type_name -> serialization.DbHash
-	2,  // 33: serialization.DbTips.tips:type_name -> serialization.DbHash
-	2,  // 34: serialization.DbVirtualDiffParents.virtualDiffParents:type_name -> serialization.DbHash
-	35, // [35:35] is the sub-list for method output_type
-	35, // [35:35] is the sub-list for method input_type
-	35, // [35:35] is the sub-list for extension type_name
-	35, // [35:35] is the sub-list for extension extendee
-	0,  // [0:35] is the sub-list for field type_name
+	19, // 16: serialization.DbTransactionAcceptanceData.transactionInputUtxoEntries:type_name -> serialization.DbUtxoEntry
+	2,  // 17: serialization.DbBlockRelations.parents:type_name -> serialization.DbHash
+	2,  // 18: serialization.DbBlockRelations.children:type_name -> serialization.DbHash
+	2,  // 19: serialization.DbBlockGhostdagData.selectedParent:type_name -> serialization.DbHash
+	2,  // 20: serialization.DbBlockGhostdagData.mergeSetBlues:type_name -> serialization.DbHash
+	2,  // 21: serialization.DbBlockGhostdagData.mergeSetReds:type_name -> serialization.DbHash
+	15, // 22: serialization.DbBlockGhostdagData.bluesAnticoneSizes:type_name -> serialization.DbBluesAnticoneSizes
+	2,  // 23: serialization.DbBluesAnticoneSizes.blueHash:type_name -> serialization.DbHash
+	18, // 24: serialization.DbUtxoSet.items:type_name -> serialization.DbUtxoCollectionItem
+	5,  // 25: serialization.DbUtxoCollectionItem.outpoint:type_name -> serialization.DbOutpoint
+	19, // 26: serialization.DbUtxoCollectionItem.utxoEntry:type_name -> serialization.DbUtxoEntry
+	2,  // 27: serialization.DbReachabilityData.children:type_name -> serialization.DbHash
+	2,  // 28: serialization.DbReachabilityData.parent:type_name -> serialization.DbHash
+	21, // 29: serialization.DbReachabilityData.interval:type_name -> serialization.DbReachabilityInterval
+	2,  // 30: serialization.DbReachabilityData.futureCoveringSet:type_name -> serialization.DbHash
+	18, // 31: serialization.DbUtxoDiff.toAdd:type_name -> serialization.DbUtxoCollectionItem
+	18, // 32: serialization.DbUtxoDiff.toRemove:type_name -> serialization.DbUtxoCollectionItem
+	2,  // 33: serialization.DbHeaderTips.tips:type_name -> serialization.DbHash
+	2,  // 34: serialization.DbTips.tips:type_name -> serialization.DbHash
+	2,  // 35: serialization.DbVirtualDiffParents.virtualDiffParents:type_name -> serialization.DbHash
+	36, // [36:36] is the sub-list for method output_type
+	36, // [36:36] is the sub-list for method input_type
+	36, // [36:36] is the sub-list for extension type_name
+	36, // [36:36] is the sub-list for extension extendee
+	0,  // [0:36] is the sub-list for field type_name
 }
 
 func init() { file_dbobjects_proto_init() }
diff --git a/domain/consensus/database/serialization/dbobjects.proto b/domain/consensus/database/serialization/dbobjects.proto
index 36f31a65..ddb97240 100644
--- a/domain/consensus/database/serialization/dbobjects.proto
+++ b/domain/consensus/database/serialization/dbobjects.proto
@@ -71,6 +71,7 @@ message DbTransactionAcceptanceData {
   DbTransaction transaction = 1;
   uint64 fee = 2;
   bool isAccepted = 3;
+  repeated DbUtxoEntry transactionInputUtxoEntries = 4;
 }
 
 message DbBlockRelations {
diff --git a/domain/consensus/factory.go b/domain/consensus/factory.go
index 27828c46..37bef61f 100644
--- a/domain/consensus/factory.go
+++ b/domain/consensus/factory.go
@@ -82,7 +82,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
 	pruningStore := pruningstore.New()
 	reachabilityDataStore := reachabilitydatastore.New(pruningWindowSizeForCaches)
 	utxoDiffStore := utxodiffstore.New(200)
-	consensusStateStore := consensusstatestore.New()
+	consensusStateStore := consensusstatestore.New(10_000)
 	ghostdagDataStore := ghostdagdatastore.New(pruningWindowSizeForCaches)
 	headersSelectedTipStore := headersselectedtipstore.New()
 	finalityStore := finalitystore.New(200)
diff --git a/domain/consensus/model/externalapi/acceptancedata.go b/domain/consensus/model/externalapi/acceptancedata.go
index 1cb4ae96..4b85741f 100644
--- a/domain/consensus/model/externalapi/acceptancedata.go
+++ b/domain/consensus/model/externalapi/acceptancedata.go
@@ -87,14 +87,15 @@ func (bad *BlockAcceptanceData) Clone() *BlockAcceptanceData {
 // TransactionAcceptanceData stores a transaction together with an indication
 // if it was accepted or not by some block
 type TransactionAcceptanceData struct {
-	Transaction *DomainTransaction
-	Fee         uint64
-	IsAccepted  bool
+	Transaction                 *DomainTransaction
+	Fee                         uint64
+	IsAccepted                  bool
+	TransactionInputUTXOEntries []UTXOEntry
 }
 
 // If this doesn't compile, it means the type definition has been changed, so it's
 // an indication to update Equal and Clone accordingly.
-var _ = &TransactionAcceptanceData{&DomainTransaction{}, 0, false}
+var _ = &TransactionAcceptanceData{&DomainTransaction{}, 0, false, []UTXOEntry{}}
 
 // Equal returns whether tad equals to other
 func (tad *TransactionAcceptanceData) Equal(other *TransactionAcceptanceData) bool {
@@ -114,14 +115,31 @@ func (tad *TransactionAcceptanceData) Equal(other *TransactionAcceptanceData) bo
 		return false
 	}
 
+	if len(tad.TransactionInputUTXOEntries) != len(other.TransactionInputUTXOEntries) {
+		return false
+	}
+
+	for i, thisUTXOEntry := range tad.TransactionInputUTXOEntries {
+		otherUTXOEntry := other.TransactionInputUTXOEntries[i]
+		if !thisUTXOEntry.Equal(otherUTXOEntry) {
+			return false
+		}
+	}
+
 	return true
 }
 
 // Clone returns a clone of TransactionAcceptanceData
 func (tad *TransactionAcceptanceData) Clone() *TransactionAcceptanceData {
+	cloneTransactionInputUTXOEntries := make([]UTXOEntry, len(tad.TransactionInputUTXOEntries))
+	for i, utxoEntry := range tad.TransactionInputUTXOEntries {
+		cloneTransactionInputUTXOEntries[i] = utxoEntry
+	}
+
 	return &TransactionAcceptanceData{
-		Transaction: tad.Transaction.Clone(),
-		Fee:         tad.Fee,
-		IsAccepted:  tad.IsAccepted,
+		Transaction:                 tad.Transaction.Clone(),
+		Fee:                         tad.Fee,
+		IsAccepted:                  tad.IsAccepted,
+		TransactionInputUTXOEntries: cloneTransactionInputUTXOEntries,
 	}
 }
diff --git a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go
index b62d10c9..711afe6b 100644
--- a/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go
+++ b/domain/consensus/processes/consensusstatemanager/calculate_past_utxo.go
@@ -155,10 +155,19 @@ func (csm *consensusStateManager) applyMergeSetBlocks(blockHash *externalapi.Dom
 			log.Tracef("Transaction %s in block %s isAccepted: %t, fee: %d",
 				transactionID, mergeSetBlockHash, isAccepted, transaction.Fee)
 
+			var transactionInputUTXOEntries []externalapi.UTXOEntry
+			if isAccepted {
+				transactionInputUTXOEntries = make([]externalapi.UTXOEntry, len(transaction.Inputs))
+				for k, input := range transaction.Inputs {
+					transactionInputUTXOEntries[k] = input.UTXOEntry
+				}
+			}
+
 			blockAcceptanceData.TransactionAcceptanceData[j] = &externalapi.TransactionAcceptanceData{
-				Transaction: transaction,
-				Fee:         transaction.Fee,
-				IsAccepted:  isAccepted,
+				Transaction:                 transaction,
+				Fee:                         transaction.Fee,
+				IsAccepted:                  isAccepted,
+				TransactionInputUTXOEntries: transactionInputUTXOEntries,
 			}
 		}
 		multiblockAcceptanceData[i] = blockAcceptanceData
diff --git a/domain/consensus/utils/utxolrucache/utxolrucache.go b/domain/consensus/utils/utxolrucache/utxolrucache.go
new file mode 100644
index 00000000..70a9e879
--- /dev/null
+++ b/domain/consensus/utils/utxolrucache/utxolrucache.go
@@ -0,0 +1,71 @@
+package utxolrucache
+
+import (
+	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
+)
+
+// LRUCache is a least-recently-used cache for UTXO entries
+// indexed by DomainOutpoint
+type LRUCache struct {
+	cache    map[externalapi.DomainOutpoint]externalapi.UTXOEntry
+	capacity int
+}
+
+// New creates a new LRUCache
+func New(capacity int) *LRUCache {
+	return &LRUCache{
+		cache:    make(map[externalapi.DomainOutpoint]externalapi.UTXOEntry, capacity+1),
+		capacity: capacity,
+	}
+}
+
+// Add adds an entry to the LRUCache
+func (c *LRUCache) Add(key *externalapi.DomainOutpoint, value externalapi.UTXOEntry) {
+	c.cache[*key] = value
+
+	if len(c.cache) > c.capacity {
+		c.evictRandom()
+	}
+}
+
+// Get returns the entry for the given key, or (nil, false) otherwise
+func (c *LRUCache) Get(key *externalapi.DomainOutpoint) (externalapi.UTXOEntry, bool) {
+	value, ok := c.cache[*key]
+	if !ok {
+		return nil, false
+	}
+	return value, true
+}
+
+// Has returns whether the LRUCache contains the given key
+func (c *LRUCache) Has(key *externalapi.DomainOutpoint) bool {
+	_, ok := c.cache[*key]
+	return ok
+}
+
+// Remove removes the entry for the the given key. Does nothing if
+// the entry does not exist
+func (c *LRUCache) Remove(key *externalapi.DomainOutpoint) {
+	delete(c.cache, *key)
+}
+
+// Clear clears the cache
+func (c *LRUCache) Clear() {
+	keys := make([]externalapi.DomainOutpoint, len(c.cache))
+	for outpoint := range c.cache {
+		keys = append(keys, outpoint)
+	}
+
+	for _, key := range keys {
+		delete(c.cache, key)
+	}
+}
+
+func (c *LRUCache) evictRandom() {
+	var keyToEvict externalapi.DomainOutpoint
+	for key := range c.cache {
+		keyToEvict = key
+		break
+	}
+	c.Remove(&keyToEvict)
+}
diff --git a/domain/utxoindex/utxoindex.go b/domain/utxoindex/utxoindex.go
index defa4a6b..e4292e56 100644
--- a/domain/utxoindex/utxoindex.go
+++ b/domain/utxoindex/utxoindex.go
@@ -80,7 +80,8 @@ func (ui *UTXOIndex) addBlock(blockHash *externalapi.DomainHash) error {
 			if !transactionAcceptanceData.IsAccepted {
 				continue
 			}
-			err := ui.addTransaction(transactionAcceptanceData.Transaction, blockInfo.BlueScore)
+			err := ui.addTransaction(transactionAcceptanceData.Transaction,
+				transactionAcceptanceData.TransactionInputUTXOEntries, blockInfo.BlueScore)
 			if err != nil {
 				return err
 			}
@@ -100,7 +101,8 @@ func (ui *UTXOIndex) removeBlock(blockHash *externalapi.DomainHash) error {
 			if !transactionAcceptanceData.IsAccepted {
 				continue
 			}
-			err := ui.removeTransaction(transactionAcceptanceData.Transaction)
+			err := ui.removeTransaction(transactionAcceptanceData.Transaction,
+				transactionAcceptanceData.TransactionInputUTXOEntries)
 			if err != nil {
 				return err
 			}
@@ -109,15 +111,18 @@ func (ui *UTXOIndex) removeBlock(blockHash *externalapi.DomainHash) error {
 	return nil
 }
 
-func (ui *UTXOIndex) addTransaction(transaction *externalapi.DomainTransaction, blockBlueScore uint64) error {
+func (ui *UTXOIndex) addTransaction(transaction *externalapi.DomainTransaction,
+	transactionInputUTXOEntries []externalapi.UTXOEntry, blockBlueScore uint64) error {
+
 	transactionID := consensushashing.TransactionID(transaction)
 	log.Tracef("Adding transaction %s to UTXO index", transactionID)
 
 	isCoinbase := transactionhelper.IsCoinBase(transaction)
-	for _, transactionInput := range transaction.Inputs {
+	for i, transactionInput := range transaction.Inputs {
 		log.Tracef("Removing outpoint %s:%d from UTXO index",
 			transactionInput.PreviousOutpoint.TransactionID, transactionInput.PreviousOutpoint.Index)
-		err := ui.store.remove(transactionInput.UTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint)
+		inputUTXOEntry := transactionInputUTXOEntries[i]
+		err := ui.store.remove(inputUTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint)
 		if err != nil {
 			return err
 		}
@@ -134,7 +139,9 @@ func (ui *UTXOIndex) addTransaction(transaction *externalapi.DomainTransaction,
 	return nil
 }
 
-func (ui *UTXOIndex) removeTransaction(transaction *externalapi.DomainTransaction) error {
+func (ui *UTXOIndex) removeTransaction(transaction *externalapi.DomainTransaction,
+	transactionInputUTXOEntries []externalapi.UTXOEntry) error {
+
 	transactionID := consensushashing.TransactionID(transaction)
 	log.Tracef("Removing transaction %s from UTXO index", transactionID)
 	for index, transactionOutput := range transaction.Outputs {
@@ -145,10 +152,11 @@ func (ui *UTXOIndex) removeTransaction(transaction *externalapi.DomainTransactio
 			return err
 		}
 	}
-	for _, transactionInput := range transaction.Inputs {
+	for i, transactionInput := range transaction.Inputs {
 		log.Tracef("Adding outpoint %s:%d to UTXO index",
 			transactionInput.PreviousOutpoint.TransactionID, transactionInput.PreviousOutpoint.Index)
-		err := ui.store.add(transactionInput.UTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint, transactionInput.UTXOEntry)
+		inputUTXOEntry := transactionInputUTXOEntries[i]
+		err := ui.store.add(inputUTXOEntry.ScriptPublicKey(), &transactionInput.PreviousOutpoint, transactionInput.UTXOEntry)
 		if err != nil {
 			return err
 		}


Test patch:
diff --git a/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go b/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go
index b3a37a78..cc2d14b8 100644
--- a/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go
+++ b/domain/consensus/datastructures/consensusstatestore/consensusstatestore.go
@@ -3,6 +3,7 @@ package consensusstatestore
 import (
 	"github.com/kaspanet/kaspad/domain/consensus/model"
 	"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
+	"github.com/kaspanet/kaspad/domain/consensus/utils/utxolrucache"
 )
 
 // consensusStateStore represents a store for the current consensus state
@@ -12,13 +13,17 @@ type consensusStateStore struct {
 	virtualUTXODiffStaging    model.UTXODiff
 	virtualUTXOSetStaging     model.UTXOCollection
 
+	virtualUTXOSetCache *utxolrucache.LRUCache
+
 	tipsCache               []*externalapi.DomainHash
 	virtualDiffParentsCache []*externalapi.DomainHash
 }
 
 // New instantiates a new ConsensusStateStore
-func New() model.ConsensusStateStore {
-	return &consensusStateStore{}
+func New(utxoSetCacheSize int) model.ConsensusStateStore {
+	return &consensusStateStore{
+		virtualUTXOSetCache: utxolrucache.New(utxoSetCacheSize),
+	}
 }
 
 func (css *consensusStateStore) Discard() {
diff --git a/domain/consensus/datastructures/consensusstatestore/utxo.go b/domain/consensus/datastructures/consensusstatestore/utxo.go
index 6bc76113..5959bfb1 100644
--- a/domain/consensus/datastructures/consensusstatestore/utxo.go
+++ b/domain/consensus/datastructures/consensusstatestore/utxo.go
@@ -39,6 +39,9 @@ func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction)
 		if err != nil {
 			return err
 		}
+
+		css.virtualUTXOSetCache.Remove(toRemoveOutpoint)
+
 		dbKey, err := utxoKey(toRemoveOutpoint)
 		if err != nil {
 			return err
@@ -55,6 +58,9 @@ func (css *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction)
 		if err != nil {
 			return err
 		}
+
+		css.virtualUTXOSetCache.Add(toAddOutpoint, toAddEntry)
+
 		dbKey, err := utxoKey(toAddOutpoint)
 		if err != nil {
 			return err
@@ -79,12 +85,15 @@ func (css *consensusStateStore) commitVirtualUTXOSet(dbTx model.DBTransaction) e
 		return nil
 	}
 
+	css.virtualUTXOSetCache.Clear()
 	iterator := css.virtualUTXOSetStaging.Iterator()
 	for iterator.Next() {
 		outpoint, utxoEntry, err := iterator.Get()
 		if err != nil {
 			return err
 		}
+
+		css.virtualUTXOSetCache.Add(outpoint, utxoEntry)
 		dbKey, err := utxoKey(outpoint)
 		if err != nil {
 			return err
@@ -127,6 +136,10 @@ func (css *consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContex
 		}
 	}
 
+	if entry, ok := css.virtualUTXOSetCache.Get(outpoint); ok {
+		return entry, nil
+	}
+
 	key, err := utxoKey(outpoint)
 	if err != nil {
 		return nil, err
@@ -137,7 +150,13 @@ func (css *consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContex
 		return nil, err
 	}
 
-	return deserializeUTXOEntry(serializedUTXOEntry)
+	entry, err := deserializeUTXOEntry(serializedUTXOEntry)
+	if err != nil {
+		return nil, err
+	}
+
+	css.virtualUTXOSetCache.Add(outpoint, entry)
+	return entry, nil
 }
 
 func (css *consensusStateStore) utxoByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) (
diff --git a/domain/consensus/model/acceptancedata_equal_clone_test.go b/domain/consensus/model/acceptancedata_equal_clone_test.go
index b3d7936f..1e96b37e 100644
--- a/domain/consensus/model/acceptancedata_equal_clone_test.go
+++ b/domain/consensus/model/acceptancedata_equal_clone_test.go
@@ -42,6 +42,7 @@ func initTestTransactionAcceptanceDataForClone() []*externalapi.TransactionAccep
 			},
 			1,
 			true,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		},
 	}
 	return tests
@@ -90,6 +91,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		},
 		1,
 		true,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 	}
 
 	var testTransactionAcceptanceData1 = externalapi.TransactionAcceptanceData{
@@ -122,6 +124,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		},
 		1,
 		true,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 	}
 	// test 2: different transactions
 	var testTransactionAcceptanceData2 = externalapi.TransactionAcceptanceData{
@@ -154,6 +157,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		},
 		1,
 		true,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 	}
 	//test 3: different Fee
 	var testTransactionAcceptanceData3 = externalapi.TransactionAcceptanceData{
@@ -187,6 +191,7 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		},
 		2,
 		true,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 	}
 	//test 4: different isAccepted
 	var testTransactionAcceptanceData4 = externalapi.TransactionAcceptanceData{
@@ -220,6 +225,42 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 		},
 		1,
 		false,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
+	}
+
+	//test 5: different TransactionInputUTXOEntries
+	var testTransactionAcceptanceData5 = externalapi.TransactionAcceptanceData{
+		&externalapi.DomainTransaction{
+			Version: 1,
+			Inputs: []*externalapi.DomainTransactionInput{{externalapi.DomainOutpoint{
+				*externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{0x01}), 0xFFFF},
+				[]byte{1, 2, 3},
+				uint64(0xFFFFFFFF),
+				utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)}},
+			Outputs: []*externalapi.DomainTransactionOutput{{uint64(0xFFFF),
+				[]byte{1, 2}},
+				{uint64(0xFFFF),
+					[]byte{1, 3}}},
+			LockTime:     1,
+			SubnetworkID: externalapi.DomainSubnetworkID{0x01},
+			Gas:          1,
+			PayloadHash: *externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
+			Payload: []byte{0x01},
+			Fee:     0,
+			Mass:    1,
+			ID: externalapi.NewDomainTransactionIDFromByteArray(&[externalapi.DomainHashSize]byte{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
+		},
+		1,
+		false,
+		[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 4, 3}, true, 2)},
 	}
 
 	tests := []testTransactionAcceptanceDataStruct{
@@ -238,6 +279,9 @@ func initTransactionAcceptanceDataForEqual() []testTransactionAcceptanceDataStru
 				}, {
 					transactionAcceptanceData: &testTransactionAcceptanceData4,
 					expectedResult:            false,
+				}, {
+					transactionAcceptanceData: &testTransactionAcceptanceData5,
+					expectedResult:            false,
 				}, {
 					transactionAcceptanceData: nil,
 					expectedResult:            false,
@@ -326,6 +370,7 @@ func initTestBlockAcceptanceDataForClone() []*externalapi.BlockAcceptanceData {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}},
 	},
 	}
@@ -377,6 +422,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 			},
 			1,
 			true,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		}}}
 	//test 1: structs are equal
 	var testBlockAcceptanceData1 = externalapi.BlockAcceptanceData{
@@ -413,6 +459,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 			},
 			1,
 			true,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		}}}
 	// test 2: different size
 	var testBlockAcceptanceData2 = externalapi.BlockAcceptanceData{
@@ -449,6 +496,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 			},
 			1,
 			true,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		}, {}}}
 	//test 3: different transactions, same size
 	var testBlockAcceptanceData3 = externalapi.BlockAcceptanceData{
@@ -485,6 +533,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 			},
 			1,
 			false,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		}}}
 
 	// test 4 - different block hash
@@ -522,6 +571,7 @@ func iniBlockAcceptanceDataForEqual() []testBlockAcceptanceDataStruct {
 			},
 			1,
 			true,
+			[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 		}}}
 
 	tests := []testBlockAcceptanceDataStruct{
@@ -629,6 +679,7 @@ func initTestAcceptanceDataForClone() []externalapi.AcceptanceData {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}},
 	},
 	}
@@ -682,6 +733,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}}}}
 	//test 1: structs are equal
 	var testAcceptanceData1 = []*externalapi.BlockAcceptanceData{
@@ -718,6 +770,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}}}}
 	// test 2: different size
 	var testAcceptanceData2 = []*externalapi.BlockAcceptanceData{
@@ -754,6 +807,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}}}, {}}
 	//test 3: different transactions, same size
 	var testAcceptanceData3 = []*externalapi.BlockAcceptanceData{
@@ -790,6 +844,7 @@ func initAcceptanceDataForEqual() []testAcceptanceDataStruct {
 				},
 				1,
 				true,
+				[]externalapi.UTXOEntry{utxo.NewUTXOEntry(1, []byte{0, 1, 2, 3}, true, 2)},
 			}}}}
 
 	tests := []testAcceptanceDataStruct{
diff --git a/domain/consensus/processes/consensusstatemanager/resolve_block_status_test.go b/domain/consensus/processes/consensusstatemanager/resolve_block_status_test.go
index 9b5511fd..02d74907 100644
--- a/domain/consensus/processes/consensusstatemanager/resolve_block_status_test.go
+++ b/domain/consensus/processes/consensusstatemanager/resolve_block_status_test.go
@@ -212,11 +212,21 @@ func TestTransactionAcceptance(t *testing.T) {
 		if err != nil {
 			t.Fatalf("Error creating spendingTransaction1: %+v", err)
 		}
+		spendingTransaction1UTXOEntry, err := testConsensus.ConsensusStateStore().
+			UTXOByOutpoint(testConsensus.DatabaseContext(), &spendingTransaction1.Inputs[0].PreviousOutpoint)
+		if err != nil {
+			t.Fatalf("Error getting UTXOEntry for spendingTransaction1: %s", err)
+		}
 
 		spendingTransaction2, err := testutils.CreateTransaction(fundingTransaction2)
 		if err != nil {
 			t.Fatalf("Error creating spendingTransaction1: %+v", err)
 		}
+		spendingTransaction2UTXOEntry, err := testConsensus.ConsensusStateStore().
+			UTXOByOutpoint(testConsensus.DatabaseContext(), &spendingTransaction2.Inputs[0].PreviousOutpoint)
+		if err != nil {
+			t.Fatalf("Error getting UTXOEntry for spendingTransaction2: %s", err)
+		}
 
 		redHash, _, err := testConsensus.AddBlock([]*externalapi.DomainHash{fundingBlock3Hash}, nil,
 			[]*externalapi.DomainTransaction{spendingTransaction1, spendingTransaction2})
@@ -284,9 +294,10 @@ func TestTransactionAcceptance(t *testing.T) {
 				BlockHash: finalTipSelectedParentHash,
 				TransactionAcceptanceData: []*externalapi.TransactionAcceptanceData{
 					{
-						Transaction: finalTipSelectedParent.Transactions[0],
-						Fee:         0,
-						IsAccepted:  true,
+						Transaction:                 finalTipSelectedParent.Transactions[0],
+						Fee:                         0,
+						IsAccepted:                  true,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{},
 					},
 				},
 			},
@@ -294,14 +305,16 @@ func TestTransactionAcceptance(t *testing.T) {
 				BlockHash: blueHash,
 				TransactionAcceptanceData: []*externalapi.TransactionAcceptanceData{
 					{
-						Transaction: blue.Transactions[0],
-						Fee:         0,
-						IsAccepted:  false,
+						Transaction:                 blue.Transactions[0],
+						Fee:                         0,
+						IsAccepted:                  false,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{},
 					},
 					{
-						Transaction: spendingTransaction1,
-						Fee:         1,
-						IsAccepted:  true,
+						Transaction:                 spendingTransaction1,
+						Fee:                         1,
+						IsAccepted:                  true,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{spendingTransaction1UTXOEntry},
 					},
 				},
 			},
@@ -309,19 +322,22 @@ func TestTransactionAcceptance(t *testing.T) {
 				BlockHash: redHash,
 				TransactionAcceptanceData: []*externalapi.TransactionAcceptanceData{
 					{
-						Transaction: red.Transactions[0],
-						Fee:         0,
-						IsAccepted:  false,
+						Transaction:                 red.Transactions[0],
+						Fee:                         0,
+						IsAccepted:                  false,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{},
 					},
 					{
-						Transaction: spendingTransaction1,
-						Fee:         0,
-						IsAccepted:  false,
+						Transaction:                 spendingTransaction1,
+						Fee:                         0,
+						IsAccepted:                  false,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{},
 					},
 					{
-						Transaction: spendingTransaction2,
-						Fee:         1,
-						IsAccepted:  true,
+						Transaction:                 spendingTransaction2,
+						Fee:                         1,
+						IsAccepted:                  true,
+						TransactionInputUTXOEntries: []externalapi.UTXOEntry{spendingTransaction2UTXOEntry},
 					},
 				},
 			},