8000 new API endpoint: blocks x validator by Marketen · Pull Request #117 · dappnode/mev-sp-oracle · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

new API endpoint: blocks x validator #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
pathMemoryWrongFeeBlocks = "/memory/wrongfeeblocks"
pathMemoryDonations = "/memory/donations"
pathMemoryPoolStatistics = "/memory/statistics"
pathMemoryValidatorBlocks = "/memory/validatorblocks"

// Onchain endpoints: what is submitted to the contract
pathOnchainValidators = "/onchain/validators" // TODO
Expand Down Expand Up @@ -139,6 +140,7 @@ func (m *ApiService) getRouter() http.Handler {
r.HandleFunc(pathMemoryMissedBlocks, m.handleMemoryMissedBlocks).Methods(http.MethodGet)
r.HandleFunc(pathMemoryWrongFeeBlocks, m.handleMemoryWrongFeeBlocks).Methods(http.MethodGet)
r.HandleFunc(pathMemoryDonations, m.handleMemoryDonations).Methods(http.MethodGet)
r.HandleFunc(pathMemoryValidatorBlocks, m.handleMemoryValidatorBlocks).Methods(http.MethodGet)

// Onchain endpoints
r.HandleFunc(pathOnchainMerkleProof, m.handleOnchainMerkleProof).Methods(http.MethodGet)
Expand Down Expand Up @@ -201,6 +203,70 @@ func (m *ApiService) handleRoot(w http.ResponseWriter, req *http.Request) {
m.respondOK(w, "see api doc for available endpoints")
}

func (m *ApiService) handleMemoryValidatorBlocks(w http.ResponseWriter, r *http.Request) {
// Access the existing OracleState instance from the ApiService
oracleState := m.oracle.State()

// Retrieve the ProposedBlocks, MissedBlocks, and WrongFeeBlocks from the OracleState
proposedBlocks := oracleState.ProposedBlocks
missedBlocks := oracleState.MissedBlocks
wrongFeeBlocks := oracleState.WrongFeeBlocks

// Create a map to hold the ordered blocks, with the ValidatorIndex as the key
orderedBlocks := make(map[uint64]*httpOkValBlocks)

// Iterate over the ProposedBlocks and add them to the orderedBlocks map
for _, block := range proposedBlocks {
validatorIndex := block.ValidatorIndex
if valBlocks, ok := orderedBlocks[validatorIndex]; ok {
valBlocks.ProposedBlocks = append(valBlocks.ProposedBlocks, block)
} else {
orderedBlocks[validatorIndex] = &httpOkValBlocks{
ValidatorIndex: validatorIndex,
ProposedBlocks: []oracle.SummarizedBlock{block},
}
}
}

// Iterate over the MissedBlocks and add them to the orderedBlocks map
for _, block := range missedBlocks {
validatorIndex := block.ValidatorIndex
if valBlocks, ok := orderedBlocks[validatorIndex]; ok {
valBlocks.MissedBlocks = append(valBlocks.MissedBlocks, block)
} else {
orderedBlocks[validatorIndex] = &httpOkValBlocks{
ValidatorIndex: validatorIndex,
MissedBlocks: []oracle.SummarizedBlock{block},
}
}
}

// Iterate over the WrongFeeBlocks and add them to the orderedBlocks map
for _, block := range wrongFeeBlocks {
validatorIndex := block.ValidatorIndex
if valBlocks, ok := orderedBlocks[validatorIndex]; ok {
valBlocks.WrongFeeBlocks = append(valBlocks.WrongFeeBlocks, block)
} else {
orderedBlocks[validatorIndex] = &httpOkValBlocks{
ValidatorIndex: validatorIndex,
WrongFeeBlocks: []oracle.SummarizedBlock{block},
}
}
}

// Create a slice to hold the final JSON output
finalOutput := make([]*httpOkValBlocks, 0, len(orderedBlocks))

// Iterate over the orderedBlocks map using the validator indices in ascending order
for index := uint64(0); index < uint64(len(orderedBlocks)); index++ {
if valBlocks, ok := orderedBlocks[index]; ok {
finalOutput = append(finalOutput, valBlocks)
}
}

m.respondOK(w, finalOutput)
}

func (m *ApiService) handleMemoryStatistics(w http.ResponseWriter, req *http.Request) {
totalSubscribed := uint64(0)
totalActive := uint64(0)
Expand Down
139 changes: 139 additions & 0 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,142 @@ func Test_ApiEndpoint(t *testing.T) {
require.Equal(t, 1, 1)
*/
}

// func TestHandleGetOrderedBlocksByValidatorKey(t *testing.T) {

// // Create a mock config
// mockConfig := &oracle.Config{
// ConsensusEndpoint: "http://consensus_endpoint",
// ExecutionEndpoint: "http://execution_endpoint",
// Network: "testnet",
// PoolAddress: "pool_address",
// DeployedSlot: 1000,
// DeployedBlock: 10000,
// CheckPointSizeInSlots: 10,
// PoolFeesAddress: "fees_address",
// DryRun: true,
// NumRetries: 3,
// CollateralInWei: big.NewInt(1000),
// UpdaterKeyPass: "key_pass",
// UpdaterKeyPath: "key_path",
// }

// // Create a mock Oracle using the NewOracle function
// mockOracle := oracle.NewOracle(mockConfig)
// //oracle.NewOracleState(mockConfig)
// numBlocks := 100
// for i := 0; i < numBlocks; i++ {
// // Generate a random ValidatorIndex between 0 and 99
// validatorIndex := rand.Intn(100)

// // Create mock blocks and add them to the OracleState's ProposedBlocks
// mockBlock := blockOkProposal(
// rand.Uint64()%101,
// uint64(validatorIndex),
// "PUBKEY",
// big.NewInt(int64(rand.Intn(1000)+10000)),
// "0xaaa0000000000000000000000000000000000000",
// )
// mockOracle.AdvanceStateToNextSlot(&mockBlock)
// // Create mock missed blocks and add them to the OracleState's MissedBlocks
// mockMissedBlock := MissedBlock(
// rand.Uint64()%101,
// uint64(validatorIndex),
// "PUBKEY",
// )
// mockOracle.AdvanceStateToNextSlot(&mockMissedBlock)

// // Create mock wrong fee blocks and add them to the OracleState's WrongFeeBlocks
// mockWrongFeeBlock := WrongFeeBlock(
// rand.Uint64()%101,
// uint64(validatorIndex),
// "PUBKEY",
// )
// mockOracle.AdvanceStateToNextSlot(&mockWrongFeeBlock)
// }
// // Create an instance of your ApiService with the mock Oracle
// apiService := &ApiService{
// oracle: mockOracle,
// // other fields initialization...
// }
// req, err := http.NewRequest("GET", "/memory/validatorblocks", nil)
// if err != nil {
// t.Fatal(err)
// }
// rr := httptest.NewRecorder()
// // Call the handler function directly, passing in the ResponseRecorder and the Request
// handler := http.HandlerFunc(apiService.handleMemoryValidatorBlocks)
// handler.ServeHTTP(rr, req)
// fmt.Println(rr.Body)

// // handler2 := http.HandlerFunc(apiService.handleMemoryAllBlocks)
// // handler2.ServeHTTP(rr, req)
// // fmt.Print(rr.Body.String())

// // Perform assertions on the response
// if status := rr.Code; status != http.StatusOK {
// t.Errorf("handler returned wrong status code: got %v, want %v", status, http.StatusOK)
// }
// // Perform additional assertions on the response body or headers if needed
// // For example, you can check the response body for expected JSON data

// // Example assertion for JSON response
// // expectedResponse := `{"message":"success"}`
// // if rr.Body.String() != expectedResponse {
// // t.Errorf("handler returned unexpected body: got %v, want %v", rr.Body.String(), expectedResponse)
// // }
// }

// func TestHandleMemoryValidatorBlocks(t *testing.T) {

// // Create an instance of ApiService
// apiService := &ApiService{}

// // Create a request and response recorder
// req, err := http.NewRequest("GET", "/handle-memory-validator-blocks", nil)
// assert.NoError(t, err)
// res := httptest.NewRecorder()

// // Call the handler function
// apiService.handleMemoryValidatorBlocks(res, req)

// // Assert the response status code
// assert.Equal(t, http.StatusOK, res.Code)

// // Assert the response body
// expectedJSON := `[{"validator_index":1,"proposed_blocks":[{"slot":0,"block":0,"validator_index":1,"validator_key":"","block_type":0,"reward_wei":null,"reward_type":0,"withdrawal_address":""}],"missed_blocks":[{"slot":0,"block":0,"validator_index":1,"validator_key":"","block_type":0,"reward_wei":null,"reward_type":0,"withdrawal_address":""}]},{"validator_index":2,"proposed_blocks":[{"slot":0,"block":0,"validator_index":2,"validator_key":"","block_type":0,"reward_wei":null,"reward_type":0,"withdrawal_address":""}],"wrong_fee_blocks":[{"slot":0,"block":0,"validator_index":2,"validator_key":"","block_type":0,"reward_wei":null,"reward_type":0,"withdrawal_address":""}]}]`
// assert.Equal(t, expectedJSON, res.Body.String())
// }

// func MissedBlock(slot uint64, valIndex uint64, pubKey string) oracle.FullBlock {
// return oracle.FullBlock{
// Validator: &v1.Validator{
// Index: phase0.ValidatorIndex(valIndex),
// },
// }
// }

// func WrongFeeBlock(slot uint64, valIndex uint64, pubKey string) oracle.FullBlock {
// return oracle.FullBlock{
// Validator: &v1.Validator{
// Index: phase0.ValidatorIndex(valIndex),
// },
// }
// }

// func blockOkProposal(slot uint64, valIndex uint64, pubKey string, reward *big.Int, withAddress string) oracle.FullBlock {
// // return oracle.FullBlock{
// // Slot: slot,
// // ValidatorIndex: valIndex,
// // ValidatorKey: pubKey,
// // BlockType: oracle.OkPoolProposal,
// // Reward: reward,
// // RewardType: oracle.MevBlock,
// // WithdrawalAddress: withAddress,
// // }
// return oracle.FullBlock{
// Validator: &v1.Validator{
// Index: phase0.ValidatorIndex(valIndex),
// },
// }
// }
9 changes: 9 additions & 0 deletions api/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package api

import "github.com/dappnode/mev-sp-oracle/oracle"

type httpErrorResp struct {
Code int `json:"code"`
Message string `json:"message"`
Expand Down Expand Up @@ -130,3 +132,10 @@ type httpOkValidatorInfo struct {
ValidatorIndex uint64 `json:"validator_index"`
ValidatorKey string `json:"validator_key"`
}

type httpOkValBlocks struct {
ValidatorIndex uint64 `json:"validator_index"`
ProposedBlocks []oracle.SummarizedBlock `json:"proposed_blocks"`
MissedBlocks []oracle.SummarizedBlock `json:"missed_blocks"`
WrongFeeBlocks []oracle.SummarizedBlock `json:"wrong_fee_blocks"`
}
0