request.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package core
  17. import (
  18. "github.com/ethereum/go-ethereum/consensus/istanbul"
  19. istanbulcommon "github.com/ethereum/go-ethereum/consensus/istanbul/common"
  20. ibfttypes "github.com/ethereum/go-ethereum/consensus/istanbul/ibft/types"
  21. )
  22. func (c *core) handleRequest(request *istanbul.Request) error {
  23. logger := c.logger.New("state", c.state, "seq", c.current.sequence)
  24. if err := c.checkRequestMsg(request); err != nil {
  25. if err == istanbulcommon.ErrInvalidMessage {
  26. logger.Warn("invalid request")
  27. return err
  28. }
  29. logger.Warn("unexpected request", "err", err, "number", request.Proposal.Number(), "hash", request.Proposal.Hash())
  30. return err
  31. }
  32. logger.Trace("handleRequest", "number", request.Proposal.Number(), "hash", request.Proposal.Hash())
  33. c.current.pendingRequest = request
  34. if c.state == ibfttypes.StateAcceptRequest {
  35. c.sendPreprepare(request)
  36. }
  37. return nil
  38. }
  39. // check request state
  40. // return errInvalidMessage if the message is invalid
  41. // return errFutureMessage if the sequence of proposal is larger than current sequence
  42. // return errOldMessage if the sequence of proposal is smaller than current sequence
  43. func (c *core) checkRequestMsg(request *istanbul.Request) error {
  44. if request == nil || request.Proposal == nil {
  45. return istanbulcommon.ErrInvalidMessage
  46. }
  47. if c := c.current.sequence.Cmp(request.Proposal.Number()); c > 0 {
  48. return istanbulcommon.ErrOldMessage
  49. } else if c < 0 {
  50. return istanbulcommon.ErrFutureMessage
  51. } else {
  52. return nil
  53. }
  54. }
  55. func (c *core) storeRequestMsg(request *istanbul.Request) {
  56. logger := c.logger.New("state", c.state)
  57. logger.Trace("Store future request", "number", request.Proposal.Number(), "hash", request.Proposal.Hash())
  58. c.pendingRequestsMu.Lock()
  59. defer c.pendingRequestsMu.Unlock()
  60. c.pendingRequests.Push(request, float32(-request.Proposal.Number().Int64()))
  61. }
  62. func (c *core) processPendingRequests() {
  63. c.pendingRequestsMu.Lock()
  64. defer c.pendingRequestsMu.Unlock()
  65. for !(c.pendingRequests.Empty()) {
  66. m, prio := c.pendingRequests.Pop()
  67. r, ok := m.(*istanbul.Request)
  68. if !ok {
  69. c.logger.Warn("Malformed request, skip", "msg", m)
  70. continue
  71. }
  72. // Push back if it's a future message
  73. err := c.checkRequestMsg(r)
  74. if err != nil {
  75. if err == istanbulcommon.ErrFutureMessage {
  76. c.logger.Trace("Stop processing request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash())
  77. c.pendingRequests.Push(m, prio)
  78. break
  79. }
  80. c.logger.Trace("Skip the pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash(), "err", err)
  81. continue
  82. }
  83. c.logger.Trace("Post pending request", "number", r.Proposal.Number(), "hash", r.Proposal.Hash())
  84. go c.sendEvent(istanbul.RequestEvent{
  85. Proposal: r.Proposal,
  86. })
  87. }
  88. }