diff --git a/go/simreq/go.mod b/go/simreq/go.mod new file mode 100644 index 0000000..a2ab8f3 --- /dev/null +++ b/go/simreq/go.mod @@ -0,0 +1,3 @@ +module simreq + +go 1.23.0 diff --git a/go/simreq/jsonrpc.go b/go/simreq/jsonrpc.go new file mode 100644 index 0000000..7fb8b93 --- /dev/null +++ b/go/simreq/jsonrpc.go @@ -0,0 +1,54 @@ +package main + +import ( + "bytes" + "encoding/json" + "net/http" +) + +type JSONRPCRequest struct { + Jsonrpc string `json:"jsonrpc"` + Method string `json:"method"` + Params []interface{} `json:"params"` + ID int `json:"id"` +} + +type JSONRPCResponse struct { + Jsonrpc string `json:"jsonrpc"` + Result BlockResponse `json:"result,omitempty"` + Error interface{} `json:"error,omitempty"` + ID int `json:"id"` +} + +type BlockResponse struct { + Number string `json:"number"` + TimeStamp string `json:"timestamp"` +} + +func SendJSONRPCRequest(url string, method string, params []interface{}) (*JSONRPCResponse, error) { + request := JSONRPCRequest{ + Jsonrpc: "2.0", + Method: method, + Params: params, + ID: 1, + } + + jsonData, err := json.Marshal(request) + if err != nil { + return nil, err + } + + resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var response JSONRPCResponse + err = json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + return nil, err + } + + return &response, nil +} diff --git a/go/simreq/main.go b/go/simreq/main.go new file mode 100644 index 0000000..cc41c66 --- /dev/null +++ b/go/simreq/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "fmt" + "sync" + "time" +) + +const ( + url = "https://bsc-dataseed2.ninicoin.io" + method = "eth_getBlockByNumber" + startBlock = 0 + endBlock = 1000 + TimeInterval = 3 + batchSize = 5 +) + +func main() { + // SimSyncRequests() + SimAsyncRequests() +} + +func SimSyncRequests() { + ticker := time.NewTicker(TimeInterval * time.Second) + reqCount := 0 + go func() { + for range ticker.C { + fmt.Printf("req %d for %d seconds\n", reqCount, TimeInterval) + reqCount = 0 + } + }() + + for block := startBlock; block < endBlock; block++ { + params := []interface{}{IntToHex(block), false} + resp, err := SendJSONRPCRequest(url, method, params) + reqCount++ + if err != nil { + fmt.Println("Error:", err) + fmt.Println(resp.Result) + continue + } + // fmt.Println(resp.Result) + } +} +func SimAsyncRequests() { + + ticker := time.NewTicker(TimeInterval * time.Second) + reqCount := 0 + var reqCountLock sync.Mutex + go func() { + for range ticker.C { + fmt.Printf("req %d for %d seconds\n", reqCount, TimeInterval) + reqCountLock.Lock() + reqCount = 0 + reqCountLock.Unlock() + } + }() + + resps := make(chan BlockResponse, batchSize) + var wg sync.WaitGroup + for base := startBlock; base < endBlock; base += batchSize { + fmt.Println("loop") + // Send batchSize requests and process them asynchronously + for block := base; block < base+batchSize; block++ { + wg.Add(1) + go func(wg *sync.WaitGroup, block int) { + defer wg.Done() + params := []interface{}{IntToHex(block), false} + resp, err := SendJSONRPCRequest(url, method, params) + reqCountLock.Lock() + reqCount++ + reqCountLock.Unlock() + if err != nil { + fmt.Println("Error:", err) + } + resps <- resp.Result + }(&wg, block) + + } + go func() { + wg.Wait() + close(resps) + }() + + for resp := range resps { + fmt.Println(resp) + } + } + +} + +func IntToHex(i int) string { + return fmt.Sprintf("0x%x", i) +} diff --git a/go/simreq/simreq b/go/simreq/simreq new file mode 100755 index 0000000..ec35427 Binary files /dev/null and b/go/simreq/simreq differ