From 14c9696a4c940a3a675249571a60c00667a8b772 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Fri, 30 Aug 2024 11:29:40 +0300 Subject: [PATCH 1/5] Webhook server --- examples/webhooks/go.mod | 3 +++ examples/webhooks/main.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 examples/webhooks/go.mod create mode 100644 examples/webhooks/main.go diff --git a/examples/webhooks/go.mod b/examples/webhooks/go.mod new file mode 100644 index 0000000..e5b6881 --- /dev/null +++ b/examples/webhooks/go.mod @@ -0,0 +1,3 @@ +module github.com/tonkeeper/tonapi-go/examples/webhooks + +go 1.22.0 diff --git a/examples/webhooks/main.go b/examples/webhooks/main.go new file mode 100644 index 0000000..a466301 --- /dev/null +++ b/examples/webhooks/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type AccountTxPayload struct { + AccountID string `json:"account_id"` + Lt int64 `json:"lt"` + TxHash string `json:"tx_hash"` +} + +func webhook(w http.ResponseWriter, req *http.Request) { + defer req.Body.Close() + + var payload AccountTxPayload + if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + + fmt.Printf("%v\n", payload) + w.WriteHeader(http.StatusOK) +} + +func main() { + http.HandleFunc("/", webhook) + http.ListenAndServe(":8092", nil) +} From 4ae5d388bec16deadda9efa348ac484d576412b3 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Tue, 12 Nov 2024 15:52:52 +0300 Subject: [PATCH 2/5] Add mempool events --- examples/webhooks/main.go | 44 +++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/examples/webhooks/main.go b/examples/webhooks/main.go index a466301..5d5986b 100644 --- a/examples/webhooks/main.go +++ b/examples/webhooks/main.go @@ -1,9 +1,12 @@ package main import ( + "crypto/sha256" + "encoding/hex" "encoding/json" "fmt" "net/http" + "sync" ) type AccountTxPayload struct { @@ -12,20 +15,53 @@ type AccountTxPayload struct { TxHash string `json:"tx_hash"` } +type MempoolEvent struct { + EventType string `json:"event_type"` + Boc string `json:"boc"` +} + +var ( + mu sync.Mutex + hashes = make(map[string]int) +) + func webhook(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() - var payload AccountTxPayload + fmt.Printf("req: %v\n", req.Method) + for name, header := range req.Header { + fmt.Printf("header: %v -> %#v\n", name, header) + + } + var payload MempoolEvent if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { w.WriteHeader(http.StatusBadRequest) return } - fmt.Printf("%v\n", payload) + hash := sha256.New() + hash.Write([]byte(payload.Boc)) + payloadHash := hash.Sum(nil) + payloadHex := hex.EncodeToString(payloadHash) + w.WriteHeader(http.StatusOK) + + mu.Lock() + defer mu.Unlock() + + hashes[payloadHex] += 1 + + value := hashes[payloadHex] + if value > 2 { + fmt.Printf("payload hex %v -> %v\n", payloadHex, value) + } + + if len(hashes) > 100_000 { + hashes = make(map[string]int) + } } func main() { - http.HandleFunc("/", webhook) - http.ListenAndServe(":8092", nil) + http.HandleFunc("/webhook", webhook) + http.ListenAndServe(":8030", nil) } From 37f0fdb70a713896fc3e7eb762d7b3fef9bbdbc1 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Tue, 12 Nov 2024 16:05:08 +0300 Subject: [PATCH 3/5] Change logic --- examples/webhooks/main.go | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/examples/webhooks/main.go b/examples/webhooks/main.go index 5d5986b..8c6c31b 100644 --- a/examples/webhooks/main.go +++ b/examples/webhooks/main.go @@ -21,18 +21,19 @@ type MempoolEvent struct { } var ( - mu sync.Mutex - hashes = make(map[string]int) + mu sync.Mutex + hashes = make(map[string]int) + messagesCounter = 0 ) func webhook(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() - fmt.Printf("req: %v\n", req.Method) - for name, header := range req.Header { - fmt.Printf("header: %v -> %#v\n", name, header) - - } + //fmt.Printf("req: %v\n", req.Method) + //for name, header := range req.Header { + // fmt.Printf("header: %v -> %#v\n", name, header) + // + //} var payload MempoolEvent if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { w.WriteHeader(http.StatusBadRequest) @@ -50,10 +51,21 @@ func webhook(w http.ResponseWriter, req *http.Request) { defer mu.Unlock() hashes[payloadHex] += 1 + messagesCounter += 1 - value := hashes[payloadHex] - if value > 2 { - fmt.Printf("payload hex %v -> %v\n", payloadHex, value) + //value := hashes[payloadHex] + //if value > 2 { + // //fmt.Printf("payload hex %v -> %v\n", payloadHex, value) + //} + if messagesCounter%1000 == 0 { + x := 0 + for _, value := range hashes { + if value > 2 { + x += 1 + } + } + percent := float64(x) / float64(len(hashes)) * 100.0 + fmt.Printf("%0.2f\n", percent) } if len(hashes) > 100_000 { From c802bfd88a0c7f1e8ee5752e544ced374feb5724 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Tue, 12 Nov 2024 16:06:56 +0300 Subject: [PATCH 4/5] Fix --- examples/webhooks/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webhooks/main.go b/examples/webhooks/main.go index 8c6c31b..2a530ef 100644 --- a/examples/webhooks/main.go +++ b/examples/webhooks/main.go @@ -57,7 +57,7 @@ func webhook(w http.ResponseWriter, req *http.Request) { //if value > 2 { // //fmt.Printf("payload hex %v -> %v\n", payloadHex, value) //} - if messagesCounter%1000 == 0 { + if messagesCounter%100 == 0 { x := 0 for _, value := range hashes { if value > 2 { From 181c51efcc9cc1adc3fa49e97b21118782342e69 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Fri, 15 Nov 2024 10:56:22 +0300 Subject: [PATCH 5/5] Update --- examples/webhooks/main.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/webhooks/main.go b/examples/webhooks/main.go index 2a530ef..4aa099e 100644 --- a/examples/webhooks/main.go +++ b/examples/webhooks/main.go @@ -26,10 +26,10 @@ var ( messagesCounter = 0 ) -func webhook(w http.ResponseWriter, req *http.Request) { +func webhookMempool(w http.ResponseWriter, req *http.Request) { defer req.Body.Close() - //fmt.Printf("req: %v\n", req.Method) + fmt.Printf("req: %v\n", req.Method) //for name, header := range req.Header { // fmt.Printf("header: %v -> %#v\n", name, header) // @@ -73,7 +73,25 @@ func webhook(w http.ResponseWriter, req *http.Request) { } } +func webhook(w http.ResponseWriter, req *http.Request) { + defer req.Body.Close() + + fmt.Printf("req: %v\n", req.Method) + //for name, header := range req.Header { + // fmt.Printf("header: %v -> %#v\n", name, header) + // + //} + var payload AccountTxPayload + if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + fmt.Printf("%v %v %v\n", payload.AccountID, payload.Lt, payload.TxHash) + +} + func main() { http.HandleFunc("/webhook", webhook) - http.ListenAndServe(":8030", nil) + http.HandleFunc("/webhook-mempool", webhookMempool) + http.ListenAndServe(":8090", nil) }