Skip to content

Commit

Permalink
internal/ethapi: added cache support for GetReceiptsByHash
Browse files Browse the repository at this point in the history
  • Loading branch information
saddoc committed Dec 19, 2023
1 parent 4a49d87 commit 6685f22
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 32 deletions.
28 changes: 19 additions & 9 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,19 +738,26 @@ func (s *PublicBlockChainAPI) GetReceiptsByHash(ctx context.Context, blockHash c
apiRequestsEnter()
defer apiRequestsLeave()

select {
case <-ctx.Done():
return nil, io.EOF
default:
}

if apiRequestsCache != nil {
if fields, err := apiCacheGetReceipts(apiRequestsCache, blockHash.Bytes()); err == nil {
log.Debug("API Cache", "found receipts", blockHash)
return fields, nil
}
}

block, err1 := s.b.BlockByHash(ctx, blockHash)
if block == nil && err1 == nil {
return nil, nil
} else if err1 != nil {
return nil, err1
}

select {
case <-ctx.Done():
return nil, io.EOF
default:
}

receipts, err2 := s.b.GetReceipts(ctx, blockHash)
if receipts == nil && err2 == nil {
return make([]map[string]interface{}, 0), nil
Expand Down Expand Up @@ -817,6 +824,9 @@ func (s *PublicBlockChainAPI) GetReceiptsByHash(ctx context.Context, blockHash c

fieldsList = append(fieldsList, fields)
}
if apiRequestsCache != nil {
apiCachePutReceipts(apiRequestsCache, blockHash.Bytes(), fieldsList)
}
return fieldsList, nil
}

Expand Down Expand Up @@ -1372,8 +1382,8 @@ func RPCMarshalBlock(ctx context.Context, block *types.Block, inclTx bool, fullT
}

if fullTx && apiRequestsCache != nil {
if fields, err := apiCacheGetMarshaledBlock(apiRequestsCache, block.Hash().Bytes()); err == nil {
log.Debug("API Cache", "found", block.Number())
if fields, err := apiCacheGetBlock(apiRequestsCache, block.Hash().Bytes()); err == nil {
log.Debug("API Cache", "found block", block.Number())
return fields, nil
}
}
Expand Down Expand Up @@ -1413,7 +1423,7 @@ func RPCMarshalBlock(ctx context.Context, block *types.Block, inclTx bool, fullT
fields["uncles"] = uncleHashes

if fullTx && apiRequestsCache != nil {
apiCachePutMarshaledBlock(apiRequestsCache, block.Hash().Bytes(), fields)
apiCachePutBlock(apiRequestsCache, block.Hash().Bytes(), fields)
}

return fields, nil
Expand Down
78 changes: 55 additions & 23 deletions internal/ethapi/api_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
)

var marshaledBlockPrefix = []byte(".block.")
var marshaledReceiptsPrefix = []byte(".receipts.")
var marshaledBlockPrefix = []byte(".blck.")
var marshaledReceiptsPrefix = []byte(".rcpt.")

func apiCacheOpen(fn string) (ethdb.Database, error) {
return rawdb.NewDB(fn, 0, 0, "", false)
Expand All @@ -37,8 +37,8 @@ func apiCacheClose(db ethdb.Database) {
db.Close()
}

func apiCacheGetMarshaledBlock(db ethdb.Database, hash []byte) (map[string]interface{}, error) {
key := append(marshaledBlockPrefix, hash...)
func apiCacheGet(db ethdb.Database, prefix, hash []byte) ([]byte, error) {
key := append(prefix, hash...)
data, err := db.Get(key)
if err != nil {
return nil, err
Expand All @@ -54,41 +54,73 @@ func apiCacheGetMarshaledBlock(db ethdb.Database, hash []byte) (map[string]inter
if err != nil {
return nil, err
}

var fields map[string]interface{}
if err = json.Unmarshal(decompressedData, &fields); err != nil {
return nil, err
}
return fields, nil
return decompressedData, nil
}

func apiCacheHasMarshaledBlock(db ethdb.Database, hash []byte) (bool, error) {
key := append(marshaledBlockPrefix, hash...)
func apiCacheHas(db ethdb.Database, prefix, hash []byte) (bool, error) {
key := append(prefix, hash...)
return db.Has(key)
}

func apiCachePutMarshaledBlock(db ethdb.Database, hash []byte, fields map[string]interface{}) error {
data, err := json.Marshal(fields)
if err != nil {
return err
}

func apiCachePut(db ethdb.Database, prefix, hash, data []byte) error {
var buf bytes.Buffer
gzWriter := gzip.NewWriter(&buf)
if _, err = gzWriter.Write(data); err != nil {
if _, err := gzWriter.Write(data); err != nil {
return err
}
if err = gzWriter.Close(); err != nil {
if err := gzWriter.Close(); err != nil {
return err
}

key := append(marshaledBlockPrefix, hash...)
key := append(prefix, hash...)
return db.Put(key, buf.Bytes())
}

func apiCacheDeleteMarshaledBlock(db ethdb.Database, hash []byte) error {
key := append(marshaledBlockPrefix, hash...)
func apiCacheDelete(db ethdb.Database, prefix, hash []byte) error {
key := append(prefix, hash...)
return db.Delete(key)
}

func apiCacheGetBlock(db ethdb.Database, hash []byte) (map[string]interface{}, error) {
data, err := apiCacheGet(db, marshaledBlockPrefix, hash)
if err != nil {
return nil, err
}

var fields map[string]interface{}
if err = json.Unmarshal(data, &fields); err != nil {
return nil, err
}
return fields, nil
}

func apiCachePutBlock(db ethdb.Database, hash []byte, fields map[string]interface{}) error {
data, err := json.Marshal(fields)
if err != nil {
return err
}
return apiCachePut(db, marshaledBlockPrefix, hash, data)
}

func apiCacheGetReceipts(db ethdb.Database, hash []byte) ([]map[string]interface{}, error) {
data, err := apiCacheGet(db, marshaledReceiptsPrefix, hash)
if err != nil {
return nil, err
}

var fields []map[string]interface{}
if err = json.Unmarshal(data, &fields); err != nil {
return nil, err
}
return fields, nil
}

func apiCachePutReceipts(db ethdb.Database, hash []byte, fields []map[string]interface{}) error {
data, err := json.Marshal(fields)
if err != nil {
return err
}
return apiCachePut(db, marshaledReceiptsPrefix, hash, data)
}

// EoF

0 comments on commit 6685f22

Please sign in to comment.