-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ea7687a
Showing
12 changed files
with
1,037 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# docker build . -t ghcr.io/reddio-com/eth_logcache:latest | ||
FROM golang:1.22-bookworm as builder | ||
|
||
RUN mkdir /build | ||
COPY . /build | ||
RUN cd /build && go build . | ||
|
||
FROM debian:bookworm-slim | ||
|
||
RUN apt-get update && apt-get install -y ca-certificates && apt-get clean | ||
|
||
RUN mkdir /data | ||
COPY --from=builder /build/main /logcache | ||
|
||
CMD ["/logcache"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# ETH LogCache | ||
|
||
## Usage | ||
|
||
### Start the service using Docker Compose | ||
|
||
``` | ||
docker-compose up -d | ||
``` | ||
|
||
or, you can build and run with environment variables: | ||
|
||
``` | ||
RPC_URL=https://eth-mainnet.reddio.com START_BLOCK=15560257 go run . | ||
``` | ||
|
||
### Send request to ETH LogCache | ||
|
||
```sh | ||
curl -X POST \ | ||
-H "Content-Type: application/json" \ | ||
-d '{ | ||
"method": "eth_getLogs", | ||
"params": [ | ||
{ | ||
"fromBlock": "0x0", | ||
"toBlock": "0x120dc53", | ||
"address": "0xb62bcd40a24985f560b5a9745d478791d8f1945c", | ||
"topics": [ | ||
[ | ||
"0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2" | ||
] | ||
] | ||
} | ||
], | ||
"id": 62, | ||
"jsonrpc": "2.0" | ||
}' \ | ||
http://localhost:3000 | ||
``` | ||
|
||
Response: | ||
```json | ||
{"block_number":[{"id":62,"jsonrpc":"2.0","result":[{"address":"0xb62bcd40a24985f560b5a9745d478791d8f1945c","blockHash":"0xb1c05e3a5f7791b40d9ded2bb67bd2d250f1ccb036dac0f6a046b7ed2d416df0","blockNumber":"0xed6e42","data":"0x0000000000000000000000006b7763b749073e892c83e674c1ec4799d6f339ef","logIndex":"0x151","removed":false,"topics":["0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2"],"transactionHash":"0x87130dfe52f1eb4ec22261333534ee7ac2c15e5256ffa7a59ae7153119c6cd73","transactionIndex":"0xc9"},{"address":"0xb62bcd40a24985f560b5a9745d478791d8f1945c","blockHash":"0xb1c05e3a5f7791b40d9ded2bb67bd2d250f1ccb036dac0f6a046b7ed2d416df0","blockNumber":"0xed6e42","data":"0x0000000000000000000000006ea99c6fe2c770c2c46ebe03a4855977282e844f","logIndex":"0x153","removed":false,"topics":["0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2"],"transactionHash":"0xca00caf8ad277bd23597d497e1c77b4308d40e8787d7e0e5204d320f1f3ab31c","transactionIndex":"0xcb"}]}]} | ||
``` | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
## Timeout Request | ||
|
||
Origin Request: | ||
|
||
* 0x0 -> 0 | ||
* 0x120dc53 -> 18930771 | ||
|
||
```json | ||
{ | ||
"method": "eth_getLogs", | ||
"params": [ | ||
{ | ||
"fromBlock": "0x0", | ||
"toBlock": "0x120dc53", | ||
"address": "0xb62bcd40a24985f560b5a9745d478791d8f1945c", | ||
"topics": [ | ||
[ | ||
"0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2" | ||
] | ||
] | ||
} | ||
], | ||
"id": 62, | ||
"jsonrpc": "2.0" | ||
} | ||
``` | ||
|
||
Response: | ||
|
||
```json | ||
{ | ||
"jsonrpc": "2.0", | ||
"id": 62, | ||
"result": [ | ||
{ | ||
"address": "0xb62bcd40a24985f560b5a9745d478791d8f1945c", | ||
"blockHash": "0xb1c05e3a5f7791b40d9ded2bb67bd2d250f1ccb036dac0f6a046b7ed2d416df0", | ||
"blockNumber": "0xed6e42", | ||
"data": "0x0000000000000000000000006b7763b749073e892c83e674c1ec4799d6f339ef", | ||
"logIndex": "0x151", | ||
"removed": false, | ||
"topics": [ | ||
"0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2" | ||
], | ||
"transactionHash": "0x87130dfe52f1eb4ec22261333534ee7ac2c15e5256ffa7a59ae7153119c6cd73", | ||
"transactionIndex": "0xc9" | ||
}, | ||
{ | ||
"address": "0xb62bcd40a24985f560b5a9745d478791d8f1945c", | ||
"blockHash": "0xb1c05e3a5f7791b40d9ded2bb67bd2d250f1ccb036dac0f6a046b7ed2d416df0", | ||
"blockNumber": "0xed6e42", | ||
"data": "0x0000000000000000000000006ea99c6fe2c770c2c46ebe03a4855977282e844f", | ||
"logIndex": "0x153", | ||
"removed": false, | ||
"topics": [ | ||
"0xcfb473e6c03f9a29ddaf990e736fa3de5188a0bd85d684f5b6e164ebfbfff5d2" | ||
], | ||
"transactionHash": "0xca00caf8ad277bd23597d497e1c77b4308d40e8787d7e0e5204d320f1f3ab31c", | ||
"transactionIndex": "0xcb" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
|
||
|
||
## Verify Request | ||
|
||
Original Request: | ||
|
||
* 0x121AE54 -> 18984532 | ||
* 0x121e2be -> 18997950 | ||
|
||
```json | ||
{ | ||
"method": "eth_getLogs", | ||
"params": [ | ||
{ | ||
"fromBlock": "0x121AE54", | ||
"toBlock": "0x121e2be", | ||
"address": "0x15e6e0d4ebeac120f9a97e71faa6a0235b85ed12", | ||
"topics": [ | ||
[ | ||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" | ||
] | ||
] | ||
} | ||
], | ||
"id": 62, | ||
"jsonrpc": "2.0" | ||
} | ||
``` | ||
|
||
Response: | ||
|
||
```json | ||
{ | ||
"jsonrpc": "2.0", | ||
"id": 62, | ||
"result": [ | ||
{ | ||
"address": "0x15e6e0d4ebeac120f9a97e71faa6a0235b85ed12", | ||
"blockHash": "0xbca59ccc09a7bb1e6877c943fce30e7d3482cc461769d98f5b7ede1d36e02463", | ||
"blockNumber": "0x121ae54", | ||
"data": "0x0000000000000000000000000000000000000000000000006e2255f409800000", | ||
"logIndex": "0xa9", | ||
"removed": false, | ||
"topics": [ | ||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
"0x000000000000000000000000f328a29acc598ff8a399e45d8b11be22ef6d3987" | ||
], | ||
"transactionHash": "0xa6a4412d64971843db5babcf25b9f5644acd295be8ff3ebbdc38e61276b713dd", | ||
"transactionIndex": "0x66" | ||
}, | ||
{ | ||
"address": "0x15e6e0d4ebeac120f9a97e71faa6a0235b85ed12", | ||
"blockHash": "0xacd6dda9c3030cef969feb8aa46730e7c929b2267b9b4291d680ed964f0a653e", | ||
"blockNumber": "0x121e2be", | ||
"data": "0x0000000000000000000000000000000000000000000000003782dace9d900000", | ||
"logIndex": "0xaa", | ||
"removed": false, | ||
"topics": [ | ||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", | ||
"0x000000000000000000000000f328a29acc598ff8a399e45d8b11be22ef6d3987", | ||
"0x000000000000000000000000861e3c82bc2753ea64ae5f962d993df6853a6700" | ||
], | ||
"transactionHash": "0x6c42543f5371e174ba751acb41f8ef9f78366fb996646203bffa43b489606bf0", | ||
"transactionIndex": "0x7d" | ||
}, | ||
{ | ||
"address": "0x15e6e0d4ebeac120f9a97e71faa6a0235b85ed12", | ||
"blockHash": "0xacd6dda9c3030cef969feb8aa46730e7c929b2267b9b4291d680ed964f0a653e", | ||
"blockNumber": "0x121e2be", | ||
"data": "0x0000000000000000000000000000000000000000000000003782dace9d900000", | ||
"logIndex": "0xab", | ||
"removed": false, | ||
"topics": [ | ||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", | ||
"0x000000000000000000000000861e3c82bc2753ea64ae5f962d993df6853a6700", | ||
"0x0000000000000000000000000000000000000000000000000000000000000000" | ||
], | ||
"transactionHash": "0x6c42543f5371e174ba751acb41f8ef9f78366fb996646203bffa43b489606bf0", | ||
"transactionIndex": "0x7d" | ||
} | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"math/big" | ||
) | ||
|
||
func LatestBlockOnChain() (uint64, error) { | ||
header, err := ETH_CLIENT.HeaderByNumber(context.Background(), nil) | ||
if err != nil { | ||
return 0, fmt.Errorf("Failed to get latest block header: %v", err) | ||
} | ||
|
||
return header.Number.Uint64(), nil | ||
} | ||
|
||
func getTopicListByBlockNumber(blockNumber uint64) ([]string, error) { | ||
blockNumberBig := new(big.Int) | ||
blockNumberBig.SetUint64(blockNumber) | ||
block, err := ETH_CLIENT.BlockByNumber(context.Background(), blockNumberBig) | ||
for err != nil { | ||
fmt.Printf("Failed to get block: %v\n", err) | ||
block, err = ETH_CLIENT.BlockByNumber(context.Background(), blockNumberBig) | ||
} | ||
|
||
totalTopics := make([]string, 0) | ||
|
||
for _, tx := range block.Transactions() { | ||
// fmt.Printf("Dealing with transaction: %s\n", tx.Hash().Hex()) | ||
|
||
receipt, err := ETH_CLIENT.TransactionReceipt(context.Background(), tx.Hash()) | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed to get transaction receipt: %v", err) | ||
} | ||
|
||
for _, log := range receipt.Logs { | ||
for _, topic := range log.Topics { | ||
totalTopics = append(totalTopics, topic.Hex()) | ||
} | ||
} | ||
} | ||
|
||
return totalTopics, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/binary" | ||
"fmt" | ||
|
||
"github.com/cockroachdb/pebble" | ||
) | ||
|
||
var ( | ||
DB *pebble.DB | ||
) | ||
|
||
func Uint64ArrayToByteSlice(array []uint64) []byte { | ||
byteSlice := make([]byte, 8*len(array)) | ||
for i, v := range array { | ||
binary.LittleEndian.PutUint64(byteSlice[i*8:], v) | ||
} | ||
return byteSlice | ||
} | ||
|
||
func ByteSliceToUint64Array(byteSlice []byte) []uint64 { | ||
array := make([]uint64, len(byteSlice)/8) | ||
for i := range array { | ||
array[i] = binary.LittleEndian.Uint64(byteSlice[i*8:]) | ||
} | ||
return array | ||
} | ||
|
||
func DeduplicateUint64Array(array []uint64) []uint64 { | ||
keys := make(map[uint64]bool) | ||
list := []uint64{} | ||
for _, entry := range array { | ||
if _, value := keys[entry]; !value { | ||
keys[entry] = true | ||
list = append(list, entry) | ||
} | ||
} | ||
return list | ||
} | ||
|
||
func SetKeyNumberArray(key string, number uint64) error { | ||
// Check if key exists, if exists, read array and append number to array | ||
// If not exists, create array with number | ||
keyByteSlice := []byte(key) | ||
existingNumberArray, err := GetKeyNumberArray(key) | ||
if err != nil { | ||
return err | ||
} | ||
if existingNumberArray != nil { | ||
// Append number to array | ||
existingNumberArray = append(existingNumberArray, number) | ||
|
||
// Deduplicate array | ||
existingNumberArray = DeduplicateUint64Array(existingNumberArray) | ||
|
||
numberByteSlice := Uint64ArrayToByteSlice(existingNumberArray) | ||
err := DB.Set(keyByteSlice, numberByteSlice, pebble.NoSync) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} else { | ||
// Create array with number | ||
numberArray := []uint64{number} | ||
numberByteSlice := Uint64ArrayToByteSlice(numberArray) | ||
err := DB.Set(keyByteSlice, numberByteSlice, pebble.NoSync) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
func SetKeyNumber(key string, number uint64) error { | ||
keyByteSlice := []byte(key) | ||
value := make([]byte, 8) | ||
binary.LittleEndian.PutUint64(value, uint64(number)) | ||
err := DB.Set(keyByteSlice, value, pebble.Sync) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func GetKeyNumberArray(key string) ([]uint64, error) { | ||
keyByteSlice := []byte(key) | ||
value, closer, err := DB.Get(keyByteSlice) | ||
if err != nil { | ||
// Check if key is not found | ||
if err == pebble.ErrNotFound { | ||
return nil, nil | ||
} | ||
return nil, err | ||
} | ||
defer closer.Close() | ||
|
||
numberArray := ByteSliceToUint64Array(value) | ||
return numberArray, nil | ||
} | ||
|
||
func GetKeyNumber(key string) (uint64, error) { | ||
keyByteSlice := []byte(key) | ||
value, closer, err := DB.Get(keyByteSlice) | ||
if err != nil { | ||
// Check if key is not found | ||
if err == pebble.ErrNotFound { | ||
fmt.Printf("Key %s not found\n", key) | ||
return 0, nil | ||
} | ||
} | ||
defer closer.Close() | ||
|
||
number := binary.LittleEndian.Uint64(value) | ||
return number, nil | ||
} | ||
|
||
func FlushDB() error { | ||
err := DB.Flush() | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func LatestBlockNumberInDB() (uint64, error) { | ||
key := "LatestBlockNumberInDB" | ||
number, err := GetKeyNumber(key) | ||
if err != nil { | ||
return 0, err | ||
} | ||
return number, nil | ||
} |
Oops, something went wrong.