From 0bad413e236fc7e429db07d94e65e6bdda0d0f4a Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Mon, 19 Jul 2021 17:28:35 +0300 Subject: [PATCH] oracle: ensure proper ValidUntilBlock for backup tx See neo-project/neo-modules#608. --- pkg/services/oracle/request.go | 5 +++++ pkg/services/oracle/response.go | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/services/oracle/request.go b/pkg/services/oracle/request.go index 4c59cbbaa..088b205d8 100644 --- a/pkg/services/oracle/request.go +++ b/pkg/services/oracle/request.go @@ -172,6 +172,7 @@ func (o *Oracle) processRequest(priv *keys.PrivateKey, req request) error { o.Log.Debug("oracle request processed", zap.String("url", req.Req.URL), zap.Int("code", int(resp.Code)), zap.String("result", string(resp.Result))) currentHeight := o.Chain.BlockHeight() + vubInc := o.Chain.GetConfig().MaxValidUntilBlockIncrement _, h, err := o.Chain.GetTransaction(req.Req.OriginalTxID) if err != nil { if !errors.Is(err, storage.ErrKeyNotFound) { @@ -180,10 +181,14 @@ func (o *Oracle) processRequest(priv *keys.PrivateKey, req request) error { // The only reason tx can be not found is if it wasn't yet persisted from DAO. h = currentHeight } + h += vubInc // Main tx is only valid for RequestHeight + ValidUntilBlock. tx, err := o.CreateResponseTx(int64(req.Req.GasForResponse), h, resp) if err != nil { return err } + for h <= currentHeight { // Backup tx must be valid in any event. + h += vubInc + } backupTx, err := o.CreateResponseTx(int64(req.Req.GasForResponse), h, &transaction.OracleResponse{ ID: req.ID, Code: transaction.ConsensusUnreachable, diff --git a/pkg/services/oracle/response.go b/pkg/services/oracle/response.go index aef834c29..6b5f9d541 100644 --- a/pkg/services/oracle/response.go +++ b/pkg/services/oracle/response.go @@ -81,10 +81,10 @@ func readResponse(rc gio.ReadCloser, limit int) ([]byte, error) { } // CreateResponseTx creates unsigned oracle response transaction. -func (o *Oracle) CreateResponseTx(gasForResponse int64, height uint32, resp *transaction.OracleResponse) (*transaction.Transaction, error) { +func (o *Oracle) CreateResponseTx(gasForResponse int64, vub uint32, resp *transaction.OracleResponse) (*transaction.Transaction, error) { tx := transaction.New(o.oracleResponse, 0) tx.Nonce = uint32(resp.ID) - tx.ValidUntilBlock = height + o.Chain.GetConfig().MaxValidUntilBlockIncrement + tx.ValidUntilBlock = vub tx.Attributes = []transaction.Attribute{{ Type: transaction.OracleResponseT, Value: resp,