From e75035faa1c0fcfa12c24251bd73800a33940bfd Mon Sep 17 00:00:00 2001 From: Petr Hanzl <84449820+petr-hanzl@users.noreply.github.com> Date: Fri, 9 Feb 2024 06:16:01 +0100 Subject: [PATCH] Fix rpc pending blocks (#981) Remove pending block from validation. Check for nilpointer --- .../statedb/temporary_archive_prepper.go | 4 +- .../statedb/temporary_archive_prepper_test.go | 43 +++++++++++++++++++ .../extension/validator/rpc_comparator.go | 5 +++ rpc/request.go | 13 +++--- 4 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 executor/extension/statedb/temporary_archive_prepper_test.go diff --git a/executor/extension/statedb/temporary_archive_prepper.go b/executor/extension/statedb/temporary_archive_prepper.go index 59e0223ab..b66a9f89c 100644 --- a/executor/extension/statedb/temporary_archive_prepper.go +++ b/executor/extension/statedb/temporary_archive_prepper.go @@ -19,7 +19,7 @@ type temporaryArchivePrepper struct { // PreTransaction creates temporary archive that is released after transaction is executed. func (r *temporaryArchivePrepper) PreTransaction(state executor.State[*rpc.RequestAndResults], ctx *executor.Context) error { - block := findBlockNumber(state.Data) // save the block for progress tracker + block := findBlockNumber(state.Data) var err error ctx.Archive, err = ctx.State.GetArchiveState(block) @@ -54,6 +54,8 @@ func findBlockNumber(data *rpc.RequestAndResults) uint64 { switch str { case "pending": + // validation for pending requests does not work, skip them + data.SkipValidation = true // pending should be treated as latest fallthrough case "latest": diff --git a/executor/extension/statedb/temporary_archive_prepper_test.go b/executor/extension/statedb/temporary_archive_prepper_test.go new file mode 100644 index 000000000..e21932d62 --- /dev/null +++ b/executor/extension/statedb/temporary_archive_prepper_test.go @@ -0,0 +1,43 @@ +package statedb + +import ( + "encoding/json" + "testing" + + "github.com/Fantom-foundation/Aida/executor" + "github.com/Fantom-foundation/Aida/rpc" + "github.com/Fantom-foundation/Aida/state" + "go.uber.org/mock/gomock" +) + +func TestTemporaryArchivePrepper_PreTransactionMarksPendingBlockAsSkipValidation(t *testing.T) { + ctrl := gomock.NewController(t) + db := state.NewMockStateDB(ctrl) + ext := MakeTemporaryArchivePrepper() + + db.EXPECT().GetArchiveState(uint64(10)).Return(nil, nil) + + st := executor.State[*rpc.RequestAndResults]{Block: 10, Transaction: 0, Data: data} + ctx := &executor.Context{State: db} + err := ext.PreTransaction(st, ctx) + if err != nil { + t.Fatal(err) + } + + if !data.SkipValidation { + t.Fatal("SkipValidation must be true") + } +} + +var data = &rpc.RequestAndResults{ + Query: &rpc.Body{ + Params: []interface{}{"test", "pending"}, + }, + Response: &rpc.Response{ + Version: "2.0", + ID: json.RawMessage{1}, + BlockID: 10, + Timestamp: 10, + }, + SkipValidation: false, +} diff --git a/executor/extension/validator/rpc_comparator.go b/executor/extension/validator/rpc_comparator.go index 3762a44b1..2ea0ab5ca 100644 --- a/executor/extension/validator/rpc_comparator.go +++ b/executor/extension/validator/rpc_comparator.go @@ -95,6 +95,11 @@ type rpcComparator struct { func (c *rpcComparator) PostTransaction(state executor.State[*rpc.RequestAndResults], ctx *executor.Context) error { c.totalNumberOfRequests++ + // pending block numbers are not validatable + if state.Data.SkipValidation || state.Data.StateDB == nil { + return nil + } + compareErr := compare(state) if compareErr != nil { // lot errors are recorded wrongly, for this case we resend the request and compare it again diff --git a/rpc/request.go b/rpc/request.go index 993e9ef97..f8eed6827 100644 --- a/rpc/request.go +++ b/rpc/request.go @@ -4,12 +4,13 @@ import "encoding/json" // RequestAndResults encapsulates request query and response for post-processing. type RequestAndResults struct { - Query *Body - Response *Response - Error *ErrorResponse - ParamsRaw []byte - ResponseRaw []byte - StateDB *StateDBData + Query *Body + Response *Response + Error *ErrorResponse + ParamsRaw []byte + ResponseRaw []byte + StateDB *StateDBData + SkipValidation bool } // Body represents a decoded payload of a balancer.