diff --git a/common/query/nodeRegistrationQuery.go b/common/query/nodeRegistrationQuery.go index 37d64636f..f35121ca8 100644 --- a/common/query/nodeRegistrationQuery.go +++ b/common/query/nodeRegistrationQuery.go @@ -191,9 +191,9 @@ func (nrq *NodeRegistrationQuery) GetNodeRegistrationsWithZeroScore(registration // GetNodeRegistryAtHeight returns unique latest node registry record at specific height func (nrq *NodeRegistrationQuery) GetNodeRegistryAtHeight(height uint32) string { - return fmt.Sprintf("SELECT %s, max(height) AS max_height FROM %s where height <= %d AND registration_status = 0 "+ - "GROUP BY id ORDER BY height DESC", - strings.Join(nrq.Fields, ", "), nrq.getTableName(), height) + return fmt.Sprintf("SELECT %s FROM %s where registration_status = 0 AND (id,height) in (SELECT id,MAX(height) "+ + "FROM %s WHERE height <= %d GROUP BY id) ORDER BY height DESC", + strings.Join(nrq.Fields, ", "), nrq.getTableName(), nrq.getTableName(), height) } // ExtractModel extract the model struct fields to the order of NodeRegistrationQuery.Fields diff --git a/common/query/nodeRegistrationQuery_test.go b/common/query/nodeRegistrationQuery_test.go index 83a7b7600..021bedc61 100644 --- a/common/query/nodeRegistrationQuery_test.go +++ b/common/query/nodeRegistrationQuery_test.go @@ -504,3 +504,34 @@ func TestNodeRegistrationQuery_SelectDataForSnapshot(t *testing.T) { }) } } + +func TestNodeRegistrationQuery_GetNodeRegistryAtHeight(t *testing.T) { + type args struct { + height uint32 + } + tests := []struct { + name string + args args + want string + }{ + { + name: "GetNodeRegistryAtHeightQuery", + args: args{ + height: 11120, + }, + want: "SELECT id, node_public_key, account_address, registration_height, node_address, " + + "locked_balance, registration_status, latest, height FROM node_registry " + + "where registration_status = 0 AND (id,height) in " + + "(SELECT id,MAX(height) FROM node_registry WHERE height <= 11120 GROUP BY id) " + + "ORDER BY height DESC", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nrq := NewNodeRegistrationQuery() + if got := nrq.GetNodeRegistryAtHeight(tt.args.height); got != tt.want { + t.Errorf("NodeRegistrationQuery.GetNodeRegistryAtHeight() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/core/service/blockMainService_test.go b/core/service/blockMainService_test.go index 4da96e5f2..9abf20952 100644 --- a/core/service/blockMainService_test.go +++ b/core/service/blockMainService_test.go @@ -531,16 +531,20 @@ func (*mockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...inter mockPublishedReceipt[0].ReceiptIndex, mockPublishedReceipt[0].PublishedIndex, )) - case "SELECT id, node_public_key, account_address, registration_height, node_address, locked_balance, " + - "registration_status, latest, height, max(height) AS max_height FROM node_registry where height <= 0 AND " + - "registration_status = 0 GROUP BY id ORDER BY height DESC": + case "SELECT id, node_public_key, account_address, registration_height, node_address, " + + "locked_balance, registration_status, latest, height " + + "FROM node_registry where registration_status = 0 AND (id,height) in " + + "(SELECT id,MAX(height) FROM node_registry WHERE height <= 0 GROUP BY id) " + + "ORDER BY height DESC": mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ "id", "node_public_key", "account_address", "registration_height", "node_address", "locked_balance", "registration_status", "latest", "height", })) - case "SELECT id, node_public_key, account_address, registration_height, node_address, locked_balance, " + - "registration_status, latest, height, max(height) AS max_height FROM node_registry where height <= 1 " + - "AND registration_status = 0 GROUP BY id ORDER BY height DESC": + case "SELECT id, node_public_key, account_address, registration_height, node_address, " + + "locked_balance, registration_status, latest, height " + + "FROM node_registry where registration_status = 0 AND (id,height) in " + + "(SELECT id,MAX(height) FROM node_registry WHERE height <= 1 GROUP BY id) " + + "ORDER BY height DESC": mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ "id", "node_public_key", "account_address", "registration_height", "node_address", "locked_balance", "registration_status", "latest", "height", diff --git a/core/service/nodeRegistrationCoreService_test.go b/core/service/nodeRegistrationCoreService_test.go index af0ce5f79..1fcef118c 100644 --- a/core/service/nodeRegistrationCoreService_test.go +++ b/core/service/nodeRegistrationCoreService_test.go @@ -181,9 +181,11 @@ func (*nrsMockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...in "participation_score", }, ).AddRow(1, nrsNodePubKey1, 8000)) - case "SELECT id, node_public_key, account_address, registration_height, node_address, locked_balance, registration_status, " + - "latest, height, max(height) AS max_height FROM node_registry where height <= 1 AND registration_status = 0 " + - "GROUP BY id ORDER BY height DESC": + case "SELECT id, node_public_key, account_address, registration_height, node_address, " + + "locked_balance, registration_status, latest, height " + + "FROM node_registry where registration_status = 0 AND (id,height) in " + + "(SELECT id,MAX(height) FROM node_registry WHERE height <= 1 GROUP BY id) " + + "ORDER BY height DESC": mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ "id", "node_public_key", @@ -194,10 +196,9 @@ func (*nrsMockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...in "registration_status", "latest", "height", - "max_height", }, ).AddRow(1, nrsNodePubKey1, nrsAddress1, 10, "10.10.10.10", 100000000, - uint32(model.NodeRegistrationState_NodeRegistered), true, 200, 200)) + uint32(model.NodeRegistrationState_NodeRegistered), true, 200)) default: return nil, errors.New("InvalidQuery") }