Repository: vsc-eco/go-vsc-node
Pull request #29: Consensus unstaking resolver, get single witness query
Author: login: techcoderx
Created: 2025-05-09T07:22:57Z | Merged: 2025-05-13T16:36:57Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a new field to account balances showing the pending consensus unstaking amount.
  - Introduced a query to fetch witness information for a specific account and block height.

- **Removals**
  - Removed the AnchorProducer type and related queries from the interface.
  - Removed queries related to witness nodes, election data, and anchor producer functionality.
  - Removed several interfaces and enums related to balance control and transaction types.
  - Removed the Mutation type and related mutation functionality.

- **Improvements**
  - Streamlined query logic for resolving block heights in account and witness-related queries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/modules/db/vsc/ledger/ledger.go b/modules/db/vsc/ledger/ledger.go
index 70fb682f..0936dad9 100644
--- a/modules/db/vsc/ledger/ledger.go
+++ b/modules/db/vsc/ledger/ledger.go
@@ -9,6 +9,7 @@ import (
 	"vsc-node/modules/db/vsc/hive_blocks"
 
 	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
@@ -406,6 +407,35 @@ func (actions *actionsDb) GetActionsRange(txId *string, actionId *string, accoun
 	return results, nil
 }
 
+func (actions *actionsDb) GetAccountPendingConsensusUnstake(account string) (int64, error) {
+	cursor, err := actions.Aggregate(context.TODO(), mongo.Pipeline{
+		{{Key: "$match", Value: bson.D{
+			{Key: "to", Value: account},
+			{Key: "status", Value: "pending"},
+			{Key: "type", Value: "consensus_unstake"},
+		}}},
+		{{Key: "$group", Value: bson.D{
+			{Key: "_id", Value: nil},
+			{Key: "totalAmount", Value: bson.M{"$sum": "$amount"}},
+		}}},
+	})
+	if err != nil {
+		return -1, err
+	}
+	defer cursor.Close(context.TODO())
+
+	var result struct {
+		TotalAmount int64 `bson:"totalAmount"`
+	}
+	if cursor.Next(context.TODO()) {
+		if err := cursor.Decode(&result); err != nil {
+			return -1, err
+		}
+		return result.TotalAmount, nil
+	}
+	return 0, nil
+}
+
 type interestClaims struct {
 	*db.Collection
 }
diff --git a/modules/db/vsc/ledger/types.go b/modules/db/vsc/ledger/types.go
index b3126c16..07961bfe 100644
--- a/modules/db/vsc/ledger/types.go
+++ b/modules/db/vsc/ledger/types.go
@@ -101,6 +101,7 @@ type BridgeActions interface {
 	GetPendingActions(bh uint64, t ...string) ([]ActionRecord, error)
 	GetPendingActionsByEpoch(epoch uint64, t ...string) ([]ActionRecord, error)
 	GetActionsRange(txId *string, actionId *string, account *string, byTypes []string, asset *Asset, status *string, fromBlock *uint64, toBlock *uint64, offset int, limit int) ([]ActionRecord, error)
+	GetAccountPendingConsensusUnstake(account string) (int64, error)
 }
 
 type ILedgerExecutor interface {
diff --git a/modules/gql/gqlgen/generated.go b/modules/gql/gqlgen/generated.go
index d5b3757d..cc30be18 100644
--- a/modules/gql/gqlgen/generated.go
+++ b/modules/gql/gqlgen/generated.go
@@ -54,7 +54,6 @@ type ResolverRoot interface {
 	ContractState() ContractStateResolver
 	ElectionResult() ElectionResultResolver
 	LedgerRecord() LedgerRecordResolver
-	Mutation() MutationResolver
 	NonceRecord() NonceRecordResolver
 	OpLogEvent() OpLogEventResolver
 	PostingJsonKeys() PostingJsonKeysResolver
@@ -83,20 +82,17 @@ type ComplexityRoot struct {
 		Type        func(childComplexity int) int
 	}
 
-	AnchorProducer struct {
-		NextSlot func(childComplexity int, account *string) int
-	}
-
 	BalanceRecord struct {
-		Account       func(childComplexity int) int
-		BlockHeight   func(childComplexity int) int
-		Hbd           func(childComplexity int) int
-		HbdAvg        func(childComplexity int) int
-		HbdClaim      func(childComplexity int) int
-		HbdModify     func(childComplexity int) int
-		HbdSavings    func(childComplexity int) int
-		Hive          func(childComplexity int) int
-		HiveConsensus func(childComplexity int) int
+		Account            func(childComplexity int) int
+		BlockHeight        func(childComplexity int) int
+		ConsensusUnstaking func(childComplexity int) int
+		Hbd                func(childComplexity int) int
+		HbdAvg             func(childComplexity int) int
+		HbdClaim           func(childComplexity int) int
+		HbdModify          func(childComplexity int) int
+		HbdSavings         func(childComplexity int) int
+		Hive               func(childComplexity int) int
+		HiveConsensus      func(childComplexity int) int
 	}
 
 	Contract struct {
@@ -182,10 +178,6 @@ type ComplexityRoot struct {
 		VersionID          func(childComplexity int) int
 	}
 
-	Mutation struct {
-		IncrementNumber func(childComplexity int) int
-	}
-
 	NonceRecord struct {
 		Account func(childComplexity int) int
 		Nonce   func(childComplexity int) int
@@ -208,29 +200,24 @@ type ComplexityRoot struct {
 	}
 
 	Query struct {
-		ActiveWitnessNodes   func(childComplexity int) int
-		AnchorProducer       func(childComplexity int) int
-		ContractState        func(childComplexity int, id *string) int
-		ContractStateDiff    func(childComplexity int, id *string) int
-		FindContract         func(childComplexity int, id *string) int
-		FindContractOutput   func(childComplexity int, filterOptions *FindContractOutputFilter, decodedFilter *string) int
-		FindLedgerActions    func(childComplexity int, filterOptions *LedgerActionsFilter) int
-		FindLedgerTXs        func(childComplexity int, filterOptions *LedgerTxFilter) int
-		FindTransaction      func(childComplexity int, filterOptions *TransactionFilter) int
-		GetAccountBalance    func(childComplexity int, account string, height *model.Uint64) int
-		GetAccountNonce      func(childComplexity int, account string) int
-		GetAccountRc         func(childComplexity int, account string, height *model.Uint64) int
-		GetCurrentNumber     func(childComplexity int) int
-		GetDagByCid          func(childComplexity int, cidString string) int
-		GetElection          func(childComplexity int, epoch model.Uint64) int
-		LocalNodeInfo        func(childComplexity int) int
-		MockGenerateElection func(childComplexity int) int
-		NextWitnessSlot      func(childComplexity int, self *bool) int
-		SubmitTransactionV1  func(childComplexity int, tx string, sig string) int
-		WitnessActiveScore   func(childComplexity int, height *int) int
-		WitnessNodes         func(childComplexity int, height model.Uint64) int
-		WitnessSchedule      func(childComplexity int, height model.Uint64) int
-		WitnessStake         func(childComplexity int, account string) int
+		ContractState       func(childComplexity int, id *string) int
+		ContractStateDiff   func(childComplexity int, id *string) int
+		FindContract        func(childComplexity int, id *string) int
+		FindContractOutput  func(childComplexity int, filterOptions *FindContractOutputFilter, decodedFilter *string) int
+		FindLedgerActions   func(childComplexity int, filterOptions *LedgerActionsFilter) int
+		FindLedgerTXs       func(childComplexity int, filterOptions *LedgerTxFilter) int
+		FindTransaction     func(childComplexity int, filterOptions *TransactionFilter) int
+		GetAccountBalance   func(childComplexity int, account string, height *model.Uint64) int
+		GetAccountNonce     func(childComplexity int, account string) int
+		GetAccountRc        func(childComplexity int, account string, height *model.Uint64) int
+		GetDagByCid         func(childComplexity int, cidString string) int
+		GetElection         func(childComplexity int, epoch model.Uint64) int
+		GetWitness          func(childComplexity int, account string, height *model.Uint64) int
+		LocalNodeInfo       func(childComplexity int) int
+		SubmitTransactionV1 func(childComplexity int, tx string, sig string) int
+		WitnessNodes        func(childComplexity int, height model.Uint64) int
+		WitnessSchedule     func(childComplexity int, height model.Uint64) int
+		WitnessStake        func(childComplexity int, account string) int
 	}
 
 	RcRecord struct {
@@ -239,10 +226,6 @@ type ComplexityRoot struct {
 		BlockHeight func(childComplexity int) int
 	}
 
-	TestResult struct {
-		CurrentNumber func(childComplexity int) int
-	}
-
 	TransactionData struct {
 		Action     func(childComplexity int) int
 		ContractID func(childComplexity int) int
@@ -314,6 +297,7 @@ type BalanceRecordResolver interface {
 	HbdSavings(ctx context.Context, obj *ledgerDb.BalanceRecord) (model.Int64, error)
 	Hive(ctx context.Context, obj *ledgerDb.BalanceRecord) (model.Int64, error)
 	HiveConsensus(ctx context.Context, obj *ledgerDb.BalanceRecord) (model.Int64, error)
+	ConsensusUnstaking(ctx context.Context, obj *ledgerDb.BalanceRecord) (model.Int64, error)
 }
 type ContractOutputResolver interface {
 	AnchoredBlock(ctx context.Context, obj *contracts.ContractOutput) (*string, error)
@@ -345,9 +329,6 @@ type LedgerRecordResolver interface {
 	Amount(ctx context.Context, obj *ledgerDb.LedgerRecord) (model.Int64, error)
 	BlockHeight(ctx context.Context, obj *ledgerDb.LedgerRecord) (model.Uint64, error)
 }
-type MutationResolver interface {
-	IncrementNumber(ctx context.Context) (*TestResult, error)
-}
 type NonceRecordResolver interface {
 	Nonce(ctx context.Context, obj *nonces.NonceRecord) (model.Uint64, error)
 }
@@ -373,14 +354,9 @@ type QueryResolver interface {
 	SubmitTransactionV1(ctx context.Context, tx string, sig string) (*TransactionSubmitResult, error)
 	GetAccountNonce(ctx context.Context, account string) (*nonces.NonceRecord, error)
 	LocalNodeInfo(ctx context.Context) (*LocalNodeInfo, error)
+	GetWitness(ctx context.Context, account string, height *model.Uint64) (*witnesses.Witness, error)
 	WitnessNodes(ctx context.Context, height model.Uint64) ([]witnesses.Witness, error)
-	ActiveWitnessNodes(ctx context.Context) (*string, error)
 	WitnessSchedule(ctx context.Context, height model.Uint64) ([]stateEngine.WitnessSlot, error)
-	NextWitnessSlot(ctx context.Context, self *bool) (*string, error)
-	WitnessActiveScore(ctx context.Context, height *int) (*string, error)
-	MockGenerateElection(ctx context.Context) (*string, error)
-	AnchorProducer(ctx context.Context) (*AnchorProducer, error)
-	GetCurrentNumber(ctx context.Context) (*TestResult, error)
 	WitnessStake(ctx context.Context, account string) (model.Uint64, error)
 	GetDagByCid(ctx context.Context, cidString string) (string, error)
 	GetElection(ctx context.Context, epoch model.Uint64) (*elections.ElectionResult, error)
@@ -505,18 +481,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.ActionRecord.Type(childComplexity), true
 
-	case "AnchorProducer.nextSlot":
-		if e.complexity.AnchorProducer.NextSlot == nil {
-			break
-		}
-
-		args, err := ec.field_AnchorProducer_nextSlot_args(context.TODO(), rawArgs)
-		if err != nil {
-			return 0, false
-		}
-
-		return e.complexity.AnchorProducer.NextSlot(childComplexity, args["account"].(*string)), true
-
 	case "BalanceRecord.account":
 		if e.complexity.BalanceRecord.Account == nil {
 			break
@@ -531,6 +495,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.BalanceRecord.BlockHeight(childComplexity), true
 
+	case "BalanceRecord.consensus_unstaking":
+		if e.complexity.BalanceRecord.ConsensusUnstaking == nil {
+			break
+		}
+
+		return e.complexity.BalanceRecord.ConsensusUnstaking(childComplexity), true
+
 	case "BalanceRecord.hbd":
 		if e.complexity.BalanceRecord.Hbd == nil {
 			break
@@ -945,13 +916,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.LocalNodeInfo.VersionID(childComplexity), true
 
-	case "Mutation.incrementNumber":
-		if e.complexity.Mutation.IncrementNumber == nil {
-			break
-		}
-
-		return e.complexity.Mutation.IncrementNumber(childComplexity), true
-
 	case "NonceRecord.account":
 		if e.complexity.NonceRecord.Account == nil {
 			break
@@ -1036,20 +1000,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.PostingJsonKeys.T(childComplexity), true
 
-	case "Query.activeWitnessNodes":
-		if e.complexity.Query.ActiveWitnessNodes == nil {
-			break
-		}
-
-		return e.complexity.Query.ActiveWitnessNodes(childComplexity), true
-
-	case "Query.anchorProducer":
-		if e.complexity.Query.AnchorProducer == nil {
-			break
-		}
-
-		return e.complexity.Query.AnchorProducer(childComplexity), true
-
 	case "Query.contractState":
 		if e.complexity.Query.ContractState == nil {
 			break
@@ -1170,13 +1120,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.Query.GetAccountRc(childComplexity, args["account"].(string), args["height"].(*model.Uint64)), true
 
-	case "Query.getCurrentNumber":
-		if e.complexity.Query.GetCurrentNumber == nil {
-			break
-		}
-
-		return e.complexity.Query.GetCurrentNumber(childComplexity), true
-
 	case "Query.getDagByCID":
 		if e.complexity.Query.GetDagByCid == nil {
 			break
@@ -1201,31 +1144,24 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.Query.GetElection(childComplexity, args["epoch"].(model.Uint64)), true
 
-	case "Query.localNodeInfo":
-		if e.complexity.Query.LocalNodeInfo == nil {
+	case "Query.getWitness":
+		if e.complexity.Query.GetWitness == nil {
 			break
 		}
 
-		return e.complexity.Query.LocalNodeInfo(childComplexity), true
-
-	case "Query.mockGenerateElection":
-		if e.complexity.Query.MockGenerateElection == nil {
-			break
+		args, err := ec.field_Query_getWitness_args(context.TODO(), rawArgs)
+		if err != nil {
+			return 0, false
 		}
 
-		return e.complexity.Query.MockGenerateElection(childComplexity), true
+		return e.complexity.Query.GetWitness(childComplexity, args["account"].(string), args["height"].(*model.Uint64)), true
 
-	case "Query.nextWitnessSlot":
-		if e.complexity.Query.NextWitnessSlot == nil {
+	case "Query.localNodeInfo":
+		if e.complexity.Query.LocalNodeInfo == nil {
 			break
 		}
 
-		args, err := ec.field_Query_nextWitnessSlot_args(context.TODO(), rawArgs)
-		if err != nil {
-			return 0, false
-		}
-
-		return e.complexity.Query.NextWitnessSlot(childComplexity, args["self"].(*bool)), true
+		return e.complexity.Query.LocalNodeInfo(childComplexity), true
 
 	case "Query.submitTransactionV1":
 		if e.complexity.Query.SubmitTransactionV1 == nil {
@@ -1239,18 +1175,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.Query.SubmitTransactionV1(childComplexity, args["tx"].(string), args["sig"].(string)), true
 
-	case "Query.witnessActiveScore":
-		if e.complexity.Query.WitnessActiveScore == nil {
-			break
-		}
-
-		args, err := ec.field_Query_witnessActiveScore_args(context.TODO(), rawArgs)
-		if err != nil {
-			return 0, false
-		}
-
-		return e.complexity.Query.WitnessActiveScore(childComplexity, args["height"].(*int)), true
-
 	case "Query.witnessNodes":
 		if e.complexity.Query.WitnessNodes == nil {
 			break
@@ -1308,13 +1232,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 
 		return e.complexity.RcRecord.BlockHeight(childComplexity), true
 
-	case "TestResult.currentNumber":
-		if e.complexity.TestResult.CurrentNumber == nil {
-			break
-		}
-
-		return e.complexity.TestResult.CurrentNumber(childComplexity), true
-
 	case "TransactionData.action":
 		if e.complexity.TransactionData.Action == nil {
 			break
@@ -1606,21 +1523,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
 
 			return &response
 		}
-	case ast.Mutation:
-		return func(ctx context.Context) *graphql.Response {
-			if !first {
-				return nil
-			}
-			first = false
-			ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
-			data := ec._Mutation(ctx, opCtx.Operation.SelectionSet)
-			var buf bytes.Buffer
-			data.MarshalGQL(&buf)
-
-			return &graphql.Response{
-				Data: buf.Bytes(),
-			}
-		}
 
 	default:
 		return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
@@ -1692,14 +1594,6 @@ enum Asset {
   hbd_savings
 }
 
-enum TransactionType {
-  NULL
-  INPUT
-  OUTPUT
-  VIRTUAL
-  CORE
-}
-
 type TransactionRecord {
   id: String!
   anchr_height: Uint64!
@@ -1816,41 +1710,6 @@ type WitnessSlot {
   bn: Uint64!
 }
 
-interface BalanceController {
-  type: BalanceControllerType
-  authority: String
-  conditions: [BalanceAccessCondition]
-}
-
-enum BalanceControllerType {
-  HIVE
-  DID
-  CONTRACT
-}
-
-interface BalanceAccessCondition {
-  type: BalanceAccessConditionType
-  value: String
-}
-
-enum BalanceAccessConditionType {
-  TIME
-  HASH
-  WITHDRAW
-}
-
-interface DepositDrain {
-  deposit_id: String
-  amount: Float
-  token: String
-  owner: String
-}
-
-interface BlockRef {
-  block_ref: String
-  included_block: Int
-}
-
 type BalanceRecord {
   account: String
   block_height: Uint64!
@@ -1861,6 +1720,7 @@ type BalanceRecord {
   hbd_savings: Int64!
   hive: Int64!
   hive_consensus: Int64!
+  consensus_unstaking: Int64!
 }
 
 type RcRecord {
@@ -1873,10 +1733,6 @@ type FindContractOutputResult {
   outputs: [ContractOutput]
 }
 
-type AnchorProducer {
-  nextSlot(account: String): JSON
-}
-
 type LedgerRecord {
   id: String!
   amount: Int64!
@@ -1982,14 +1838,9 @@ type Query {
   submitTransactionV1(tx: String!, sig: String!): TransactionSubmitResult
   getAccountNonce(account: String!): NonceRecord
   localNodeInfo: LocalNodeInfo
+  getWitness(account: String!, height: Uint64): Witness
   witnessNodes(height: Uint64!): [Witness!]!
-  activeWitnessNodes: JSON
   witnessSchedule(height: Uint64!): [WitnessSlot!]!
-  nextWitnessSlot(self: Boolean): JSON
-  witnessActiveScore(height: Int): JSON
-  mockGenerateElection: JSON
-  anchorProducer: AnchorProducer
-  getCurrentNumber: TestResult # TESTING QUERY
   witnessStake(account: String!): Uint64!
   getDagByCID(cidString: String!): JSON!
   getElection(epoch: Uint64!): ElectionResult
@@ -1999,15 +1850,6 @@ scalar Uint64
 scalar Int64
 scalar Map
 scalar DateTime
-
-type Mutation {
-  incrementNumber: TestResult # TESTING MUTATION
-}
-
-# TESTING TYPE
-type TestResult {
-  currentNumber: Int
-}
 `, BuiltIn: false},
 }
 var parsedSchema = gqlparser.MustLoadSchema(sources...)
@@ -2016,29 +1858,6 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...)
 
 // region    ***************************** args.gotpl *****************************
 
-func (ec *executionContext) field_AnchorProducer_nextSlot_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
-	var err error
-	args := map[string]any{}
-	arg0, err := ec.field_AnchorProducer_nextSlot_argsAccount(ctx, rawArgs)
-	if err != nil {
-		return nil, err
-	}
-	args["account"] = arg0
-	return args, nil
-}
-func (ec *executionContext) field_AnchorProducer_nextSlot_argsAccount(
-	ctx context.Context,
-	rawArgs map[string]any,
-) (*string, error) {
-	ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("account"))
-	if tmp, ok := rawArgs["account"]; ok {
-		return ec.unmarshalOString2ᚖstring(ctx, tmp)
-	}
-
-	var zeroVal *string
-	return zeroVal, nil
-}
-
 func (ec *executionContext) field_ContractState_stateKeys_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
 	var err error
 	args := map[string]any{}
@@ -2479,26 +2298,44 @@ func (ec *executionContext) field_Query_getElection_argsEpoch(
 	return zeroVal, nil
 }
 
-func (ec *executionContext) field_Query_nextWitnessSlot_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+func (ec *executionContext) field_Query_getWitness_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
 	var err error
 	args := map[string]any{}
-	arg0, err := ec.field_Query_nextWitnessSlot_argsSelf(ctx, rawArgs)
+	arg0, err := ec.field_Query_getWitness_argsAccount(ctx, rawArgs)
+	if err != nil {
+		return nil, err
+	}
+	args["account"] = arg0
+	arg1, err := ec.field_Query_getWitness_argsHeight(ctx, rawArgs)
 	if err != nil {
 		return nil, err
 	}
-	args["self"] = arg0
+	args["height"] = arg1
 	return args, nil
 }
-func (ec *executionContext) field_Query_nextWitnessSlot_argsSelf(
+func (ec *executionContext) field_Query_getWitness_argsAccount(
 	ctx context.Context,
 	rawArgs map[string]any,
-) (*bool, error) {
-	ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("self"))
-	if tmp, ok := rawArgs["self"]; ok {
-		return ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
+) (string, error) {
+	ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("account"))
+	if tmp, ok := rawArgs["account"]; ok {
+		return ec.unmarshalNString2string(ctx, tmp)
 	}
 
-	var zeroVal *bool
+	var zeroVal string
+	return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query_getWitness_argsHeight(
+	ctx context.Context,
+	rawArgs map[string]any,
+) (*model.Uint64, error) {
+	ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("height"))
+	if tmp, ok := rawArgs["height"]; ok {
+		return ec.unmarshalOUint642ᚖvscᚑnodeᚋmodulesᚋgqlᚋmodelᚐUint64(ctx, tmp)
+	}
+
+	var zeroVal *model.Uint64
 	return zeroVal, nil
 }
 
@@ -2543,29 +2380,6 @@ func (ec *executionContext) field_Query_submitTransactionV1_argsSig(
 	return zeroVal, nil
 }
 
-func (ec *executionContext) field_Query_witnessActiveScore_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
-	var err error
-	args := map[string]any{}
-	arg0, err := ec.field_Query_witnessActiveScore_argsHeight(ctx, rawArgs)
-	if err != nil {
-		return nil, err
-	}
-	args["height"] = arg0
-	return args, nil
-}
-func (ec *executionContext) field_Query_witnessActiveScore_argsHeight(
-	ctx context.Context,
-	rawArgs map[string]any,
-) (*int, error) {
-	ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("height"))
-	if tmp, ok := rawArgs["height"]; ok {
-		return ec.unmarshalOInt2ᚖint(ctx, tmp)
-	}
-
-	var zeroVal *int
-	return zeroVal, nil
-}
-
 func (ec *executionContext) field_Query_witnessNodes_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
 	var err error
 	args := map[string]any{}
@@ -3216,58 +3030,6 @@ func (ec *executionContext) fieldContext_ActionRecord_timestamp(_ context.Contex
 	return fc, nil
 }
 
-func (ec *executionContext) _AnchorProducer_nextSlot(ctx context.Context, field graphql.CollectedField, obj *AnchorProducer) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_AnchorProducer_nextSlot(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return obj.NextSlot, nil
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*string)
-	fc.Result = res
-	return ec.marshalOJSON2ᚖstring(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_AnchorProducer_nextSlot(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "AnchorProducer",
-		Field:      field,
-		IsMethod:   false,
-		IsResolver: false,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type JSON does not have child fields")
-		},
-	}
-	defer func() {
-		if r := recover(); r != nil {
-			err = ec.Recover(ctx, r)
-			ec.Error(ctx, err)
-		}
-	}()
-	ctx = graphql.WithFieldContext(ctx, fc)
-	if fc.Args, err = ec.field_AnchorProducer_nextSlot_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
-		ec.Error(ctx, err)
-		return fc, err
-	}
-	return fc, nil
-}
-
 func (ec *executionContext) _BalanceRecord_account(ctx context.Context, field graphql.CollectedField, obj *ledgerDb.BalanceRecord) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_BalanceRecord_account(ctx, field)
 	if err != nil {
@@ -3661,6 +3423,50 @@ func (ec *executionContext) fieldContext_BalanceRecord_hive_consensus(_ context.
 	return fc, nil
 }
 
+func (ec *executionContext) _BalanceRecord_consensus_unstaking(ctx context.Context, field graphql.CollectedField, obj *ledgerDb.BalanceRecord) (ret graphql.Marshaler) {
+	fc, err := ec.fieldContext_BalanceRecord_consensus_unstaking(ctx, field)
+	if err != nil {
+		return graphql.Null
+	}
+	ctx = graphql.WithFieldContext(ctx, fc)
+	defer func() {
+		if r := recover(); r != nil {
+			ec.Error(ctx, ec.Recover(ctx, r))
+			ret = graphql.Null
+		}
+	}()
+	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+		ctx = rctx // use context from middleware stack in children
+		return ec.resolvers.BalanceRecord().ConsensusUnstaking(rctx, obj)
+	})
+	if err != nil {
+		ec.Error(ctx, err)
+		return graphql.Null
+	}
+	if resTmp == nil {
+		if !graphql.HasFieldError(ctx, fc) {
+			ec.Errorf(ctx, "must not be null")
+		}
+		return graphql.Null
+	}
+	res := resTmp.(model.Int64)
+	fc.Result = res
+	return ec.marshalNInt642vscᚑnodeᚋmodulesᚋgqlᚋmodelᚐInt64(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_BalanceRecord_consensus_unstaking(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+	fc = &graphql.FieldContext{
+		Object:     "BalanceRecord",
+		Field:      field,
+		IsMethod:   true,
+		IsResolver: true,
+		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+			return nil, errors.New("field of type Int64 does not have child fields")
+		},
+	}
+	return fc, nil
+}
+
 func (ec *executionContext) _Contract_id(ctx context.Context, field graphql.CollectedField, obj *Contract) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_Contract_id(ctx, field)
 	if err != nil {
@@ -5868,8 +5674,8 @@ func (ec *executionContext) fieldContext_LocalNodeInfo_epoch(_ context.Context,
 	return fc, nil
 }
 
-func (ec *executionContext) _Mutation_incrementNumber(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Mutation_incrementNumber(ctx, field)
+func (ec *executionContext) _NonceRecord_account(ctx context.Context, field graphql.CollectedField, obj *nonces.NonceRecord) (ret graphql.Marshaler) {
+	fc, err := ec.fieldContext_NonceRecord_account(ctx, field)
 	if err != nil {
 		return graphql.Null
 	}
@@ -5882,76 +5688,31 @@ func (ec *executionContext) _Mutation_incrementNumber(ctx context.Context, field
 	}()
 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
 		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Mutation().IncrementNumber(rctx)
+		return obj.Account, nil
 	})
 	if err != nil {
 		ec.Error(ctx, err)
 		return graphql.Null
 	}
 	if resTmp == nil {
+		if !graphql.HasFieldError(ctx, fc) {
+			ec.Errorf(ctx, "must not be null")
+		}
 		return graphql.Null
 	}
-	res := resTmp.(*TestResult)
+	res := resTmp.(string)
 	fc.Result = res
-	return ec.marshalOTestResult2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐTestResult(ctx, field.Selections, res)
+	return ec.marshalNString2string(ctx, field.Selections, res)
 }
 
-func (ec *executionContext) fieldContext_Mutation_incrementNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_NonceRecord_account(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
 	fc = &graphql.FieldContext{
-		Object:     "Mutation",
+		Object:     "NonceRecord",
 		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
+		IsMethod:   false,
+		IsResolver: false,
 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			switch field.Name {
-			case "currentNumber":
-				return ec.fieldContext_TestResult_currentNumber(ctx, field)
-			}
-			return nil, fmt.Errorf("no field named %q was found under type TestResult", field.Name)
-		},
-	}
-	return fc, nil
-}
-
-func (ec *executionContext) _NonceRecord_account(ctx context.Context, field graphql.CollectedField, obj *nonces.NonceRecord) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_NonceRecord_account(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return obj.Account, nil
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		if !graphql.HasFieldError(ctx, fc) {
-			ec.Errorf(ctx, "must not be null")
-		}
-		return graphql.Null
-	}
-	res := resTmp.(string)
-	fc.Result = res
-	return ec.marshalNString2string(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_NonceRecord_account(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "NonceRecord",
-		Field:      field,
-		IsMethod:   false,
-		IsResolver: false,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type String does not have child fields")
+			return nil, errors.New("field of type String does not have child fields")
 		},
 	}
 	return fc, nil
@@ -6888,6 +6649,8 @@ func (ec *executionContext) fieldContext_Query_getAccountBalance(ctx context.Con
 				return ec.fieldContext_BalanceRecord_hive(ctx, field)
 			case "hive_consensus":
 				return ec.fieldContext_BalanceRecord_hive_consensus(ctx, field)
+			case "consensus_unstaking":
+				return ec.fieldContext_BalanceRecord_consensus_unstaking(ctx, field)
 			}
 			return nil, fmt.Errorf("no field named %q was found under type BalanceRecord", field.Name)
 		},
@@ -7187,8 +6950,8 @@ func (ec *executionContext) fieldContext_Query_localNodeInfo(_ context.Context,
 	return fc, nil
 }
 
-func (ec *executionContext) _Query_witnessNodes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_witnessNodes(ctx, field)
+func (ec *executionContext) _Query_getWitness(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+	fc, err := ec.fieldContext_Query_getWitness(ctx, field)
 	if err != nil {
 		return graphql.Null
 	}
@@ -7201,24 +6964,21 @@ func (ec *executionContext) _Query_witnessNodes(ctx context.Context, field graph
 	}()
 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
 		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().WitnessNodes(rctx, fc.Args["height"].(model.Uint64))
+		return ec.resolvers.Query().GetWitness(rctx, fc.Args["account"].(string), fc.Args["height"].(*model.Uint64))
 	})
 	if err != nil {
 		ec.Error(ctx, err)
 		return graphql.Null
 	}
 	if resTmp == nil {
-		if !graphql.HasFieldError(ctx, fc) {
-			ec.Errorf(ctx, "must not be null")
-		}
 		return graphql.Null
 	}
-	res := resTmp.([]witnesses.Witness)
+	res := resTmp.(*witnesses.Witness)
 	fc.Result = res
-	return ec.marshalNWitness2ᚕvscᚑnodeᚋmodulesᚋdbᚋvscᚋwitnessesᚐWitnessᚄ(ctx, field.Selections, res)
+	return ec.marshalOWitness2ᚖvscᚑnodeᚋmodulesᚋdbᚋvscᚋwitnessesᚐWitness(ctx, field.Selections, res)
 }
 
-func (ec *executionContext) fieldContext_Query_witnessNodes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_getWitness(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
 	fc = &graphql.FieldContext{
 		Object:     "Query",
 		Field:      field,
@@ -7261,56 +7021,15 @@ func (ec *executionContext) fieldContext_Query_witnessNodes(ctx context.Context,
 		}
 	}()
 	ctx = graphql.WithFieldContext(ctx, fc)
-	if fc.Args, err = ec.field_Query_witnessNodes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+	if fc.Args, err = ec.field_Query_getWitness_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
 		ec.Error(ctx, err)
 		return fc, err
 	}
 	return fc, nil
 }
 
-func (ec *executionContext) _Query_activeWitnessNodes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_activeWitnessNodes(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().ActiveWitnessNodes(rctx)
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*string)
-	fc.Result = res
-	return ec.marshalOJSON2ᚖstring(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_activeWitnessNodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "Query",
-		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type JSON does not have child fields")
-		},
-	}
-	return fc, nil
-}
-
-func (ec *executionContext) _Query_witnessSchedule(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_witnessSchedule(ctx, field)
+func (ec *executionContext) _Query_witnessNodes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+	fc, err := ec.fieldContext_Query_witnessNodes(ctx, field)
 	if err != nil {
 		return graphql.Null
 	}
@@ -7323,7 +7042,7 @@ func (ec *executionContext) _Query_witnessSchedule(ctx context.Context, field gr
 	}()
 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
 		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().WitnessSchedule(rctx, fc.Args["height"].(model.Uint64))
+		return ec.resolvers.Query().WitnessNodes(rctx, fc.Args["height"].(model.Uint64))
 	})
 	if err != nil {
 		ec.Error(ctx, err)
@@ -7335,12 +7054,12 @@ func (ec *executionContext) _Query_witnessSchedule(ctx context.Context, field gr
 		}
 		return graphql.Null
 	}
-	res := resTmp.([]stateEngine.WitnessSlot)
+	res := resTmp.([]witnesses.Witness)
 	fc.Result = res
-	return ec.marshalNWitnessSlot2ᚕvscᚑnodeᚋmodulesᚋstateᚑprocessingᚐWitnessSlotᚄ(ctx, field.Selections, res)
+	return ec.marshalNWitness2ᚕvscᚑnodeᚋmodulesᚋdbᚋvscᚋwitnessesᚐWitnessᚄ(ctx, field.Selections, res)
 }
 
-func (ec *executionContext) fieldContext_Query_witnessSchedule(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_witnessNodes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
 	fc = &graphql.FieldContext{
 		Object:     "Query",
 		Field:      field,
@@ -7349,11 +7068,31 @@ func (ec *executionContext) fieldContext_Query_witnessSchedule(ctx context.Conte
 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
 			switch field.Name {
 			case "account":
-				return ec.fieldContext_WitnessSlot_account(ctx, field)
-			case "bn":
-				return ec.fieldContext_WitnessSlot_bn(ctx, field)
+				return ec.fieldContext_Witness_account(ctx, field)
+			case "height":
+				return ec.fieldContext_Witness_height(ctx, field)
+			case "did_keys":
+				return ec.fieldContext_Witness_did_keys(ctx, field)
+			case "enabled":
+				return ec.fieldContext_Witness_enabled(ctx, field)
+			case "git_commit":
+				return ec.fieldContext_Witness_git_commit(ctx, field)
+			case "net_id":
+				return ec.fieldContext_Witness_net_id(ctx, field)
+			case "peer_id":
+				return ec.fieldContext_Witness_peer_id(ctx, field)
+			case "protocol_version":
+				return ec.fieldContext_Witness_protocol_version(ctx, field)
+			case "ts":
+				return ec.fieldContext_Witness_ts(ctx, field)
+			case "tx_id":
+				return ec.fieldContext_Witness_tx_id(ctx, field)
+			case "version_id":
+				return ec.fieldContext_Witness_version_id(ctx, field)
+			case "gateway_key":
+				return ec.fieldContext_Witness_gateway_key(ctx, field)
 			}
-			return nil, fmt.Errorf("no field named %q was found under type WitnessSlot", field.Name)
+			return nil, fmt.Errorf("no field named %q was found under type Witness", field.Name)
 		},
 	}
 	defer func() {
@@ -7363,15 +7102,15 @@ func (ec *executionContext) fieldContext_Query_witnessSchedule(ctx context.Conte
 		}
 	}()
 	ctx = graphql.WithFieldContext(ctx, fc)
-	if fc.Args, err = ec.field_Query_witnessSchedule_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+	if fc.Args, err = ec.field_Query_witnessNodes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
 		ec.Error(ctx, err)
 		return fc, err
 	}
 	return fc, nil
 }
 
-func (ec *executionContext) _Query_nextWitnessSlot(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_nextWitnessSlot(ctx, field)
+func (ec *executionContext) _Query_witnessSchedule(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+	fc, err := ec.fieldContext_Query_witnessSchedule(ctx, field)
 	if err != nil {
 		return graphql.Null
 	}
@@ -7384,80 +7123,37 @@ func (ec *executionContext) _Query_nextWitnessSlot(ctx context.Context, field gr
 	}()
 	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
 		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().NextWitnessSlot(rctx, fc.Args["self"].(*bool))
+		return ec.resolvers.Query().WitnessSchedule(rctx, fc.Args["height"].(model.Uint64))
 	})
 	if err != nil {
 		ec.Error(ctx, err)
 		return graphql.Null
 	}
 	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*string)
-	fc.Result = res
-	return ec.marshalOJSON2ᚖstring(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_nextWitnessSlot(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "Query",
-		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type JSON does not have child fields")
-		},
-	}
-	defer func() {
-		if r := recover(); r != nil {
-			err = ec.Recover(ctx, r)
-			ec.Error(ctx, err)
-		}
-	}()
-	ctx = graphql.WithFieldContext(ctx, fc)
-	if fc.Args, err = ec.field_Query_nextWitnessSlot_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
-		ec.Error(ctx, err)
-		return fc, err
-	}
-	return fc, nil
-}
-
-func (ec *executionContext) _Query_witnessActiveScore(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_witnessActiveScore(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
+		if !graphql.HasFieldError(ctx, fc) {
+			ec.Errorf(ctx, "must not be null")
 		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().WitnessActiveScore(rctx, fc.Args["height"].(*int))
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
 		return graphql.Null
 	}
-	res := resTmp.(*string)
+	res := resTmp.([]stateEngine.WitnessSlot)
 	fc.Result = res
-	return ec.marshalOJSON2ᚖstring(ctx, field.Selections, res)
+	return ec.marshalNWitnessSlot2ᚕvscᚑnodeᚋmodulesᚋstateᚑprocessingᚐWitnessSlotᚄ(ctx, field.Selections, res)
 }
 
-func (ec *executionContext) fieldContext_Query_witnessActiveScore(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_witnessSchedule(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
 	fc = &graphql.FieldContext{
 		Object:     "Query",
 		Field:      field,
 		IsMethod:   true,
 		IsResolver: true,
 		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type JSON does not have child fields")
+			switch field.Name {
+			case "account":
+				return ec.fieldContext_WitnessSlot_account(ctx, field)
+			case "bn":
+				return ec.fieldContext_WitnessSlot_bn(ctx, field)
+			}
+			return nil, fmt.Errorf("no field named %q was found under type WitnessSlot", field.Name)
 		},
 	}
 	defer func() {
@@ -7467,144 +7163,13 @@ func (ec *executionContext) fieldContext_Query_witnessActiveScore(ctx context.Co
 		}
 	}()
 	ctx = graphql.WithFieldContext(ctx, fc)
-	if fc.Args, err = ec.field_Query_witnessActiveScore_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+	if fc.Args, err = ec.field_Query_witnessSchedule_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
 		ec.Error(ctx, err)
 		return fc, err
 	}
 	return fc, nil
 }
 
-func (ec *executionContext) _Query_mockGenerateElection(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_mockGenerateElection(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().MockGenerateElection(rctx)
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*string)
-	fc.Result = res
-	return ec.marshalOJSON2ᚖstring(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_mockGenerateElection(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "Query",
-		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type JSON does not have child fields")
-		},
-	}
-	return fc, nil
-}
-
-func (ec *executionContext) _Query_anchorProducer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_anchorProducer(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().AnchorProducer(rctx)
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*AnchorProducer)
-	fc.Result = res
-	return ec.marshalOAnchorProducer2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐAnchorProducer(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_anchorProducer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "Query",
-		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			switch field.Name {
-			case "nextSlot":
-				return ec.fieldContext_AnchorProducer_nextSlot(ctx, field)
-			}
-			return nil, fmt.Errorf("no field named %q was found under type AnchorProducer", field.Name)
-		},
-	}
-	return fc, nil
-}
-
-func (ec *executionContext) _Query_getCurrentNumber(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_Query_getCurrentNumber(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return ec.resolvers.Query().GetCurrentNumber(rctx)
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*TestResult)
-	fc.Result = res
-	return ec.marshalOTestResult2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐTestResult(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_getCurrentNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "Query",
-		Field:      field,
-		IsMethod:   true,
-		IsResolver: true,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			switch field.Name {
-			case "currentNumber":
-				return ec.fieldContext_TestResult_currentNumber(ctx, field)
-			}
-			return nil, fmt.Errorf("no field named %q was found under type TestResult", field.Name)
-		},
-	}
-	return fc, nil
-}
-
 func (ec *executionContext) _Query_witnessStake(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_Query_witnessStake(ctx, field)
 	if err != nil {
@@ -8054,47 +7619,6 @@ func (ec *executionContext) fieldContext_RcRecord_block_height(_ context.Context
 	return fc, nil
 }
 
-func (ec *executionContext) _TestResult_currentNumber(ctx context.Context, field graphql.CollectedField, obj *TestResult) (ret graphql.Marshaler) {
-	fc, err := ec.fieldContext_TestResult_currentNumber(ctx, field)
-	if err != nil {
-		return graphql.Null
-	}
-	ctx = graphql.WithFieldContext(ctx, fc)
-	defer func() {
-		if r := recover(); r != nil {
-			ec.Error(ctx, ec.Recover(ctx, r))
-			ret = graphql.Null
-		}
-	}()
-	resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
-		ctx = rctx // use context from middleware stack in children
-		return obj.CurrentNumber, nil
-	})
-	if err != nil {
-		ec.Error(ctx, err)
-		return graphql.Null
-	}
-	if resTmp == nil {
-		return graphql.Null
-	}
-	res := resTmp.(*int)
-	fc.Result = res
-	return ec.marshalOInt2ᚖint(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_TestResult_currentNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
-	fc = &graphql.FieldContext{
-		Object:     "TestResult",
-		Field:      field,
-		IsMethod:   false,
-		IsResolver: false,
-		Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
-			return nil, errors.New("field of type Int does not have child fields")
-		},
-	}
-	return fc, nil
-}
-
 func (ec *executionContext) _TransactionData_op(ctx context.Context, field graphql.CollectedField, obj *TransactionData) (ret graphql.Marshaler) {
 	fc, err := ec.fieldContext_TransactionData_op(ctx, field)
 	if err != nil {
@@ -11854,49 +11378,13 @@ func (ec *executionContext) unmarshalInputTransactionFilter(ctx context.Context,
 		}
 	}
 
-	return it, nil
-}
-
-// endregion **************************** input.gotpl *****************************
-
-// region    ************************** interface.gotpl ***************************
-
-func (ec *executionContext) _BalanceAccessCondition(ctx context.Context, sel ast.SelectionSet, obj BalanceAccessCondition) graphql.Marshaler {
-	switch obj := (obj).(type) {
-	case nil:
-		return graphql.Null
-	default:
-		panic(fmt.Errorf("unexpected type %T", obj))
-	}
-}
-
-func (ec *executionContext) _BalanceController(ctx context.Context, sel ast.SelectionSet, obj BalanceController) graphql.Marshaler {
-	switch obj := (obj).(type) {
-	case nil:
-		return graphql.Null
-	default:
-		panic(fmt.Errorf("unexpected type %T", obj))
-	}
-}
-
-func (ec *executionContext) _BlockRef(ctx context.Context, sel ast.SelectionSet, obj BlockRef) graphql.Marshaler {
-	switch obj := (obj).(type) {
-	case nil:
-		return graphql.Null
-	default:
-		panic(fmt.Errorf("unexpected type %T", obj))
-	}
-}
-
-func (ec *executionContext) _DepositDrain(ctx context.Context, sel ast.SelectionSet, obj DepositDrain) graphql.Marshaler {
-	switch obj := (obj).(type) {
-	case nil:
-		return graphql.Null
-	default:
-		panic(fmt.Errorf("unexpected type %T", obj))
-	}
+	return it, nil
 }
 
+// endregion **************************** input.gotpl *****************************
+
+// region    ************************** interface.gotpl ***************************
+
 // endregion ************************** interface.gotpl ***************************
 
 // region    **************************** object.gotpl ****************************
@@ -12111,42 +11599,6 @@ func (ec *executionContext) _ActionRecord(ctx context.Context, sel ast.Selection
 	return out
 }
 
-var anchorProducerImplementors = []string{"AnchorProducer"}
-
-func (ec *executionContext) _AnchorProducer(ctx context.Context, sel ast.SelectionSet, obj *AnchorProducer) graphql.Marshaler {
-	fields := graphql.CollectFields(ec.OperationContext, sel, anchorProducerImplementors)
-
-	out := graphql.NewFieldSet(fields)
-	deferred := make(map[string]*graphql.FieldSet)
-	for i, field := range fields {
-		switch field.Name {
-		case "__typename":
-			out.Values[i] = graphql.MarshalString("AnchorProducer")
-		case "nextSlot":
-			out.Values[i] = ec._AnchorProducer_nextSlot(ctx, field, obj)
-		default:
-			panic("unknown field " + strconv.Quote(field.Name))
-		}
-	}
-	out.Dispatch(ctx)
-	if out.Invalids > 0 {
-		return graphql.Null
-	}
-
-	atomic.AddInt32(&ec.deferred, int32(len(deferred)))
-
-	for label, dfs := range deferred {
-		ec.processDeferredGroup(graphql.DeferredGroup{
-			Label:    label,
-			Path:     graphql.GetPath(ctx),
-			FieldSet: dfs,
-			Context:  ctx,
-		})
-	}
-
-	return out
-}
-
 var balanceRecordImplementors = []string{"BalanceRecord"}
 
 func (ec *executionContext) _BalanceRecord(ctx context.Context, sel ast.SelectionSet, obj *ledgerDb.BalanceRecord) graphql.Marshaler {
@@ -12447,6 +11899,42 @@ func (ec *executionContext) _BalanceRecord(ctx context.Context, sel ast.Selectio
 				continue
 			}
 
+			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
+		case "consensus_unstaking":
+			field := field
+
+			innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
+				defer func() {
+					if r := recover(); r != nil {
+						ec.Error(ctx, ec.Recover(ctx, r))
+					}
+				}()
+				res = ec._BalanceRecord_consensus_unstaking(ctx, field, obj)
+				if res == graphql.Null {
+					atomic.AddUint32(&fs.Invalids, 1)
+				}
+				return res
+			}
+
+			if field.Deferrable != nil {
+				dfs, ok := deferred[field.Deferrable.Label]
+				di := 0
+				if ok {
+					dfs.AddField(field)
+					di = len(dfs.Values) - 1
+				} else {
+					dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
+					deferred[field.Deferrable.Label] = dfs
+				}
+				dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
+					return innerFunc(ctx, dfs)
+				})
+
+				// don't run the out.Concurrently() call below
+				out.Values[i] = graphql.Null
+				continue
+			}
+
 			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
 		default:
 			panic("unknown field " + strconv.Quote(field.Name))
@@ -13624,52 +13112,6 @@ func (ec *executionContext) _LocalNodeInfo(ctx context.Context, sel ast.Selectio
 	return out
 }
 
-var mutationImplementors = []string{"Mutation"}
-
-func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {
-	fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors)
-	ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
-		Object: "Mutation",
-	})
-
-	out := graphql.NewFieldSet(fields)
-	deferred := make(map[string]*graphql.FieldSet)
-	for i, field := range fields {
-		innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{
-			Object: field.Name,
-			Field:  field,
-		})
-
-		switch field.Name {
-		case "__typename":
-			out.Values[i] = graphql.MarshalString("Mutation")
-		case "incrementNumber":
-			out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
-				return ec._Mutation_incrementNumber(ctx, field)
-			})
-		default:
-			panic("unknown field " + strconv.Quote(field.Name))
-		}
-	}
-	out.Dispatch(ctx)
-	if out.Invalids > 0 {
-		return graphql.Null
-	}
-
-	atomic.AddInt32(&ec.deferred, int32(len(deferred)))
-
-	for label, dfs := range deferred {
-		ec.processDeferredGroup(graphql.DeferredGroup{
-			Label:    label,
-			Path:     graphql.GetPath(ctx),
-			FieldSet: dfs,
-			Context:  ctx,
-		})
-	}
-
-	return out
-}
-
 var nonceRecordImplementors = []string{"NonceRecord"}
 
 func (ec *executionContext) _NonceRecord(ctx context.Context, sel ast.SelectionSet, obj *nonces.NonceRecord) graphql.Marshaler {
@@ -14219,19 +13661,16 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
 			}
 
 			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "witnessNodes":
+		case "getWitness":
 			field := field
 
-			innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
+			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
 				defer func() {
 					if r := recover(); r != nil {
 						ec.Error(ctx, ec.Recover(ctx, r))
 					}
 				}()
-				res = ec._Query_witnessNodes(ctx, field)
-				if res == graphql.Null {
-					atomic.AddUint32(&fs.Invalids, 1)
-				}
+				res = ec._Query_getWitness(ctx, field)
 				return res
 			}
 
@@ -14241,16 +13680,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
 			}
 
 			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "activeWitnessNodes":
+		case "witnessNodes":
 			field := field
 
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
+			innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
 				defer func() {
 					if r := recover(); r != nil {
 						ec.Error(ctx, ec.Recover(ctx, r))
 					}
 				}()
-				res = ec._Query_activeWitnessNodes(ctx, field)
+				res = ec._Query_witnessNodes(ctx, field)
+				if res == graphql.Null {
+					atomic.AddUint32(&fs.Invalids, 1)
+				}
 				return res
 			}
 
@@ -14281,101 +13723,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
 					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
 			}
 
-			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "nextWitnessSlot":
-			field := field
-
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
-				defer func() {
-					if r := recover(); r != nil {
-						ec.Error(ctx, ec.Recover(ctx, r))
-					}
-				}()
-				res = ec._Query_nextWitnessSlot(ctx, field)
-				return res
-			}
-
-			rrm := func(ctx context.Context) graphql.Marshaler {
-				return ec.OperationContext.RootResolverMiddleware(ctx,
-					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
-			}
-
-			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "witnessActiveScore":
-			field := field
-
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
-				defer func() {
-					if r := recover(); r != nil {
-						ec.Error(ctx, ec.Recover(ctx, r))
-					}
-				}()
-				res = ec._Query_witnessActiveScore(ctx, field)
-				return res
-			}
-
-			rrm := func(ctx context.Context) graphql.Marshaler {
-				return ec.OperationContext.RootResolverMiddleware(ctx,
-					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
-			}
-
-			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "mockGenerateElection":
-			field := field
-
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
-				defer func() {
-					if r := recover(); r != nil {
-						ec.Error(ctx, ec.Recover(ctx, r))
-					}
-				}()
-				res = ec._Query_mockGenerateElection(ctx, field)
-				return res
-			}
-
-			rrm := func(ctx context.Context) graphql.Marshaler {
-				return ec.OperationContext.RootResolverMiddleware(ctx,
-					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
-			}
-
-			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "anchorProducer":
-			field := field
-
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
-				defer func() {
-					if r := recover(); r != nil {
-						ec.Error(ctx, ec.Recover(ctx, r))
-					}
-				}()
-				res = ec._Query_anchorProducer(ctx, field)
-				return res
-			}
-
-			rrm := func(ctx context.Context) graphql.Marshaler {
-				return ec.OperationContext.RootResolverMiddleware(ctx,
-					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
-			}
-
-			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
-		case "getCurrentNumber":
-			field := field
-
-			innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
-				defer func() {
-					if r := recover(); r != nil {
-						ec.Error(ctx, ec.Recover(ctx, r))
-					}
-				}()
-				res = ec._Query_getCurrentNumber(ctx, field)
-				return res
-			}
-
-			rrm := func(ctx context.Context) graphql.Marshaler {
-				return ec.OperationContext.RootResolverMiddleware(ctx,
-					func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
-			}
-
 			out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) })
 		case "witnessStake":
 			field := field
@@ -14582,42 +13929,6 @@ func (ec *executionContext) _RcRecord(ctx context.Context, sel ast.SelectionSet,
 	return out
 }
 
-var testResultImplementors = []string{"TestResult"}
-
-func (ec *executionContext) _TestResult(ctx context.Context, sel ast.SelectionSet, obj *TestResult) graphql.Marshaler {
-	fields := graphql.CollectFields(ec.OperationContext, sel, testResultImplementors)
-
-	out := graphql.NewFieldSet(fields)
-	deferred := make(map[string]*graphql.FieldSet)
-	for i, field := range fields {
-		switch field.Name {
-		case "__typename":
-			out.Values[i] = graphql.MarshalString("TestResult")
-		case "currentNumber":
-			out.Values[i] = ec._TestResult_currentNumber(ctx, field, obj)
-		default:
-			panic("unknown field " + strconv.Quote(field.Name))
-		}
-	}
-	out.Dispatch(ctx)
-	if out.Invalids > 0 {
-		return graphql.Null
-	}
-
-	atomic.AddInt32(&ec.deferred, int32(len(deferred)))
-
-	for label, dfs := range deferred {
-		ec.processDeferredGroup(graphql.DeferredGroup{
-			Label:    label,
-			Path:     graphql.GetPath(ctx),
-			FieldSet: dfs,
-			Context:  ctx,
-		})
-	}
-
-	return out
-}
-
 var transactionDataImplementors = []string{"TransactionData"}
 
 func (ec *executionContext) _TransactionData(ctx context.Context, sel ast.SelectionSet, obj *TransactionData) graphql.Marshaler {
@@ -16276,13 +15587,6 @@ func (ec *executionContext) marshalOActionRecord2ᚕvscᚑnodeᚋmodulesᚋdbᚋ
 	return ret
 }
 
-func (ec *executionContext) marshalOAnchorProducer2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐAnchorProducer(ctx context.Context, sel ast.SelectionSet, v *AnchorProducer) graphql.Marshaler {
-	if v == nil {
-		return graphql.Null
-	}
-	return ec._AnchorProducer(ctx, sel, v)
-}
-
 func (ec *executionContext) unmarshalOAsset2ᚖvscᚑnodeᚋmodulesᚋdbᚋvscᚋledgerᚐAsset(ctx context.Context, v any) (*ledgerDb.Asset, error) {
 	if v == nil {
 		return nil, nil
@@ -16676,13 +15980,6 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as
 	return res
 }
 
-func (ec *executionContext) marshalOTestResult2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐTestResult(ctx context.Context, sel ast.SelectionSet, v *TestResult) graphql.Marshaler {
-	if v == nil {
-		return graphql.Null
-	}
-	return ec._TestResult(ctx, sel, v)
-}
-
 func (ec *executionContext) unmarshalOTransactionFilter2ᚖvscᚑnodeᚋmodulesᚋgqlᚋgqlgenᚐTransactionFilter(ctx context.Context, v any) (*TransactionFilter, error) {
 	if v == nil {
 		return nil, nil
@@ -16778,6 +16075,13 @@ func (ec *executionContext) marshalOUint642ᚖvscᚑnodeᚋmodulesᚋgqlᚋmodel
 	return v
 }
 
+func (ec *executionContext) marshalOWitness2ᚖvscᚑnodeᚋmodulesᚋdbᚋvscᚋwitnessesᚐWitness(ctx context.Context, sel ast.SelectionSet, v *witnesses.Witness) graphql.Marshaler {
+	if v == nil {
+		return graphql.Null
+	}
+	return ec._Witness(ctx, sel, v)
+}
+
 func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {
 	if v == nil {
 		return graphql.Null
diff --git a/modules/gql/gqlgen/models.go b/modules/gql/gqlgen/models.go
index 75c9273b..e0a4239b 100644
--- a/modules/gql/gqlgen/models.go
+++ b/modules/gql/gqlgen/models.go
@@ -3,46 +3,12 @@
 package gqlgen
 
 import (
-	"fmt"
-	"io"
-	"strconv"
 	"vsc-node/modules/db/vsc/contracts"
 	ledgerDb "vsc-node/modules/db/vsc/ledger"
 	"vsc-node/modules/db/vsc/transactions"
 	"vsc-node/modules/gql/model"
 )
 
-type BalanceAccessCondition interface {
-	IsBalanceAccessCondition()
-	GetType() *BalanceAccessConditionType
-	GetValue() *string
-}
-
-type BalanceController interface {
-	IsBalanceController()
-	GetType() *BalanceControllerType
-	GetAuthority() *string
-	GetConditions() []BalanceAccessCondition
-}
-
-type BlockRef interface {
-	IsBlockRef()
-	GetBlockRef() *string
-	GetIncludedBlock() *int
-}
-
-type DepositDrain interface {
-	IsDepositDrain()
-	GetDepositID() *string
-	GetAmount() *float64
-	GetToken() *string
-	GetOwner() *string
-}
-
-type AnchorProducer struct {
-	NextSlot *string `json:"nextSlot,omitempty"`
-}
-
 type Contract struct {
 	ID         *string `json:"id,omitempty"`
 	Code       *string `json:"code,omitempty"`
@@ -104,16 +70,9 @@ type LocalNodeInfo struct {
 	Epoch              model.Uint64 `json:"epoch"`
 }
 
-type Mutation struct {
-}
-
 type Query struct {
 }
 
-type TestResult struct {
-	CurrentNumber *int `json:"currentNumber,omitempty"`
-}
-
 type TransactionData struct {
 	Op         string  `json:"op"`
 	Action     *string `json:"action,omitempty"`
@@ -142,136 +101,3 @@ type TransactionOutput struct {
 type TransactionSubmitResult struct {
 	ID *string `json:"id,omitempty"`
 }
-
-type BalanceAccessConditionType string
-
-const (
-	BalanceAccessConditionTypeTime     BalanceAccessConditionType = "TIME"
-	BalanceAccessConditionTypeHash     BalanceAccessConditionType = "HASH"
-	BalanceAccessConditionTypeWithdraw BalanceAccessConditionType = "WITHDRAW"
-)
-
-var AllBalanceAccessConditionType = []BalanceAccessConditionType{
-	BalanceAccessConditionTypeTime,
-	BalanceAccessConditionTypeHash,
-	BalanceAccessConditionTypeWithdraw,
-}
-
-func (e BalanceAccessConditionType) IsValid() bool {
-	switch e {
-	case BalanceAccessConditionTypeTime, BalanceAccessConditionTypeHash, BalanceAccessConditionTypeWithdraw:
-		return true
-	}
-	return false
-}
-
-func (e BalanceAccessConditionType) String() string {
-	return string(e)
-}
-
-func (e *BalanceAccessConditionType) UnmarshalGQL(v any) error {
-	str, ok := v.(string)
-	if !ok {
-		return fmt.Errorf("enums must be strings")
-	}
-
-	*e = BalanceAccessConditionType(str)
-	if !e.IsValid() {
-		return fmt.Errorf("%s is not a valid BalanceAccessConditionType", str)
-	}
-	return nil
-}
-
-func (e BalanceAccessConditionType) MarshalGQL(w io.Writer) {
-	fmt.Fprint(w, strconv.Quote(e.String()))
-}
-
-type BalanceControllerType string
-
-const (
-	BalanceControllerTypeHive     BalanceControllerType = "HIVE"
-	BalanceControllerTypeDid      BalanceControllerType = "DID"
-	BalanceControllerTypeContract BalanceControllerType = "CONTRACT"
-)
-
-var AllBalanceControllerType = []BalanceControllerType{
-	BalanceControllerTypeHive,
-	BalanceControllerTypeDid,
-	BalanceControllerTypeContract,
-}
-
-func (e BalanceControllerType) IsValid() bool {
-	switch e {
-	case BalanceControllerTypeHive, BalanceControllerTypeDid, BalanceControllerTypeContract:
-		return true
-	}
-	return false
-}
-
-func (e BalanceControllerType) String() string {
-	return string(e)
-}
-
-func (e *BalanceControllerType) UnmarshalGQL(v any) error {
-	str, ok := v.(string)
-	if !ok {
-		return fmt.Errorf("enums must be strings")
-	}
-
-	*e = BalanceControllerType(str)
-	if !e.IsValid() {
-		return fmt.Errorf("%s is not a valid BalanceControllerType", str)
-	}
-	return nil
-}
-
-func (e BalanceControllerType) MarshalGQL(w io.Writer) {
-	fmt.Fprint(w, strconv.Quote(e.String()))
-}
-
-type TransactionType string
-
-const (
-	TransactionTypeNull    TransactionType = "NULL"
-	TransactionTypeInput   TransactionType = "INPUT"
-	TransactionTypeOutput  TransactionType = "OUTPUT"
-	TransactionTypeVirtual TransactionType = "VIRTUAL"
-	TransactionTypeCore    TransactionType = "CORE"
-)
-
-var AllTransactionType = []TransactionType{
-	TransactionTypeNull,
-	TransactionTypeInput,
-	TransactionTypeOutput,
-	TransactionTypeVirtual,
-	TransactionTypeCore,
-}
-
-func (e TransactionType) IsValid() bool {
-	switch e {
-	case TransactionTypeNull, TransactionTypeInput, TransactionTypeOutput, TransactionTypeVirtual, TransactionTypeCore:
-		return true
-	}
-	return false
-}
-
-func (e TransactionType) String() string {
-	return string(e)
-}
-
-func (e *TransactionType) UnmarshalGQL(v any) error {
-	str, ok := v.(string)
-	if !ok {
-		return fmt.Errorf("enums must be strings")
-	}
-
-	*e = TransactionType(str)
-	if !e.IsValid() {
-		return fmt.Errorf("%s is not a valid TransactionType", str)
-	}
-	return nil
-}
-
-func (e TransactionType) MarshalGQL(w io.Writer) {
-	fmt.Fprint(w, strconv.Quote(e.String()))
-}
diff --git a/modules/gql/gqlgen/schema.resolvers.go b/modules/gql/gqlgen/schema.resolvers.go
index 13f7f881..88c7f4a2 100644
--- a/modules/gql/gqlgen/schema.resolvers.go
+++ b/modules/gql/gqlgen/schema.resolvers.go
@@ -86,6 +86,12 @@ func (r *balanceRecordResolver) HiveConsensus(ctx context.Context, obj *ledgerDb
 	return model.Int64(obj.HIVE_CONSENSUS), nil
 }
 
+// ConsensusUnstaking is the resolver for the consensus_unstaking field.
+func (r *balanceRecordResolver) ConsensusUnstaking(ctx context.Context, obj *ledgerDb.BalanceRecord) (model.Int64, error) {
+	amt, err := r.Actions.GetAccountPendingConsensusUnstake(obj.Account)
+	return model.Int64(amt), err
+}
+
 // AnchoredBlock is the resolver for the anchored_block field.
 func (r *contractOutputResolver) AnchoredBlock(ctx context.Context, obj *contracts.ContractOutput) (*string, error) {
 	panic(fmt.Errorf("not implemented: AnchoredBlock - anchored_block"))
@@ -185,11 +191,6 @@ func (r *ledgerRecordResolver) BlockHeight(ctx context.Context, obj *ledgerDb.Le
 	return model.Uint64(obj.BlockHeight), nil
 }
 
-// IncrementNumber is the resolver for the incrementNumber field.
-func (r *mutationResolver) IncrementNumber(ctx context.Context) (*TestResult, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
 // Nonce is the resolver for the nonce field.
 func (r *nonceRecordResolver) Nonce(ctx context.Context, obj *nonces.NonceRecord) (model.Uint64, error) {
 	return model.Uint64(obj.Nonce), nil
@@ -277,15 +278,9 @@ func (r *queryResolver) GetAccountBalance(ctx context.Context, account string, h
 	if account == "" {
 		return nil, fmt.Errorf("account parameter cannot be empty")
 	}
-	var blockHeight uint64
-	if height != nil {
-		blockHeight = uint64(*height)
-	} else {
-		head, headErr := r.HiveBlocks.GetLastProcessedBlock()
-		if headErr != nil {
-			return nil, headErr
-		}
-		blockHeight = head
+	blockHeight, err := ParseHeight(height)
+	if err != nil {
+		return nil, err
 	}
 	return r.Balances.GetBalanceRecord(account, blockHeight)
 }
@@ -295,15 +290,9 @@ func (r *queryResolver) GetAccountRc(ctx context.Context, account string, height
 	if account == "" {
 		return nil, fmt.Errorf("account parameter cannot be empty")
 	}
-	var blockHeight uint64
-	if height != nil {
-		blockHeight = uint64(*height)
-	} else {
-		head, headErr := r.HiveBlocks.GetLastProcessedBlock()
-		if headErr != nil {
-			return nil, headErr
-		}
-		blockHeight = head
+	blockHeight, err := ParseHeight(height)
+	if err != nil {
+		return nil, err
 	}
 	rc, err := r.Rc.GetRecord(account, blockHeight)
 	return &rc, err
@@ -356,16 +345,20 @@ func (r *queryResolver) LocalNodeInfo(ctx context.Context) (*LocalNodeInfo, erro
 	return &LocalNodeInfo{GitCommit: announcements.GitCommit, VersionID: announcements.VersionId, LastProcessedBlock: model.Uint64(head), Epoch: model.Uint64(election.Epoch)}, nil
 }
 
+// GetWitness is the resolver for the getWitness field.
+func (r *queryResolver) GetWitness(ctx context.Context, account string, height *model.Uint64) (*witnesses.Witness, error) {
+	blockHeight, err := ParseHeight(height)
+	if err != nil {
+		return nil, err
+	}
+	return r.Witnesses.GetWitnessAtHeight(account, &blockHeight)
+}
+
 // WitnessNodes is the resolver for the witnessNodes field.
 func (r *queryResolver) WitnessNodes(ctx context.Context, height model.Uint64) ([]witnesses.Witness, error) {
 	return r.Witnesses.GetWitnessesAtBlockHeight(uint64(height))
 }
 
-// ActiveWitnessNodes is the resolver for the activeWitnessNodes field.
-func (r *queryResolver) ActiveWitnessNodes(ctx context.Context) (*string, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
 // WitnessSchedule is the resolver for the witnessSchedule field.
 func (r *queryResolver) WitnessSchedule(ctx context.Context, height model.Uint64) ([]stateEngine.WitnessSlot, error) {
 	slotInfo := stateEngine.CalculateSlotInfo(uint64(height))
@@ -373,31 +366,6 @@ func (r *queryResolver) WitnessSchedule(ctx context.Context, height model.Uint64
 	return schedule, nil
 }
 
-// NextWitnessSlot is the resolver for the nextWitnessSlot field.
-func (r *queryResolver) NextWitnessSlot(ctx context.Context, self *bool) (*string, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
-// WitnessActiveScore is the resolver for the witnessActiveScore field.
-func (r *queryResolver) WitnessActiveScore(ctx context.Context, height *int) (*string, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
-// MockGenerateElection is the resolver for the mockGenerateElection field.
-func (r *queryResolver) MockGenerateElection(ctx context.Context) (*string, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
-// AnchorProducer is the resolver for the anchorProducer field.
-func (r *queryResolver) AnchorProducer(ctx context.Context) (*AnchorProducer, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
-// GetCurrentNumber is the resolver for the getCurrentNumber field.
-func (r *queryResolver) GetCurrentNumber(ctx context.Context) (*TestResult, error) {
-	panic(fmt.Errorf("not implemented"))
-}
-
 // WitnessStake is the resolver for the witnessStake field.
 func (r *queryResolver) WitnessStake(ctx context.Context, account string) (model.Uint64, error) {
 	res, err := r.Balances.GetBalanceRecord(account, uint64(math.MaxInt64))
@@ -514,9 +482,6 @@ func (r *Resolver) ElectionResult() ElectionResultResolver { return &electionRes
 // LedgerRecord returns LedgerRecordResolver implementation.
 func (r *Resolver) LedgerRecord() LedgerRecordResolver { return &ledgerRecordResolver{r} }
 
-// Mutation returns MutationResolver implementation.
-func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }
-
 // NonceRecord returns NonceRecordResolver implementation.
 func (r *Resolver) NonceRecord() NonceRecordResolver { return &nonceRecordResolver{r} }
 
@@ -549,7 +514,6 @@ type contractOutputResolver struct{ *Resolver }
 type contractStateResolver struct{ *Resolver }
 type electionResultResolver struct{ *Resolver }
 type ledgerRecordResolver struct{ *Resolver }
-type mutationResolver struct{ *Resolver }
 type nonceRecordResolver struct{ *Resolver }
 type opLogEventResolver struct{ *Resolver }
 type postingJsonKeysResolver struct{ *Resolver }
diff --git a/modules/gql/gqlgen/pagination.go b/modules/gql/gqlgen/utils.go
similarity index 64%
rename from modules/gql/gqlgen/pagination.go
rename to modules/gql/gqlgen/utils.go
index 90a91852..fee68f24 100644
--- a/modules/gql/gqlgen/pagination.go
+++ b/modules/gql/gqlgen/utils.go
@@ -1,6 +1,10 @@
 package gqlgen
 
-import "fmt"
+import (
+	"fmt"
+	"math"
+	"vsc-node/modules/gql/model"
+)
 
 // Helper function for handling offset-limit pagination. Returns offset, limit and error.
 func Paginate(offset *int, limit *int) (int, int, error) {
@@ -22,3 +26,14 @@ func Paginate(offset *int, limit *int) (int, int, error) {
 	}
 	return offset_result, limit_result, nil
 }
+
+// Parse optional height, falling back to last processed block if not specified
+func ParseHeight(height *model.Uint64) (uint64, error) {
+	var blockHeight uint64
+	if height != nil {
+		blockHeight = uint64(*height)
+	} else {
+		blockHeight = math.MaxUint64
+	}
+	return blockHeight, nil
+}
diff --git a/modules/gql/schema.graphql b/modules/gql/schema.graphql
index dff122ab..eb36f0b4 100644
--- a/modules/gql/schema.graphql
+++ b/modules/gql/schema.graphql
@@ -21,14 +21,6 @@ enum Asset {
   hbd_savings
 }
 
-enum TransactionType {
-  NULL
-  INPUT
-  OUTPUT
-  VIRTUAL
-  CORE
-}
-
 type TransactionRecord {
   id: String!
   anchr_height: Uint64!
@@ -145,41 +137,6 @@ type WitnessSlot {
   bn: Uint64!
 }
 
-interface BalanceController {
-  type: BalanceControllerType
-  authority: String
-  conditions: [BalanceAccessCondition]
-}
-
-enum BalanceControllerType {
-  HIVE
-  DID
-  CONTRACT
-}
-
-interface BalanceAccessCondition {
-  type: BalanceAccessConditionType
-  value: String
-}
-
-enum BalanceAccessConditionType {
-  TIME
-  HASH
-  WITHDRAW
-}
-
-interface DepositDrain {
-  deposit_id: String
-  amount: Float
-  token: String
-  owner: String
-}
-
-interface BlockRef {
-  block_ref: String
-  included_block: Int
-}
-
 type BalanceRecord {
   account: String
   block_height: Uint64!
@@ -190,6 +147,7 @@ type BalanceRecord {
   hbd_savings: Int64!
   hive: Int64!
   hive_consensus: Int64!
+  consensus_unstaking: Int64!
 }
 
 type RcRecord {
@@ -202,10 +160,6 @@ type FindContractOutputResult {
   outputs: [ContractOutput]
 }
 
-type AnchorProducer {
-  nextSlot(account: String): JSON
-}
-
 type LedgerRecord {
   id: String!
   amount: Int64!
@@ -311,14 +265,9 @@ type Query {
   submitTransactionV1(tx: String!, sig: String!): TransactionSubmitResult
   getAccountNonce(account: String!): NonceRecord
   localNodeInfo: LocalNodeInfo
+  getWitness(account: String!, height: Uint64): Witness
   witnessNodes(height: Uint64!): [Witness!]!
-  activeWitnessNodes: JSON
   witnessSchedule(height: Uint64!): [WitnessSlot!]!
-  nextWitnessSlot(self: Boolean): JSON
-  witnessActiveScore(height: Int): JSON
-  mockGenerateElection: JSON
-  anchorProducer: AnchorProducer
-  getCurrentNumber: TestResult # TESTING QUERY
   witnessStake(account: String!): Uint64!
   getDagByCID(cidString: String!): JSON!
   getElection(epoch: Uint64!): ElectionResult
@@ -328,12 +277,3 @@ scalar Uint64
 scalar Int64
 scalar Map
 scalar DateTime
-
-type Mutation {
-  incrementNumber: TestResult # TESTING MUTATION
-}
-
-# TESTING TYPE
-type TestResult {
-  currentNumber: Int
-}


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (3)</summary><blockquote>

<details>
<summary>modules/gql/gqlgen/generated.go (3)</summary><blockquote>

`509-518`: **Safety guard works but does not log ‑ consider observability**  

The new `case "BalanceRecord.consensus_unstaking":` block bails out silently when the complexity func is `nil`.  Adding a debug log (behind a build tag) or a metrics counter can surface accidental omissions early in staging environments.

---

`1175-1186`: **Argument parsing uses `context.TODO()` – keep downstream middle-wares in mind**  

The auto-generated argument helper still relies on `context.TODO()`.  
If any of your parsers/middle-wares rely on values from the incoming request context (e.g. tracing/span IDs), they will be lost here.  

Although this is the default behaviour of gqlgen, you can patch the template once to pass the caller’s `ctx` instead so it propagates trace information:

```diff
- args, err := ec.field_Query_getWitness_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query_getWitness_args(ctx, rawArgs)
```

---

`3529-3557`: **Resolver returns non-null but code still checks for `nil`**  

`consensus_unstaking` is declared as `Int64!` (non-nullable).  
The generated wrapper still checks `if resTmp == nil { … }`, which can never happen if your resolver returns the concrete `model.Int64` type.  

Not a functional bug, just redundant branching that makes the flow harder to read; feel free to leave it (it comes from gqlgen templates) or clean it up if you maintain custom templates.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 6ee8207af2f570dc309e9c4faa9c3bbc571705f9 and bd2bb96fac88235ad96d09b4263b8c83bacaaa9b.

</details>

<details>
<summary>📒 Files selected for processing (7)</summary>

* `modules/db/vsc/ledger/ledger.go` (2 hunks)
* `modules/db/vsc/ledger/types.go` (1 hunks)
* `modules/gql/gqlgen/generated.go` (22 hunks)
* `modules/gql/gqlgen/models.go` (0 hunks)
* `modules/gql/gqlgen/schema.resolvers.go` (4 hunks)
* `modules/gql/gqlgen/utils.go` (2 hunks)
* `modules/gql/schema.graphql` (2 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* modules/gql/gqlgen/models.go

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (2)</summary>

<details>
<summary>modules/gql/gqlgen/schema.resolvers.go (6)</summary><blockquote>

<details>
<summary>modules/db/vsc/ledger/types.go (1)</summary>

* `BalanceRecord` (46-56)

</details>
<details>
<summary>modules/gql/model/Int64.go (1)</summary>

* `Int64` (10-10)

</details>
<details>
<summary>modules/gql/gqlgen/utils.go (1)</summary>

* `ParseHeight` (31-43)

</details>
<details>
<summary>modules/db/vsc/hive_blocks/interface.go (1)</summary>

* `HiveBlocks` (8-20)

</details>
<details>
<summary>modules/gql/model/Uint64.go (1)</summary>

* `Uint64` (10-10)

</details>
<details>
<summary>modules/db/vsc/witnesses/interface.go (1)</summary>

* `Witnesses` (5-13)

</details>

</blockquote></details>
<details>
<summary>modules/gql/gqlgen/utils.go (2)</summary><blockquote>

<details>
<summary>modules/db/vsc/hive_blocks/interface.go (1)</summary>

* `HiveBlocks` (8-20)

</details>
<details>
<summary>modules/gql/model/Uint64.go (1)</summary>

* `Uint64` (10-10)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (11)</summary><blockquote>

<details>
<summary>modules/db/vsc/ledger/types.go (1)</summary>

`104-104`: **Interface extension for consensus unstaking tracking.**

The new method `GetAccountPendingConsensusUnstake` is a good addition to the `BridgeActions` interface that enables querying for pending consensus unstake amounts for a specific account.

</details>
<details>
<summary>modules/gql/gqlgen/utils.go (2)</summary>

`3-7`: **Appropriate import additions.**

The added imports for hive_blocks and model packages are necessary to support the new ParseHeight utility function.

---

`30-43`: **Well-structured utility function for height resolution.**

The `ParseHeight` function centralizes the common logic of resolving an optional height parameter, falling back to the last processed block height when not specified. This is a good refactoring that will reduce code duplication across resolvers.


The function correctly handles:
1. Explicit height conversion when provided
2. Fallback to the last processed block when height is nil
3. Proper error propagation

</details>
<details>
<summary>modules/db/vsc/ledger/ledger.go (1)</summary>

`410-437`: **Clean implementation of consensus unstaking aggregation.**

The implementation of `GetAccountPendingConsensusUnstake` correctly uses MongoDB's aggregation pipeline to calculate the total pending unstake amount for an account.


The function:
1. Uses a match stage to filter for the correct account, pending status, and consensus_unstake type
2. Uses a group stage to sum the amount field
3. Properly handles the cursor and decoding of results
4. Returns sensible default values (0 when no matching records, -1 with error on failure)

</details>
<details>
<summary>modules/gql/schema.graphql (2)</summary>

`193-193`: **New field added for tracking pending unstakes.**

The addition of `consensus_unstaking: Int64!` to the BalanceRecord type allows clients to query the amount of tokens that are in the process of being unstaked from consensus, which aligns with the PR objective.

---

`311-311`: **New GraphQL query for retrieving witness information.**

The new `getWitness` query allows fetching details for a specific witness by account name, with an optional height parameter to query historical data. This is a more targeted approach compared to the removed queries, making it more efficient for client applications.

</details>
<details>
<summary>modules/gql/gqlgen/schema.resolvers.go (4)</summary>

`89-93`: **Well-implemented resolver for new consensus_unstaking field**

The implementation correctly retrieves pending unstake amounts using the `GetAccountPendingConsensusUnstake` method and properly converts the result to the expected GraphQL type. The error handling is appropriate as it passes through any errors from the underlying service.

---

`286-288`: **Good refactoring to use the ParseHeight utility function**

Replacing inline height resolution logic with the shared `ParseHeight` utility function improves code maintainability and consistency. Error handling is properly implemented.

---

`298-300`: **Consistent refactoring for GetAccountRc using ParseHeight**

This change follows the same pattern as the GetAccountBalance refactoring, using the shared `ParseHeight` utility function. This ensures consistent block height resolution across resolvers.

---

`353-360`: **Well-implemented GetWitness resolver**

The new resolver correctly implements the functionality to retrieve a single witness record at a specific block height. It properly utilizes the `ParseHeight` utility function for block height resolution and calls the appropriate method on the Witnesses service. Error handling is properly implemented.

</details>
<details>
<summary>modules/gql/gqlgen/generated.go (1)</summary>

`7101-7163`: **`GetWitness` resolver: verify that `ParseHeight` handles `nil` safely**  

`GetWitness` ultimately delegates to your custom resolver (`schema.resolvers.go`).  
Because `height` is `*model.Uint64`, double-check that the helper `ParseHeight` gracefully handles:

1. `height == nil` – should fall back to latest processed block
2. `height != nil && *height == 0` – should probably be rejected rather than interpreted as HEAD

Unit-testing both paths now will prevent subtle off-by-one issues later.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-09T07:27:58Z
user: login: techcoderx
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-09T07:35:04Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-09T07:35:21Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>♻️ Duplicate comments (2)</summary><blockquote>

<details>
<summary>modules/gql/gqlgen/generated.go (2)</summary><blockquote>

`86-96`: **Code structure looks good, but don't forget to define the complexity function**

The `ConsensusUnstaking` field has been correctly added to the `BalanceRecord` complexity struct. Make sure you explicitly define a non-zero cost function for this field in your `gqlgen.yml` or complexity.go file, otherwise, it will be treated as "free" in the query planner.

```go
complexity:
  BalanceRecord:
    ConsensusUnstaking: func(childComplexity int) int { return 5 + childComplexity }
```

Choose an appropriate cost value based on the aggregation complexity of fetching unstaking data.

---

`207-227`: **Ensure query complexity functions are defined properly**

The `GetWitness` query has been added to the complexity structure. Remember to explicitly define a non-zero cost function for this query in your `gqlgen.yml` configuration or complexity.go file.

```go
complexity:
  Query:
    GetWitness: func(childComplexity int, _ string, _ *model.Uint64) int { return 10 + childComplexity }
```

This will ensure the query planner correctly accounts for the cost of retrieving witness data.

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>modules/gql/schema.graphql (2)</summary><blockquote>

`150-150`: **Verify `consensus_unstaking` resolver and add schema documentation**  
Ensure that the resolver for the newly added `consensus_unstaking: Int64!` field on `BalanceRecord` always returns a non-null integer (use 0 when there are no pending unstakings). Also, consider adding a descriptive comment above this field to improve schema introspection and generated docs.  
   
Example diff:
```diff
 type BalanceRecord {
   hive_consensus: Int64!
+  # Total pending consensus unstake amount for this account at the specified block height.
+  consensus_unstaking: Int64!
 }
```

---

`268-268`: **Document the new `getWitness` query in the schema**  
The addition of `getWitness(account: String!, height: Uint64): Witness` should be accompanied by a schema description to clarify its behavior—particularly how the optional `height` parameter is resolved (e.g., defaults to the latest processed block). Please update any generated documentation and client-side queries accordingly.  

Example diff:
```diff
 type Query {
   ...
+  # Retrieves witness metadata for the given account at the specified block height (defaults to latest if omitted).
+  getWitness(account: String!, height: Uint64): Witness
   ...
 }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between bd2bb96fac88235ad96d09b4263b8c83bacaaa9b and 70d3b41324214b6ef90db35895f8d09261949173.

</details>

<details>
<summary>📒 Files selected for processing (4)</summary>

* `modules/gql/gqlgen/generated.go` (21 hunks)
* `modules/gql/gqlgen/models.go` (0 hunks)
* `modules/gql/gqlgen/schema.resolvers.go` (4 hunks)
* `modules/gql/schema.graphql` (2 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* modules/gql/gqlgen/models.go

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* modules/gql/gqlgen/schema.resolvers.go

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (1)</summary>

<details>
<summary>modules/gql/gqlgen/generated.go (5)</summary><blockquote>

<details>
<summary>modules/gql/gqlgen/models.go (6)</summary>

* `FindContractOutputFilter` (23-28)
* `LedgerActionsFilter` (42-53)
* `LedgerTxFilter` (55-64)
* `TransactionFilter` (90-101)
* `LocalNodeInfo` (66-71)
* `Query` (76-77)

</details>
<details>
<summary>modules/gql/model/Uint64.go (1)</summary>

* `Uint64` (10-10)

</details>
<details>
<summary>modules/db/vsc/ledger/types.go (1)</summary>

* `BalanceRecord` (46-56)

</details>
<details>
<summary>modules/gql/model/Int64.go (1)</summary>

* `Int64` (10-10)

</details>
<details>
<summary>modules/state-processing/consensus.go (1)</summary>

* `WitnessSlot` (62-65)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (8)</summary><blockquote>

<details>
<summary>modules/gql/gqlgen/generated.go (8)</summary>

`310-310`: **Proper interface definition for new resolver**

The ConsensusUnstaking resolver method has been correctly added to the BalanceRecordResolver interface.

---

`370-370`: **Well-structured GetWitness query signature**

The GetWitness query resolver method signature is correctly defined with appropriate parameters for account name and optional height.

---

`3486-3528`: **Correct implementation of ConsensusUnstaking resolver**

The resolver implementation for the `consensus_unstaking` field follows the expected pattern for gqlgen resolvers with proper error handling and null checking.

---

`7058-7083`: **Well-structured GetWitness query implementation**

The implementation for the `getWitness` query follows the standard gqlgen pattern with proper error handling, argument processing, and return type marshaling.

---

`1773-1773`: **Good schema extension to include unstaking balances**

Adding the `consensus_unstaking` field to the BalanceRecord type is a good addition that will help clients track pending unstaking amounts.

---

`1891-1891`: **Clean GetWitness query definition in schema**

The `getWitness` query definition with appropriate parameters is well designed and follows GraphQL naming conventions.

---

`16377-16382`: **Proper marshaling implementation for Witness type**

The marshaling code for the Witness type is correctly implemented with proper null handling.

---

`2361-2399`: <details>
<summary>✅ Verification successful</summary>

**Verify height parameter handling in the resolver implementation**

The argument parsing for the `getWitness` query correctly handles the optional `height` parameter. Make sure the resolver implementation properly handles the case when height is nil by defaulting to the latest block height.

To verify this, check your resolver implementation in `schema.resolvers.go` to ensure it uses a helper function like `ParseHeight` to resolve the height parameter.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check if the GetWitness resolver handles nil height parameter
rg -A 10 "func.*GetWitness" --type go
```

Length of output: 4493

---



</details>

**GetWitness resolver correctly handles optional height**  
The `GetWitness` resolver in `modules/gql/gqlgen/schema.resolvers.go` already calls `ParseHeight(r.HiveBlocks, height)`, which defaults to the latest block height when `height` is `nil`, and then passes the resulting `blockHeight` to `GetWitnessAtHeight`. No further changes are needed.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-09T08:28:38Z
user: login: Geo25rey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T16:28:53Z
user: login: Geo25rey
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T16:36:46Z

Review comments:
diff_hunk: @@ -83,20 +83,17 @@ type ComplexityRoot struct {
 		Type        func(childComplexity int) int
 	}
 
-	AnchorProducer struct {
-		NextSlot func(childComplexity int, account *string) int
-	}
-
 	BalanceRecord struct {
-		Account       func(childComplexity int) int
-		BlockHeight   func(childComplexity int) int
-		Hbd           func(childComplexity int) int
-		HbdAvg        func(childComplexity int) int
-		HbdClaim      func(childComplexity int) int
-		HbdModify     func(childComplexity int) int
-		HbdSavings    func(childComplexity int) int
-		Hive          func(childComplexity int) int
-		HiveConsensus func(childComplexity int) int
+		Account            func(childComplexity int) int
+		BlockHeight        func(childComplexity int) int
+		ConsensusUnstaking func(childComplexity int) int
+		Hbd                func(childComplexity int) int
+		HbdAvg             func(childComplexity int) int
+		HbdClaim           func(childComplexity int) int
+		HbdModify          func(childComplexity int) int
+		HbdSavings         func(childComplexity int) int
+		Hive               func(childComplexity int) int
+		HiveConsensus      func(childComplexity int) int
 	}
path: modules/gql/gqlgen/generated.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Complexity entry added – remember to wire an actual cost function**  

`ConsensusUnstaking` has been added to `ComplexityRoot.BalanceRecord`, but unless you (or gqlgen’s automatic config) explicitly set `BalanceRecord.ConsensusUnstaking` in `generated.go`’s *generated* `NewExecutableSchema` call, it will default to `nil`.  
With a `nil` entry the switch-case below skips the cost calculation entirely, effectively treating the field as **free** in the query planner.  
For heavy aggregation queries this opens the door to unexpectedly expensive calls (think repeated nested selection in one request).

Recommended:

```go
// in gqlgen.yml or a hand-written complexity.go
Complexity:
  BalanceRecord:
    ConsensusUnstaking:  func(childComplexity int) int { return 5 + childComplexity }
```

(choose a cost >0 appropriate for your aggregation).

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-09T07:27:58Z
author_association: NONE
diff_hunk: @@ -208,29 +205,25 @@ type ComplexityRoot struct {
 	}
 
 	Query struct {
-		ActiveWitnessNodes   func(childComplexity int) int
-		AnchorProducer       func(childComplexity int) int
-		ContractState        func(childComplexity int, id *string) int
-		ContractStateDiff    func(childComplexity int, id *string) int
-		FindContract         func(childComplexity int, id *string) int
-		FindContractOutput   func(childComplexity int, filterOptions *FindContractOutputFilter, decodedFilter *string) int
-		FindLedgerActions    func(childComplexity int, filterOptions *LedgerActionsFilter) int
-		FindLedgerTXs        func(childComplexity int, filterOptions *LedgerTxFilter) int
-		FindTransaction      func(childComplexity int, filterOptions *TransactionFilter) int
-		GetAccountBalance    func(childComplexity int, account string, height *model.Uint64) int
-		GetAccountNonce      func(childComplexity int, account string) int
-		GetAccountRc         func(childComplexity int, account string, height *model.Uint64) int
-		GetCurrentNumber     func(childComplexity int) int
-		GetDagByCid          func(childComplexity int, cidString string) int
-		GetElection          func(childComplexity int, epoch model.Uint64) int
-		LocalNodeInfo        func(childComplexity int) int
-		MockGenerateElection func(childComplexity int) int
-		NextWitnessSlot      func(childComplexity int, self *bool) int
-		SubmitTransactionV1  func(childComplexity int, tx string, sig string) int
-		WitnessActiveScore   func(childComplexity int, height *int) int
-		WitnessNodes         func(childComplexity int, height model.Uint64) int
-		WitnessSchedule      func(childComplexity int, height model.Uint64) int
-		WitnessStake         func(childComplexity int, account string) int
+		ContractState       func(childComplexity int, id *string) int
+		ContractStateDiff   func(childComplexity int, id *string) int
+		FindContract        func(childComplexity int, id *string) int
+		FindContractOutput  func(childComplexity int, filterOptions *FindContractOutputFilter, decodedFilter *string) int
+		FindLedgerActions   func(childComplexity int, filterOptions *LedgerActionsFilter) int
+		FindLedgerTXs       func(childComplexity int, filterOptions *LedgerTxFilter) int
+		FindTransaction     func(childComplexity int, filterOptions *TransactionFilter) int
+		GetAccountBalance   func(childComplexity int, account string, height *model.Uint64) int
+		GetAccountNonce     func(childComplexity int, account string) int
+		GetAccountRc        func(childComplexity int, account string, height *model.Uint64) int
+		GetCurrentNumber    func(childComplexity int) int
+		GetDagByCid         func(childComplexity int, cidString string) int
+		GetElection         func(childComplexity int, epoch model.Uint64) int
+		GetWitness          func(childComplexity int, account string, height *model.Uint64) int
+		LocalNodeInfo       func(childComplexity int) int
+		SubmitTransactionV1 func(childComplexity int, tx string, sig string) int
+		WitnessNodes        func(childComplexity int, height model.Uint64) int
+		WitnessSchedule     func(childComplexity int, height model.Uint64) int
+		WitnessStake        func(childComplexity int, account string) int
 	}
path: modules/gql/gqlgen/generated.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**`GetWitness` also lacks a complexity function**  

Same observation for `Query.GetWitness`.  If you forget to assign a non-nil function, a client can request arbitrarily deep sub-selections of `Witness` objects without the call contributing to the overall query cost.

At minimum:

```go
Complexity:
  Query:
    GetWitness: func(child int, _ string, _ *model.Uint64) int { return 10 + child }
```

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-09T07:27:58Z
author_association: NONE
diff_hunk: @@ -83,20 +83,17 @@ type ComplexityRoot struct {
 		Type        func(childComplexity int) int
 	}
 
-	AnchorProducer struct {
-		NextSlot func(childComplexity int, account *string) int
-	}
-
 	BalanceRecord struct {
-		Account       func(childComplexity int) int
-		BlockHeight   func(childComplexity int) int
-		Hbd           func(childComplexity int) int
-		HbdAvg        func(childComplexity int) int
-		HbdClaim      func(childComplexity int) int
-		HbdModify     func(childComplexity int) int
-		HbdSavings    func(childComplexity int) int
-		Hive          func(childComplexity int) int
-		HiveConsensus func(childComplexity int) int
+		Account            func(childComplexity int) int
+		BlockHeight        func(childComplexity int) int
+		ConsensusUnstaking func(childComplexity int) int
+		Hbd                func(childComplexity int) int
+		HbdAvg             func(childComplexity int) int
+		HbdClaim           func(childComplexity int) int
+		HbdModify          func(childComplexity int) int
+		HbdSavings         func(childComplexity int) int
+		Hive               func(childComplexity int) int
+		HiveConsensus      func(childComplexity int) int
 	}
path: modules/gql/gqlgen/generated.go
user: login: techcoderx
body: is it `Complexity` or `complexity`?
created_at: 2025-05-09T07:35:04Z
author_association: MEMBER
diff_hunk: @@ -83,20 +83,17 @@ type ComplexityRoot struct {
 		Type        func(childComplexity int) int
 	}
 
-	AnchorProducer struct {
-		NextSlot func(childComplexity int, account *string) int
-	}
-
 	BalanceRecord struct {
-		Account       func(childComplexity int) int
-		BlockHeight   func(childComplexity int) int
-		Hbd           func(childComplexity int) int
-		HbdAvg        func(childComplexity int) int
-		HbdClaim      func(childComplexity int) int
-		HbdModify     func(childComplexity int) int
-		HbdSavings    func(childComplexity int) int
-		Hive          func(childComplexity int) int
-		HiveConsensus func(childComplexity int) int
+		Account            func(childComplexity int) int
+		BlockHeight        func(childComplexity int) int
+		ConsensusUnstaking func(childComplexity int) int
+		Hbd                func(childComplexity int) int
+		HbdAvg             func(childComplexity int) int
+		HbdClaim           func(childComplexity int) int
+		HbdModify          func(childComplexity int) int
+		HbdSavings         func(childComplexity int) int
+		Hive               func(childComplexity int) int
+		HiveConsensus      func(childComplexity int) int
 	}
path: modules/gql/gqlgen/generated.go
user: login: coderabbitai[bot]
body: @techcoderx The correct key is `complexity` (all lowercase) in `gqlgen.yml`. The field names under it (like `BalanceRecord.ConsensusUnstaking`) are capitalized to match Go struct fields.


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@techcoderx The correct key is `complexity` (all lowercase) in `gqlgen.yml`. The field names under it (like `BalanceRecord.ConsensusUnstaking`) are capitalized to match Go struct fields.</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-09T07:35:21Z
author_association: NONE
diff_hunk: @@ -22,3 +26,18 @@ func Paginate(offset *int, limit *int) (int, int, error) {
 	}
 	return offset_result, limit_result, nil
 }
+
+// Parse optional height, falling back to last processed block if not specified
+func ParseHeight(hb hive_blocks.HiveBlocks, height *model.Uint64) (uint64, error) {
+	var blockHeight uint64
+	if height != nil {
+		blockHeight = uint64(*height)
+	} else {
+		head, headErr := hb.GetLastProcessedBlock()
+		if headErr != nil {
+			return 0, headErr
+		}
+		blockHeight = head
path: modules/gql/gqlgen/utils.go
user: login: Geo25rey
body: Getting the last processed block isn't needed. Using max uint64 as the height, will get the latest info.
created_at: 2025-05-13T16:26:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -314,12 +267,7 @@ type Query {
   localNodeInfo: LocalNodeInfo
   getWitness(account: String!, height: Uint64): Witness
   witnessNodes(height: Uint64!): [Witness!]!
-  activeWitnessNodes: JSON
   witnessSchedule(height: Uint64!): [WitnessSlot!]!
-  nextWitnessSlot(self: Boolean): JSON
-  witnessActiveScore(height: Int): JSON
-  mockGenerateElection: JSON
-  anchorProducer: AnchorProducer
   getCurrentNumber: TestResult # TESTING QUERY
path: modules/gql/schema.graphql
user: login: Geo25rey
body: This can get removed too
created_at: 2025-05-13T16:28:49Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-09T07:23:03Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: failure by coderabbit.ai -->

> [!CAUTION]
> ## Review failed
> 
> The pull request is closed.

<!-- end of auto-generated comment: failure by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This change introduces a new method to aggregate pending consensus unstake amounts for an account, updates the relevant interface, and exposes this data via a new GraphQL field and resolver. Several obsolete GraphQL types and queries related to witness nodes and anchor producers are removed, and a utility function for block height resolution is added.

## Changes

| File(s)                                                                                   | Change Summary |
|------------------------------------------------------------------------------------------|---------------|
| `modules/db/vsc/ledger/ledger.go`, `modules/db/vsc/ledger/types.go`                      | Added `GetAccountPendingConsensusUnstake` method to both the `actionsDb` type and `BridgeActions` interface for aggregating pending consensus unstake amounts. |
| `modules/gql/gqlgen/generated.go`, `modules/gql/gqlgen/models.go`, `modules/gql/schema.graphql` | Removed `AnchorProducer` type and related queries; removed multiple interfaces and enums; added `consensus_unstaking` field to `BalanceRecord` and new `getWitness` query to the schema and generated code. |
| `modules/gql/gqlgen/schema.resolvers.go`                                                 | Added resolver for `consensus_unstaking` field in `BalanceRecord`; added `GetWitness` query resolver; refactored height resolution logic; removed obsolete witness and anchor producer resolvers. |
| `modules/gql/gqlgen/utils.go`                                                            | Added `ParseHeight` utility function for resolving block height from optional input or latest processed block. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant GQL_Server as GraphQL Server
    participant ActionsDB

    Client->>GQL_Server: Query BalanceRecord { consensus_unstaking }
    GQL_Server->>ActionsDB: GetAccountPendingConsensusUnstake(account)
    ActionsDB-->>GQL_Server: int64 (pending unstake sum)
    GQL_Server-->>Client: consensus_unstaking value
```

```mermaid
sequenceDiagram
    participant Client
    participant GQL_Server as GraphQL Server
    participant HiveBlocks
    participant WitnessesDB

    Client->>GQL_Server: Query getWitness(account, height)
    GQL_Server->>HiveBlocks: ParseHeight(height)
    HiveBlocks-->>GQL_Server: block height
    GQL_Server->>WitnessesDB: GetWitness(account, block height)
    WitnessesDB-->>GQL_Server: Witness object
    GQL_Server-->>Client: Witness data
```

## Possibly related PRs

- [vsc-eco/go-vsc-node#21](https://github.com/vsc-eco/go-vsc-node/pull/21): Adds and refactors ledger actions querying, including methods in the same `actionsDb` type and interface, but does not introduce the new consensus unstake aggregation method.

## Poem

> In the ledger fields where queries grow,  
> A new unstaking sum now flows.  
> AnchorProducer hops away,  
> While Witness comes to light today.  
> With block heights parsed and data neat,  
> The rabbits thump their happy feet!  
> 🐇✨

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- announcements_start -->

> [!TIP]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> - CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> 
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->

---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 70d3b41324214b6ef90db35895f8d09261949173 and a34b751514d4bae2ae9b28db6d3b357ea6f53514.

</details>

<details>
<summary>📒 Files selected for processing (5)</summary>

* `modules/gql/gqlgen/generated.go` (27 hunks)
* `modules/gql/gqlgen/models.go` (0 hunks)
* `modules/gql/gqlgen/schema.resolvers.go` (4 hunks)
* `modules/gql/gqlgen/utils.go` (2 hunks)
* `modules/gql/schema.graphql` (2 hunks)

</details>

</details>
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=vsc-eco/go-vsc-node&utm_content=29):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-05-13T16:35:06Z
body: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=vsc-eco_go-vsc-node&pullRequest=29) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [28.8% Duplication on New Code](https://sonarcloud.io/component_measures?id=vsc-eco_go-vsc-node&pullRequest=29&metric=new_duplicated_lines_density&view=list) (required ≤ 3%)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vsc-eco_go-vsc-node&pullRequest=29)


author_association: NONE