Skip to content

Commit

Permalink
db2/BigTableEthRaw: handle index for get uncle
Browse files Browse the repository at this point in the history
export BlocRawTable
  • Loading branch information
Tangui-Bitfly committed Oct 14, 2024
1 parent 448767f commit bcb8340
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 99 deletions.
185 changes: 101 additions & 84 deletions backend/pkg/commons/db2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,89 +62,15 @@ func (r *BigTableEthRaw) RoundTrip(request *http.Request) (*http.Response, error
}
messages = append(messages, message)
}
var resps []jsonrpcMessage
var resps []*jsonrpcMessage
for _, message := range messages {
var respBody []byte
switch message.Method {
case "eth_getBlockByNumber":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

// we decode only big.Int maybe we should also handle "latest"
block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.BlockByNumber(request.Context(), block)
if err != nil {
return nil, err
}
respBody = b

case "debug_traceBlockByNumber":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.TraceBlockByNumber(request.Context(), block)
if err != nil {
return nil, err
}
respBody = b

case "eth_getBlockReceipts":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.BlockReceipts(request.Context(), block)
if err != nil {
return nil, err
}
respBody = b

case "eth_getUncleByBlockHashAndIndex":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}
number, exist := r.hashToNumber.Load(args[0].(string))
if !exist {
return nil, fmt.Errorf("cannot find hash '%s' in cache", args[0].(string))
}

index, err := hexutil.DecodeBig(args[1].(string))
if err != nil {
return nil, err
}
// TODO handle index
b, err := r.UncleByBlockNumberAndIndex(request.Context(), number.(*big.Int), index.Int64())
if err != nil {
return nil, err
}
respBody = b
resp, err := r.handle(request.Context(), message)
if err != nil {
return &http.Response{
Body: io.NopCloser(bytes.NewBufferString(err.Error())),
StatusCode: http.StatusBadRequest,
}, nil
}
if len(respBody) == 0 {
continue
}
var resp jsonrpcMessage
_ = json.Unmarshal(respBody, &resp)
resp.ID = message.ID
resps = append(resps, resp)
}

Expand All @@ -157,7 +83,91 @@ func (r *BigTableEthRaw) RoundTrip(request *http.Request) (*http.Response, error
}, nil
}

func makeBody(isSingle bool, messages []jsonrpcMessage) io.ReadCloser {
func (r *BigTableEthRaw) handle(ctx context.Context, message *jsonrpcMessage) (*jsonrpcMessage, error) {
var respBody []byte
switch message.Method {
case "eth_getBlockByNumber":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

// we decode only big.Int maybe we should also handle "latest"
block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.BlockByNumber(ctx, block)
if err != nil {
return nil, err
}
respBody = b

case "debug_traceBlockByNumber":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.TraceBlockByNumber(ctx, block)
if err != nil {
return nil, err
}
respBody = b

case "eth_getBlockReceipts":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}

block, err := hexutil.DecodeBig(args[0].(string))
if err != nil {
return nil, err
}

b, err := r.BlockReceipts(ctx, block)
if err != nil {
return nil, err
}
respBody = b

case "eth_getUncleByBlockHashAndIndex":
var args []interface{}
if err := json.Unmarshal(message.Params, &args); err != nil {
return nil, err
}
number, exist := r.hashToNumber.Load(args[0].(string))
if !exist {
return nil, fmt.Errorf("cannot find hash '%s' in cache", args[0].(string))
}

index, err := hexutil.DecodeBig(args[1].(string))
if err != nil {
return nil, err
}
b, err := r.UncleByBlockNumberAndIndex(ctx, number.(*big.Int), index.Int64())
if err != nil {
return nil, err
}
respBody = b
}
if len(respBody) == 0 {
return nil, nil
}
var resp jsonrpcMessage
_ = json.Unmarshal(respBody, &resp)
resp.ID = message.ID
return &resp, nil
}

func makeBody(isSingle bool, messages []*jsonrpcMessage) io.ReadCloser {
var b []byte
if isSingle {
b, _ = json.Marshal(messages[0])

Check failure on line 173 in backend/pkg/commons/db2/client.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `encoding/json.Marshal` is not checked: unsafe type `encoding/json.RawMessage` found (errchkjson)
Expand Down Expand Up @@ -212,8 +222,15 @@ func (r *BigTableEthRaw) UncleByBlockNumberAndIndex(ctx context.Context, number
if err != nil {
return nil, err
}
// TODO handle index
return block.Uncles, nil

// len of one uncle without tx is 1473
if len(block.Uncles) < 2000 {
return block.Uncles, nil
}
// we have two uncles so we need to retrieve the good index
var uncles []*jsonrpcMessage
_ = json.Unmarshal(block.Uncles, &uncles)
return json.Marshal(uncles[index])
}

// A value of this type can a JSON-RPC request, notification, successful response or
Expand Down
22 changes: 12 additions & 10 deletions backend/pkg/commons/db2/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ import (

func TestBigTableClient(t *testing.T) {
tests := []struct {
name string
number int64
block FullBlockRawData
name string
block FullBlockRawData
}{
{
name: "test block",
number: testBlockNumber,
block: testFullBlock,
name: "test block",
block: testFullBlock,
},
{
name: "two uncles",
block: testTwoUnclesFullBlock,
},
}

Expand All @@ -36,7 +38,7 @@ func TestBigTableClient(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rawStore := NewRawStore(store.Wrap(bg, blocRawTable, ""))
rawStore := NewRawStore(store.Wrap(bg, BlocRawTable, ""))
if err := rawStore.AddBlocks([]FullBlockRawData{tt.block}); err != nil {
t.Fatal(err)
}
Expand All @@ -49,15 +51,15 @@ func TestBigTableClient(t *testing.T) {
}
ethClient := ethclient.NewClient(rpcClient)

block, err := ethClient.BlockByNumber(context.Background(), big.NewInt(tt.number))
block, err := ethClient.BlockByNumber(context.Background(), big.NewInt(tt.block.BlockNumber))
if err != nil {
t.Fatalf("BlockByNumber() error = %v", err)
}
if got, want := block.Number().Int64(), tt.number; got != want {
if got, want := block.Number().Int64(), tt.block.BlockNumber; got != want {
t.Errorf("got %v, want %v", got, want)
}

receipts, err := ethClient.BlockReceipts(context.Background(), rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(tt.number)))
receipts, err := ethClient.BlockReceipts(context.Background(), rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(tt.block.BlockNumber)))
if err != nil {
t.Fatalf("BlockReceipts() error = %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/pkg/commons/db2/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (db RawStore) AddBlocks(blocks []FullBlockRawData) error {
itemsByKey := make(map[string][]store.Item)
for _, fullBlock := range blocks {
if len(fullBlock.Block) == 0 || len(fullBlock.Traces) == 0 {
return fmt.Errorf("empty data")
return fmt.Errorf("block %d: empty data", fullBlock.BlockNumber)
}
key := blockKey(fullBlock.ChainID, fullBlock.BlockNumber)

Expand Down
107 changes: 106 additions & 1 deletion backend/pkg/commons/db2/raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestRaw(t *testing.T) {
}

db := RawStore{
store: store.Wrap(s, blocRawTable, ""),
store: store.Wrap(s, BlocRawTable, ""),
compressor: noOpCompressor{},
}

Expand Down Expand Up @@ -66,6 +66,16 @@ var testFullBlock = FullBlockRawData{
Uncles: []byte(testUncles),
}

var testTwoUnclesFullBlock = FullBlockRawData{
ChainID: 1,
BlockNumber: testTwoUnclesBlockNumber,
BlockUnclesCount: 2,
Block: []byte(testTwoUnclesBlock),
Receipts: []byte(testReceipts),
Traces: []byte(testTraces),
Uncles: []byte(testTwoUnclesBlockUncles),
}

const (
testBlockNumber = 6008149
testBlock = `{
Expand Down Expand Up @@ -330,4 +340,99 @@ const (
"uncles": []
}
}`

testTwoUnclesBlockNumber = 141
testTwoUnclesBlock = `{
"jsonrpc":"2.0",
"id":0,
"result":{
"difficulty":"0x4417decf7",
"extraData":"0x426974636f696e2069732054484520426c6f636b636861696e2e",
"gasLimit":"0x1388",
"gasUsed":"0x0",
"hash":"0xeafbe76fdcadc1b69ba248589eb2a674b60b00c84374c149c9deaf5596183932",
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner":"0x1b7047b4338acf65be94c1a3e8c5c9338ad7d67c",
"mixHash":"0x21eabda67c3151855389a5a968e50daa7b356b3046e2f119ef46c97d204a541e",
"nonce":"0x85378a3fc5e608e1",
"number":"0x8d",
"parentHash":"0xe2c1e8200ef2e9fba09979f0b504dc52c068719623c7064904c7bd3e9365acc1",
"receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles":"0x393f5f01182846b91386f8b00759fd54f83998a6a1064b8ac72fc8eca1bcf81b",
"size":"0x653",
"stateRoot":"0x3e1eea9a01178945535230b6f5839201f594d9be20618bb4edaa383f4f0c850f",
"timestamp":"0x55ba4444",
"totalDifficulty":"0x24826e73469",
"transactions":[
],
"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles":[
"0x61beeeb3e11e89d19fed2e988c8017b55c3ddb8895f531072363ce2abaf56b95",
"0xf84d9d74415364c3a7569f315ff831b910968c7dd637fffaab51278c9e7f9306"
]
}
}`
testTwoUnclesBlockUncles = `[
{
"jsonrpc":"2.0",
"id":141,
"result":{
"difficulty":"0x4406dc086",
"extraData":"0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32",
"gasLimit":"0x1388",
"gasUsed":"0x0",
"hash":"0x61beeeb3e11e89d19fed2e988c8017b55c3ddb8895f531072363ce2abaf56b95",
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner":"0xbb7b8287f3f0a933474a79eae42cbca977791171",
"mixHash":"0x87547a998fe63f18b36180ca918131b6b20fc5d67390e2ac2f66be3fee8fb7d2",
"nonce":"0x1dc5b79704350bee",
"number":"0x8b",
"parentHash":"0x2253b8f79c23b6ff67cb2ef6fabd9ec59e1edf2d07c16d98a19378041f96624d",
"receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size":"0x21f",
"stateRoot":"0x940131b162b07452ea31b5335c4dedfdddc13338142f71f261d51dea664033b4",
"timestamp":"0x55ba4441",
"totalDifficulty":"0x24826e73469",
"transactions":[
],
"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles":[
]
}
},
{
"jsonrpc":"2.0",
"id":141,
"result":{
"difficulty":"0x4406dc086",
"extraData":"0x476574682f6b6c6f737572652f76312e302e302d66633739643332642f6c696e",
"gasLimit":"0x1388",
"gasUsed":"0x0",
"hash":"0xf84d9d74415364c3a7569f315ff831b910968c7dd637fffaab51278c9e7f9306",
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner":"0xd7e30ae310c1d1800f5b641baa7af95b2e1fd98c",
"mixHash":"0x6039f236ebb70ec71091df5770aef0f0faa13ef334c4c68daaffbfdf7961a3d3",
"nonce":"0x7d8ec05d330e6e99",
"number":"0x8b",
"parentHash":"0x2253b8f79c23b6ff67cb2ef6fabd9ec59e1edf2d07c16d98a19378041f96624d",
"receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size":"0x221",
"stateRoot":"0x302bb7708752013f46f009dec61cad586c35dc185d20cdde0071b7487f7c2008",
"timestamp":"0x55ba4440",
"totalDifficulty":"0x24826e73469",
"transactions":[
],
"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"uncles":[
]
}
}
]`
)
Loading

0 comments on commit bcb8340

Please sign in to comment.