Skip to content

Commit 5873cfe

Browse files
committed
blocks x val endpoint
1 parent f636523 commit 5873cfe

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

api/api.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const (
6161
pathMemoryWrongFeeBlocks = "/memory/wrongfeeblocks"
6262
pathMemoryDonations = "/memory/donations"
6363
pathMemoryPoolStatistics = "/memory/statistics"
64+
pathMemoryValidatorBlocks = "/memory/validatorblocks"
6465

6566
// Onchain endpoints: what is submitted to the contract
6667
pathOnchainValidators = "/onchain/validators" // TODO
@@ -178,6 +179,19 @@ type httpOkProofs struct {
178179
PendingRewardsWei string `json:"pending_rewards_wei"`
179180
}
180181

182+
type SimplifiedValidatorInfo struct {
183+
Status oracle.ValidatorStatus `json:"status"`
184+
AccumulatedRewards *big.Int `json:"accumulated_rewards_wei"`
185+
PendingRewards *big.Int `json:"pending_rewards_wei"`
186+
Collateral *big.Int `json:"collateral_wei"`
187+
WithdrawalAddress string `json:"withdrawal_address"`
188+
ValidatorIndex uint64 `json:"validator_index"`
189+
ValidatorKey string `json:"validator_key"`
190+
ProposedBlocks []oracle.Block `json:"proposed_block"`
191+
MissedBlocks []oracle.Block `json:"missed_blocks"`
192+
WrongFeeBlocks []oracle.Block `json:"wrong_fee_blocks"`
193+
}
194+
181195
type ApiService struct {
182196
srv *http.Server
183197
cfg *config.Config
@@ -243,6 +257,7 @@ func (m *ApiService) getRouter() http.Handler {
243257
r.HandleFunc(pathMemoryMissedBlocks, m.handleMemoryMissedBlocks).Methods(http.MethodGet)
244258
r.HandleFunc(pathMemoryWrongFeeBlocks, m.handleMemoryWrongFeeBlocks).Methods(http.MethodGet)
245259
r.HandleFunc(pathMemoryDonations, m.handleMemoryDonations).Methods(http.MethodGet)
260+
r.HandleFunc(pathMemoryValidatorBlocks, m.handleMemoryValidatorBlocks).Methods(http.MethodGet)
246261

247262
// Onchain endpoints
248263
r.HandleFunc(pathOnchainMerkleProof, m.handleOnchainMerkleProof).Methods(http.MethodGet)
@@ -305,6 +320,62 @@ func (m *ApiService) handleRoot(w http.ResponseWriter, req *http.Request) {
305320
m.respondOK(w, "see api doc for available endpoints")
306321
}
307322

323+
func (m *ApiService) handleMemoryValidatorBlocks(w http.ResponseWriter, r *http.Request) {
324+
// Access the existing OracleState instance from the ApiService
325+
oracleState := m.oracle.State()
326+
327+
// Retrieve the ProposedBlocks, MissedBlocks, and WrongFeeBlocks from the OracleState
328+
proposedBlocks := oracleState.ProposedBlocks
329+
missedBlocks := oracleState.MissedBlocks
330+
wrongFeeBlocks := oracleState.WrongFeeBlocks
331+
332+
// Sort the blocks by ValidatorKey
333+
sort.Slice(proposedBlocks, func(i, j int) bool {
334+
return proposedBlocks[i].ValidatorKey < proposedBlocks[j].ValidatorKey
335+
})
336+
sort.Slice(missedBlocks, func(i, j int) bool {
337+
return missedBlocks[i].ValidatorKey < missedBlocks[j].ValidatorKey
338+
})
339+
sort.Slice(wrongFeeBlocks, func(i, j int) bool {
340+
return wrongFeeBlocks[i].ValidatorKey < wrongFeeBlocks[j].ValidatorKey
341+
})
342+
343+
// Create a map to hold the ordered blocks, with the ValidatorKey as the key
344+
orderedBlocks := make(map[string]interface{})
345+
346+
// Add the ordered blocks to the map
347+
for _, block := range proposedBlocks {
348+
validatorKey := block.ValidatorKey
349+
if orderedBlocks[validatorKey] == nil {
350+
orderedBlocks[validatorKey] = make(map[string]interface{})
351+
}
352+
orderedBlocks[validatorKey].(map[string]interface{})["proposed_block"] = append(orderedBlocks[validatorKey].(map[string]interface{})["proposed_block"].([]oracle.Block), block)
353+
}
354+
for _, block := range missedBlocks {
355+
validatorKey := block.ValidatorKey
356+
if orderedBlocks[validatorKey] == nil {
357+
orderedBlocks[validatorKey] = make(map[string]interface{})
358+
}
359+
orderedBlocks[validatorKey].(map[string]interface{})["missed_blocks"] = append(orderedBlocks[validatorKey].(map[string]interface{})["missed_blocks"].([]oracle.Block), block)
360+
}
361+
for _, block := range wrongFeeBlocks {
362+
validatorKey := block.ValidatorKey
363+
if orderedBlocks[validatorKey] == nil {
364+
orderedBlocks[validatorKey] = make(map[string]interface{})
365+
}
366+
orderedBlocks[validatorKey].(map[string]interface{})["wrong_fee_blocks"] = append(orderedBlocks[validatorKey].(map[string]interface{})["wrong_fee_blocks"].([]oracle.Block), block)
367+
}
368+
369+
// Convert the map to JSON
370+
responseJSON, err := json.Marshal(orderedBlocks)
371+
if err != nil {
372+
// Handle error
373+
w.WriteHeader(http.StatusInternalServerError)
374+
return
375+
}
376+
m.respondOK(w, string(responseJSON))
377+
}
378+
308379
func (m *ApiService) handleMemoryStatistics(w http.ResponseWriter, req *http.Request) {
309380
totalSubscribed := uint64(0)
310381
totalActive := uint64(0)

api/api_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package api
22

33
import (
44
"encoding/hex"
5+
"fmt"
56
"math/big"
7+
"math/rand"
8+
"net/http"
9+
"net/http/httptest"
610
"testing"
711

812
v1 "github.com/attestantio/go-eth2-client/api/v1"
@@ -314,3 +318,101 @@ func Test_ApiEndpoint(t *testing.T) {
314318
require.Equal(t, 1, 1)
315319
*/
316320
}
321+
322+
func TestHandleGetOrderedBlocksByValidatorKey(t *testing.T) {
323+
324+
// Create a mock config
325+
mockConfig := &config.Config{
326+
ConsensusEndpoint: "http://consensus_endpoint",
327+
ExecutionEndpoint: "http://execution_endpoint",
328+
Network: "testnet",
329+
PoolAddress: "pool_address",
330+
DeployedSlot: 1000,
331+
DeployedBlock: 10000,
332+
CheckPointSizeInSlots: 10,
333+
PoolFeesPercent: 150,
334+
PoolFeesAddress: "fees_address",
335+
DryRun: true,
336+
NumRetries: 3,
337+
CollateralInWei: big.NewInt(1000),
338+
UpdaterKeyPass: "key_pass",
339+
UpdaterKeyPath: "key_path",
340+
}
341+
342+
// Create a mock Oracle using the NewOracle function
343+
mockOracle := oracle.NewOracle(mockConfig)
344+
oracle.NewOracleState(mockConfig)
345+
346+
// blockPool := oracle.Block{
347+
// // Set the desired values for the blockPool struct
348+
// Slot: 0,
349+
// Block: 0,
350+
// ValidatorIndex: 420,
351+
// BlockType: 3,
352+
// }
353+
blockSubs := []oracle.Subscription{
354+
// Create mock subscription objects as needed
355+
}
356+
blockUnsubs := []oracle.Unsubscription{
357+
// Create mock unsubscription objects as needed
358+
}
359+
blockDonations := []oracle.Donation{
360+
// Create mock donation objects as needed
361+
}
362+
mevReward := big.NewInt(int64(rand.Intn(1000) + 10000))
363+
364+
// Call the function and capture the returned values
365+
processedSlot, err := mockOracle.AdvanceStateToNextSlot(blockOkProposal(
366+
0,
367+
420,
368+
"1",
369+
mevReward,
370+
"0xaaa0000000000000000000000000000000000000"), blockSubs, blockUnsubs, blockDonations)
371+
fmt.Print(mockOracle.State().ProposedBlocks)
372+
373+
_ = processedSlot
374+
// Create an instance of your ApiService with the mock Oracle
375+
apiService := &ApiService{
376+
oracle: mockOracle,
377+
// other fields initialization...
378+
}
379+
req, err := http.NewRequest("GET", "/memory/validatorblocks", nil)
380+
if err != nil {
381+
t.Fatal(err)
382+
}
383+
rr := httptest.NewRecorder()
384+
// Call the handler function directly, passing in the ResponseRecorder and the Request
385+
handler := http.HandlerFunc(apiService.handleMemoryValidatorBlocks)
386+
handler.ServeHTTP(rr, req)
387+
fmt.Print(rr.Body.String())
388+
389+
handler2 := http.HandlerFunc(apiService.handleMemoryAllBlocks)
390+
handler2.ServeHTTP(rr, req)
391+
fmt.Print(rr.Body.String())
392+
393+
// // Perform assertions on the response
394+
// if status := rr.Code; status != http.StatusOK {
395+
// t.Errorf("handler returned wrong status code: got %v, want %v", status, http.StatusOK)
396+
// }
397+
// fmt.Print(rr.Body.String())
398+
// // Perform additional assertions on the response body or headers if needed
399+
// // For example, you can check the response body for expected JSON data
400+
401+
// // Example assertion for JSON response
402+
// expectedResponse := `{"message":"success"}`
403+
// if rr.Body.String() != expectedResponse {
404+
// t.Errorf("handler returned unexpected body: got %v, want %v", rr.Body.String(), expectedResponse)
405+
// }
406+
}
407+
408+
func blockOkProposal(slot uint64, valIndex uint64, pubKey string, reward *big.Int, withAddress string) oracle.Block {
409+
return oracle.Block{
410+
Slot: slot,
411+
ValidatorIndex: valIndex,
412+
ValidatorKey: pubKey,
413+
BlockType: oracle.OkPoolProposal,
414+
Reward: reward,
415+
RewardType: oracle.MevBlock,
416+
WithdrawalAddress: withAddress,
417+
}
418+
}

0 commit comments

Comments
 (0)