feat(cache and trace api): Add redis cache in database and add trace api in bridge.l2backend. (#228)

Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: colinlyguo <colinlyguo@gmail.com>
This commit is contained in:
maskpp
2023-01-29 09:56:25 +08:00
committed by GitHub
parent 16576b6f53
commit b5549f6301
51 changed files with 775 additions and 241 deletions

View File

@@ -1,8 +1,8 @@
package orm
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"strings"
@@ -12,18 +12,24 @@ import (
"github.com/scroll-tech/go-ethereum/core/types"
"github.com/scroll-tech/go-ethereum/log"
"scroll-tech/database/cache"
"scroll-tech/common/utils"
)
type blockTraceOrm struct {
db *sqlx.DB
db *sqlx.DB
cache cache.Cache
}
var _ BlockTraceOrm = (*blockTraceOrm)(nil)
// NewBlockTraceOrm create an blockTraceOrm instance
func NewBlockTraceOrm(db *sqlx.DB) BlockTraceOrm {
return &blockTraceOrm{db: db}
func NewBlockTraceOrm(db *sqlx.DB, cache cache.Cache) BlockTraceOrm {
return &blockTraceOrm{
db: db,
cache: cache,
}
}
func (o *blockTraceOrm) Exist(number uint64) (bool, error) {
@@ -49,11 +55,7 @@ func (o *blockTraceOrm) GetBlockTracesLatestHeight() (int64, error) {
}
func (o *blockTraceOrm) GetBlockTraces(fields map[string]interface{}, args ...string) ([]*types.BlockTrace, error) {
type Result struct {
Trace string
}
query := "SELECT trace FROM block_trace WHERE 1 = 1 "
query := "SELECT hash FROM block_trace WHERE 1 = 1 "
for key := range fields {
query += fmt.Sprintf("AND %s=:%s ", key, key)
}
@@ -65,18 +67,24 @@ func (o *blockTraceOrm) GetBlockTraces(fields map[string]interface{}, args ...st
return nil, err
}
var traces []*types.BlockTrace
var (
traces []*types.BlockTrace
rdb = o.cache
)
for rows.Next() {
result := &Result{}
if err = rows.StructScan(result); err != nil {
var (
trace *types.BlockTrace
hash string
)
if err = rows.Scan(&hash); err != nil {
break
}
trace := types.BlockTrace{}
err = json.Unmarshal([]byte(result.Trace), &trace)
trace, err = rdb.GetBlockTrace(context.Background(), common.HexToHash(hash))
if err != nil {
break
return nil, err
}
traces = append(traces, &trace)
traces = append(traces, trace)
}
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, err
@@ -153,6 +161,7 @@ func (o *blockTraceOrm) GetHashByNumber(number uint64) (*common.Hash, error) {
func (o *blockTraceOrm) InsertBlockTraces(blockTraces []*types.BlockTrace) error {
traceMaps := make([]map[string]interface{}, len(blockTraces))
rdb := o.cache
for i, trace := range blockTraces {
number, hash, txNum, mtime := trace.Header.Number.Int64(),
trace.Header.Hash().String(),
@@ -160,24 +169,22 @@ func (o *blockTraceOrm) InsertBlockTraces(blockTraces []*types.BlockTrace) error
trace.Header.Time
gasCost := utils.ComputeTraceGasCost(trace)
// clear the `StructLogs` to reduce storage cost
for _, executionResult := range trace.ExecutionResults {
executionResult.StructLogs = nil
}
data, err := json.Marshal(trace)
if err != nil {
log.Error("failed to marshal blockTrace", "hash", hash, "err", err)
return err
}
traceMaps[i] = map[string]interface{}{
"number": number,
"hash": hash,
"parent_hash": trace.Header.ParentHash.String(),
"trace": string(data),
"number": number,
"hash": hash,
"parent_hash": trace.Header.ParentHash.String(),
// Empty json
"trace": "{}",
"tx_num": txNum,
"gas_used": gasCost,
"block_timestamp": mtime,
}
if rdb != nil {
err := rdb.SetBlockTrace(context.Background(), trace)
if err != nil {
return err
}
}
}
_, err := o.db.NamedExec(`INSERT INTO public.block_trace (number, hash, parent_hash, trace, tx_num, gas_used, block_timestamp) VALUES (:number, :hash, :parent_hash, :trace, :tx_num, :gas_used, :block_timestamp);`, traceMaps)
if err != nil {