diff --git a/cmd/api/handlers/code.go b/cmd/api/handlers/code.go index 6d645cf3a..cacd3111f 100644 --- a/cmd/api/handlers/code.go +++ b/cmd/api/handlers/code.go @@ -71,7 +71,7 @@ func getContractCodeJSON(c context.Context, ctx *config.Context, address string, if err != nil { return res, err } - script, err := ctx.Contracts.Script(c, address, symLink) + script, err := ctx.Cache.Script(c, address, symLink) if err != nil { return res, err } diff --git a/cmd/api/handlers/fork.go b/cmd/api/handlers/fork.go index 288198e26..bf83b7b24 100644 --- a/cmd/api/handlers/fork.go +++ b/cmd/api/handlers/fork.go @@ -45,7 +45,7 @@ func buildStorageDataFromForkRequest(c context.Context, ctxs config.Contexts, re if err != nil { return nil, err } - scriptData, err = getScriptBytes(c, ctx.Contracts, req.Address, symLink) + scriptData, err = getScriptBytes(c, ctx.Cache, req.Address, symLink) if err != nil { return nil, err } diff --git a/cmd/api/handlers/prepare.go b/cmd/api/handlers/prepare.go index 0950335cc..d9e6cffe7 100644 --- a/cmd/api/handlers/prepare.go +++ b/cmd/api/handlers/prepare.go @@ -326,7 +326,7 @@ func getErrorLocation(c context.Context, ctx *config.Context, operation operatio if err != nil { return GetErrorLocationResponse{}, err } - code, err := getScriptBytes(c, ctx.Contracts, operation.Destination.Address, proto.SymLink) + code, err := getScriptBytes(c, ctx.Cache, operation.Destination.Address, proto.SymLink) if err != nil { return GetErrorLocationResponse{}, err } diff --git a/cmd/api/handlers/run_code.go b/cmd/api/handlers/run_code.go index 62bdcea47..3d550e959 100644 --- a/cmd/api/handlers/run_code.go +++ b/cmd/api/handlers/run_code.go @@ -148,7 +148,7 @@ func RunCode() gin.HandlerFunc { return } - scriptBytes, err := getScriptBytes(c.Request.Context(), ctx.Contracts, req.Address, state.Protocol.SymLink) + scriptBytes, err := getScriptBytes(c.Request.Context(), ctx.Cache, req.Address, state.Protocol.SymLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -246,7 +246,7 @@ func parseAppliedRunCode(c context.Context, ctx *config.Context, response noderp s = script } else { var err error - s, err = getScript(c, ctx.Contracts, op.Destination, proto.SymLink) + s, err = getScript(c, ctx.Cache, op.Destination, proto.SymLink) if err != nil { return nil, err } diff --git a/cmd/api/handlers/script.go b/cmd/api/handlers/script.go index c617bebae..661d6a882 100644 --- a/cmd/api/handlers/script.go +++ b/cmd/api/handlers/script.go @@ -5,20 +5,21 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/bcd/consts" + "github.com/baking-bad/bcdhub/internal/cache" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" ) -func getScript(ctx context.Context, contracts contract.Repository, address, symLink string) (*ast.Script, error) { - data, err := getScriptBytes(ctx, contracts, address, symLink) +func getScript(ctx context.Context, cache *cache.Cache, address, symLink string) (*ast.Script, error) { + data, err := getScriptBytes(ctx, cache, address, symLink) if err != nil { return nil, err } return ast.NewScriptWithoutCode(data) } -func getScriptBytes(ctx context.Context, contracts contract.Repository, address, symLink string) ([]byte, error) { - script, err := contracts.Script(ctx, address, symLink) +func getScriptBytes(ctx context.Context, cache *cache.Cache, address, symLink string) ([]byte, error) { + script, err := cache.Script(ctx, address, symLink) if err != nil { return nil, err } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 75693ff56..f39176a45 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -56,6 +56,7 @@ func (cache *Cache) ContractTags(ctx context.Context, address string) (types.Tag return c.Tags, nil }) if err != nil { + cache.Delete(key) return 0, err } return item.Value().(types.Tags), nil @@ -68,6 +69,7 @@ func (cache *Cache) TezosBalance(ctx context.Context, address string, level int6 return cache.rpc.GetContractBalance(ctx, address, level) }) if err != nil { + cache.Delete(key) return 0, err } return item.Value().(int64), nil @@ -84,6 +86,7 @@ func (cache *Cache) StorageTypeBytes(ctx context.Context, address, symLink strin return cache.contracts.ScriptPart(ctx, address, symLink, consts.STORAGE) }) if err != nil { + cache.Delete(key) return nil, err } return item.Value().([]byte), nil @@ -96,7 +99,20 @@ func (cache *Cache) ProtocolByID(ctx context.Context, id int64) (protocol.Protoc return cache.protocols.GetByID(ctx, id) }) if err != nil { + cache.Delete(key) return protocol.Protocol{}, err } return item.Value().(protocol.Protocol), nil } + +func (cache *Cache) Script(ctx context.Context, address, symLink string) (contract.Script, error) { + key := fmt.Sprintf("script:%s:%s", address, symLink) + item, err := cache.Fetch(key, time.Hour, func() (interface{}, error) { + return cache.contracts.Script(ctx, address, symLink) + }) + if err != nil { + cache.Delete(key) + return contract.Script{}, err + } + return item.Value().(contract.Script), nil +} diff --git a/internal/parsers/operations/transaction.go b/internal/parsers/operations/transaction.go index 8a2dfc617..435297bc6 100644 --- a/internal/parsers/operations/transaction.go +++ b/internal/parsers/operations/transaction.go @@ -112,7 +112,7 @@ func (p Transaction) parseContractParams(ctx context.Context, data noderpc.Opera } } - scriptEntity, err := p.ctx.Contracts.Script(ctx, tx.Destination.Address, p.protocol.SymLink) + scriptEntity, err := p.ctx.Cache.Script(ctx, tx.Destination.Address, p.protocol.SymLink) if err != nil { if !tx.Internal { return nil