Commit 4d5b0407 authored by vicotor's avatar vicotor

add detail request log

parent 8d7de62c
......@@ -4,6 +4,7 @@ import (
"bytes"
"database/sql"
"encoding/json"
"github.com/ethereum/go-ethereum/common/lru"
"io"
"log"
"net"
......@@ -68,6 +69,11 @@ type RPCResponse struct {
Error interface{} `json:"error,omitempty"`
}
type TxArgs struct {
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
}
var (
db *sql.DB
rpcBackend = os.Getenv("ETH_RPC_BACKEND") // Real Ethereum RPC address, recommend using environment variable
......@@ -106,6 +112,9 @@ var (
localBlacklistFile string
localBlacklist map[string]struct{}
localBlacklistMu sync.RWMutex
// tx cache lru
txCache = lru.NewCache[string, TxArgs](10000)
)
type visitor struct {
......@@ -271,17 +280,17 @@ func main() {
func isSendTxFromBlacklist(req RPCRequest, ip string) bool {
if req.Method == "eth_sendRawTransaction" && len(req.Params) > 0 {
if rawHex, ok := req.Params[0].(string); ok {
if fromAddr, err := getSenderFromRawTx(rawHex); err == nil {
if txArgs, ok := getEthTx(rawHex); ok {
// Check local blacklist first
if isLocalBlacklisted(fromAddr) {
log.Printf("sender %s is in local blacklist, banning IP %s\n", fromAddr, ip)
if isLocalBlacklisted(txArgs.From) {
log.Printf("sender %s is in local blacklist, banning IP %s\n", txArgs.From, ip)
return true
} else {
// check in contract blacklist.
if ethClient != nil && blacklistContract != (common.Address{}) {
inBlack, _ := CachedIsInBlacklist(ethClient, blacklistContract, common.HexToAddress(strings.ToLower(fromAddr)))
inBlack, _ := CachedIsInBlacklist(ethClient, blacklistContract, common.HexToAddress(strings.ToLower(txArgs.From)))
if inBlack {
log.Printf("sender %s is in contract blacklist, banning IP %s\n", fromAddr, ip)
log.Printf("sender %s is in contract blacklist, banning IP %s\n", txArgs.From, ip)
return inBlack
}
}
......@@ -307,6 +316,36 @@ func isFromInBlacklist(addr string) bool {
return false
}
func dumpRequestInfo(req RPCRequest, ip string) {
switch req.Method {
case "eth_sendTransaction":
// get rawtx and unmarshal to get from and to.
if rawHex, ok := req.Params[0].(string); ok {
if txArgs, ok := getEthTx(rawHex); ok {
log.Printf("detail request %s from ip %s, from: %s, to: %s\n", req.Method, ip, txArgs.From, txArgs.To)
}
}
case "eth_call", "eth_estimateGas":
param := req.Params[0]
// how to parse the json struct to go struct CallArgs
if argMap, ok := param.(map[string]interface{}); ok {
from, _ := argMap["from"].(string)
to, _ := argMap["to"].(string)
if from != "" && to != "" {
log.Printf("detail request %s from ip %s, from: %s, to: %s\n", req.Method, ip, from, to)
}
}
case "eth_getBalance", "eth_getTransactionCount":
from, ok := req.Params[0].(string)
if ok {
log.Printf("detail request %s from ip %s, from: %s\n", req.Method, ip, from)
}
default:
}
}
func proxyHandler(w http.ResponseWriter, r *http.Request) {
// Add CORS support
setCORSHeaders(w, r)
......@@ -398,6 +437,8 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
}
// dump ip, method, from, to info.
dumpRequestInfo(req, ip)
}
forwardToBackend(w, body)
}
......@@ -474,21 +515,25 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
}
dumpRequestInfo(req, ip)
// Forward other cases directly
forwardToBackend(w, body)
}
// getSenderFromRawTx decodes a raw transaction hex (0x...) and returns the sender address as a hex string.
func getSenderFromRawTx(rawHex string) (string, error) {
func getEthTx(rawHex string) (TxArgs, bool) {
if v, exist := txCache.Get(rawHex); exist {
return v, true
}
arg := TxArgs{}
// strip 0x if present
b, err := hexutil.Decode(rawHex)
if err != nil {
return "", err
return arg, false
}
var tx types.Transaction
if err := tx.UnmarshalBinary(b); err != nil {
return "", err
return arg, false
}
// determine signer
var signer types.Signer
......@@ -499,9 +544,23 @@ func getSenderFromRawTx(rawHex string) (string, error) {
}
from, err := types.Sender(signer, &tx)
if err != nil {
return "", err
return arg, false
}
arg.From = strings.ToLower(from.Hex())
if tx.To() != nil {
arg.To = strings.ToLower(tx.To().Hex())
}
txCache.Add(rawHex, arg)
return arg, true
}
// getSenderFromRawTx decodes a raw transaction hex (0x...) and returns the sender address as a hex string.
func getSenderFromRawTx(rawHex string) (string, error) {
txArgs, ok := getEthTx(rawHex)
if !ok {
return "", fmt.Errorf("failed to decode raw transaction")
}
return strings.ToLower(from.Hex()), nil
return txArgs.From, nil
}
func setCORSHeaders(w http.ResponseWriter, r *http.Request) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment