Implement request event validation from cache
This commit is contained in:
parent
027f060703
commit
221cf45dad
@ -4,6 +4,10 @@ import (
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"github.com/Secured-Finance/dione/node"
|
||||
|
||||
oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter"
|
||||
|
||||
"github.com/Secured-Finance/dione/consensus/types"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -32,11 +36,11 @@ type ConsensusData struct {
|
||||
alreadySubmitted bool
|
||||
}
|
||||
|
||||
func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey []byte, ethereumClient *ethclient.EthereumClient, miner *Miner) *PBFTConsensusManager {
|
||||
func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey []byte, ethereumClient *ethclient.EthereumClient, miner *Miner, evc *node.EventLogCache) *PBFTConsensusManager {
|
||||
pcm := &PBFTConsensusManager{}
|
||||
pcm.psb = psb
|
||||
pcm.miner = miner
|
||||
pcm.prePreparePool = NewPrePreparePool(miner)
|
||||
pcm.prePreparePool = NewPrePreparePool(miner, evc)
|
||||
pcm.preparePool = NewPreparePool()
|
||||
pcm.commitPool = NewCommitPool()
|
||||
pcm.minApprovals = minApprovals
|
||||
@ -49,11 +53,17 @@ func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey
|
||||
return pcm
|
||||
}
|
||||
|
||||
func (pcm *PBFTConsensusManager) Propose(consensusID string, task types2.DioneTask, requestID *big.Int, callbackAddress common.Address) error {
|
||||
func (pcm *PBFTConsensusManager) Propose(consensusID string, task types2.DioneTask, requestEvent *oracleEmitter.OracleEmitterNewOracleRequest) error {
|
||||
pcm.consensusInfo[consensusID] = &ConsensusData{}
|
||||
reqIDRaw := requestID.String()
|
||||
callbackAddressHex := callbackAddress.Hex()
|
||||
prePrepareMsg, err := pcm.prePreparePool.CreatePrePrepare(consensusID, task, reqIDRaw, callbackAddressHex, pcm.privKey)
|
||||
|
||||
prePrepareMsg, err := pcm.prePreparePool.CreatePrePrepare(
|
||||
consensusID,
|
||||
task,
|
||||
requestEvent.RequestID.String(),
|
||||
requestEvent.CallbackAddress.Hex(),
|
||||
string(requestEvent.CallbackMethodID[:]),
|
||||
pcm.privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -3,6 +3,10 @@ package consensus
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter"
|
||||
|
||||
"github.com/Secured-Finance/dione/node"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -17,22 +21,25 @@ import (
|
||||
type PrePreparePool struct {
|
||||
prePrepareMsgs map[string][]*types2.Message
|
||||
miner *Miner
|
||||
eventLogCache *node.EventLogCache
|
||||
}
|
||||
|
||||
func NewPrePreparePool(miner *Miner) *PrePreparePool {
|
||||
func NewPrePreparePool(miner *Miner, evc *node.EventLogCache) *PrePreparePool {
|
||||
return &PrePreparePool{
|
||||
prePrepareMsgs: map[string][]*types2.Message{},
|
||||
miner: miner,
|
||||
eventLogCache: evc,
|
||||
}
|
||||
}
|
||||
|
||||
func (pp *PrePreparePool) CreatePrePrepare(consensusID string, task types.DioneTask, requestID string, callbackAddress string, privateKey []byte) (*types2.Message, error) {
|
||||
func (pp *PrePreparePool) CreatePrePrepare(consensusID string, task types.DioneTask, requestID, callbackAddress, callbackMethodID string, privateKey []byte) (*types2.Message, error) {
|
||||
var message types2.Message
|
||||
message.Type = types2.MessageTypePrePrepare
|
||||
var consensusMsg types2.ConsensusMessage
|
||||
consensusMsg.ConsensusID = consensusID
|
||||
consensusMsg.RequestID = requestID
|
||||
consensusMsg.CallbackAddress = callbackAddress
|
||||
consensusMsg.CallbackMethodID = callbackMethodID
|
||||
consensusMsg.Task = task
|
||||
cHash, err := hashstructure.Hash(consensusMsg, hashstructure.FormatV2, nil)
|
||||
if err != nil {
|
||||
@ -70,6 +77,24 @@ func (ppp *PrePreparePool) IsValidPrePrepare(prePrepare *types2.Message) bool {
|
||||
}
|
||||
/////////////////////////////////
|
||||
|
||||
// === verify if request exists in event log cache ===
|
||||
requestEventPlain, err := ppp.eventLogCache.Get("request_" + consensusMsg.RequestID)
|
||||
if err != nil {
|
||||
logrus.Errorf("the incoming request task event doesn't exist in the EVC, or is broken: %v", err)
|
||||
return false
|
||||
}
|
||||
requestEvent := requestEventPlain.(*oracleEmitter.OracleEmitterNewOracleRequest)
|
||||
if requestEvent.CallbackAddress.String() != consensusMsg.CallbackAddress ||
|
||||
string(requestEvent.CallbackMethodID[:]) != consensusMsg.CallbackMethodID ||
|
||||
requestEvent.OriginChain != consensusMsg.Task.OriginChain ||
|
||||
requestEvent.RequestType != consensusMsg.Task.RequestType ||
|
||||
requestEvent.RequestParams != consensusMsg.Task.RequestParams {
|
||||
|
||||
logrus.Errorf("the incoming task and cached request event don't match!")
|
||||
return false
|
||||
}
|
||||
/////////////////////////////////
|
||||
|
||||
// === verify election proof wincount preliminarily ===
|
||||
if consensusMsg.Task.ElectionProof.WinCount < 1 {
|
||||
logrus.Error("miner isn't a winner!")
|
||||
|
@ -16,12 +16,13 @@ const (
|
||||
)
|
||||
|
||||
type ConsensusMessage struct {
|
||||
_ struct{} `cbor:",toarray" hash:"-"`
|
||||
ConsensusID string
|
||||
Signature []byte `hash:"-"`
|
||||
RequestID string
|
||||
CallbackAddress string
|
||||
Task types.DioneTask
|
||||
_ struct{} `cbor:",toarray" hash:"-"`
|
||||
ConsensusID string
|
||||
Signature []byte `hash:"-"`
|
||||
RequestID string
|
||||
CallbackAddress string
|
||||
CallbackMethodID string
|
||||
Task types.DioneTask
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
|
21
node/node.go
21
node/node.go
@ -105,7 +105,10 @@ func NewNode(config *config.Config, prvKey crypto.PrivKey, pexDiscoveryUpdateTim
|
||||
miner := provideMiner(n.Host.ID(), *n.Ethereum.GetEthAddress(), n.Beacon, n.Ethereum, rawPrivKey)
|
||||
n.Miner = miner
|
||||
|
||||
cManager := provideConsensusManager(psb, miner, ethClient, rawPrivKey, n.Config.ConsensusMinApprovals)
|
||||
eventLogCache := provideEventLogCache()
|
||||
n.EventLogCache = eventLogCache
|
||||
|
||||
cManager := provideConsensusManager(psb, miner, ethClient, rawPrivKey, n.Config.ConsensusMinApprovals, eventLogCache)
|
||||
n.ConsensusManager = cManager
|
||||
|
||||
wallet, err := provideWallet(n.Host.ID(), rawPrivKey)
|
||||
@ -114,9 +117,6 @@ func NewNode(config *config.Config, prvKey crypto.PrivKey, pexDiscoveryUpdateTim
|
||||
}
|
||||
n.Wallet = wallet
|
||||
|
||||
eventLogCache := provideEventLogCache()
|
||||
n.EventLogCache = eventLogCache
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@ -194,15 +194,18 @@ func (n *Node) subscribeOnEthContractsAsync(ctx context.Context) {
|
||||
logrus.Errorf("Failed to store new request event to event log cache: %v", err)
|
||||
}
|
||||
|
||||
task, err := n.Miner.MineTask(ctx, event)
|
||||
logrus.Info("Let's wait a little so that all nodes have time to receive the request and cache it")
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
task, err := n.Miner.MineTask(context.TODO(), event)
|
||||
if err != nil {
|
||||
logrus.Fatal("Failed to mine task, exiting... ", err)
|
||||
}
|
||||
if task == nil {
|
||||
continue
|
||||
}
|
||||
logrus.Infof("Started new consensus round with ID: %s", event.RequestID.String())
|
||||
err = n.ConsensusManager.Propose(event.RequestID.String(), *task, event.RequestID, event.CallbackAddress)
|
||||
logrus.Infof("Proposed new Dione task with ID: %s", event.RequestID.String())
|
||||
err = n.ConsensusManager.Propose(event.RequestID.String(), *task, event)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to propose task: %w", err)
|
||||
}
|
||||
@ -284,8 +287,8 @@ func providePubsubRouter(lhost host.Host, config *config.Config) *pubsub2.PubSub
|
||||
return pubsub2.NewPubSubRouter(lhost, config.PubSub.ServiceTopicName)
|
||||
}
|
||||
|
||||
func provideConsensusManager(psb *pubsub2.PubSubRouter, miner *consensus.Miner, ethClient *ethclient.EthereumClient, privateKey []byte, minApprovals int) *consensus.PBFTConsensusManager {
|
||||
return consensus.NewPBFTConsensusManager(psb, minApprovals, privateKey, ethClient, miner)
|
||||
func provideConsensusManager(psb *pubsub2.PubSubRouter, miner *consensus.Miner, ethClient *ethclient.EthereumClient, privateKey []byte, minApprovals int, evc *EventLogCache) *consensus.PBFTConsensusManager {
|
||||
return consensus.NewPBFTConsensusManager(psb, minApprovals, privateKey, ethClient, miner, evc)
|
||||
}
|
||||
|
||||
func provideLibp2pNode(config *config.Config, privateKey crypto.PrivKey, pexDiscoveryUpdateTime time.Duration) (host.Host, *pex.PEXDiscovery, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user