oracle: ensure proper ValidUntilBlock for backup tx

See neo-project/neo-modules#608.
This commit is contained in:
Roman Khimov 2021-07-19 17:28:35 +03:00
parent 5e26170b79
commit 0bad413e23
2 changed files with 7 additions and 2 deletions

View file

@ -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))) 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() currentHeight := o.Chain.BlockHeight()
vubInc := o.Chain.GetConfig().MaxValidUntilBlockIncrement
_, h, err := o.Chain.GetTransaction(req.Req.OriginalTxID) _, h, err := o.Chain.GetTransaction(req.Req.OriginalTxID)
if err != nil { if err != nil {
if !errors.Is(err, storage.ErrKeyNotFound) { 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. // The only reason tx can be not found is if it wasn't yet persisted from DAO.
h = currentHeight h = currentHeight
} }
h += vubInc // Main tx is only valid for RequestHeight + ValidUntilBlock.
tx, err := o.CreateResponseTx(int64(req.Req.GasForResponse), h, resp) tx, err := o.CreateResponseTx(int64(req.Req.GasForResponse), h, resp)
if err != nil { if err != nil {
return err 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{ backupTx, err := o.CreateResponseTx(int64(req.Req.GasForResponse), h, &transaction.OracleResponse{
ID: req.ID, ID: req.ID,
Code: transaction.ConsensusUnreachable, Code: transaction.ConsensusUnreachable,

View file

@ -81,10 +81,10 @@ func readResponse(rc gio.ReadCloser, limit int) ([]byte, error) {
} }
// CreateResponseTx creates unsigned oracle response transaction. // 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 := transaction.New(o.oracleResponse, 0)
tx.Nonce = uint32(resp.ID) tx.Nonce = uint32(resp.ID)
tx.ValidUntilBlock = height + o.Chain.GetConfig().MaxValidUntilBlockIncrement tx.ValidUntilBlock = vub
tx.Attributes = []transaction.Attribute{{ tx.Attributes = []transaction.Attribute{{
Type: transaction.OracleResponseT, Type: transaction.OracleResponseT,
Value: resp, Value: resp,