Implement basic version of dispute manager, slightly refactor consensus package
This commit is contained in:
parent
56c23a9087
commit
35e7994da7
@ -32,7 +32,7 @@ func (cp *CommitPool) IsExistingCommit(commitMsg *types2.Message) bool {
|
||||
|
||||
consensusMessage := commitMsg.Payload
|
||||
var exists bool
|
||||
for _, v := range cp.commitMsgs[consensusMessage.ConsensusID] {
|
||||
for _, v := range cp.commitMsgs[consensusMessage.Task.ConsensusID] {
|
||||
if v.From == commitMsg.From {
|
||||
exists = true
|
||||
}
|
||||
@ -54,7 +54,7 @@ func (cp *CommitPool) AddCommit(commit *types2.Message) {
|
||||
cp.mut.Lock()
|
||||
defer cp.mut.Unlock()
|
||||
|
||||
consensusID := commit.Payload.ConsensusID
|
||||
consensusID := commit.Payload.Task.ConsensusID
|
||||
if _, ok := cp.commitMsgs[consensusID]; !ok {
|
||||
cp.commitMsgs[consensusID] = []*types2.Message{}
|
||||
}
|
||||
|
@ -26,15 +26,17 @@ type PBFTConsensusManager struct {
|
||||
prePreparePool *PrePreparePool
|
||||
preparePool *PreparePool
|
||||
commitPool *CommitPool
|
||||
consensusInfo map[string]*ConsensusData
|
||||
consensusMap map[string]*Consensus
|
||||
ethereumClient *ethclient.EthereumClient
|
||||
miner *Miner
|
||||
eventCache cache.EventCache
|
||||
}
|
||||
|
||||
type ConsensusData struct {
|
||||
mutex sync.Mutex
|
||||
alreadySubmitted bool
|
||||
type Consensus struct {
|
||||
mutex sync.Mutex
|
||||
Finished bool
|
||||
IsCurrentMinerLeader bool
|
||||
Task *types2.DioneTask
|
||||
}
|
||||
|
||||
func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey []byte, ethereumClient *ethclient.EthereumClient, miner *Miner, evc cache.EventCache) *PBFTConsensusManager {
|
||||
@ -48,7 +50,7 @@ func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey
|
||||
pcm.privKey = privKey
|
||||
pcm.ethereumClient = ethereumClient
|
||||
pcm.eventCache = evc
|
||||
pcm.consensusInfo = map[string]*ConsensusData{}
|
||||
pcm.consensusMap = map[string]*Consensus{}
|
||||
pcm.psb.Hook(types.MessageTypePrePrepare, pcm.handlePrePrepare)
|
||||
pcm.psb.Hook(types.MessageTypePrepare, pcm.handlePrepare)
|
||||
pcm.psb.Hook(types.MessageTypeCommit, pcm.handleCommit)
|
||||
@ -56,11 +58,10 @@ func NewPBFTConsensusManager(psb *pubsub.PubSubRouter, minApprovals int, privKey
|
||||
}
|
||||
|
||||
func (pcm *PBFTConsensusManager) Propose(consensusID string, task types2.DioneTask, requestEvent *dioneOracle.DioneOracleNewOracleRequest) error {
|
||||
pcm.consensusInfo[consensusID] = &ConsensusData{}
|
||||
pcm.createConsensusInfo(&task, true)
|
||||
|
||||
prePrepareMsg, err := pcm.prePreparePool.CreatePrePrepare(
|
||||
consensusID,
|
||||
task,
|
||||
&task,
|
||||
requestEvent.ReqID.String(),
|
||||
requestEvent.CallbackAddress.Bytes(),
|
||||
requestEvent.CallbackMethodID[:],
|
||||
@ -74,6 +75,9 @@ func (pcm *PBFTConsensusManager) Propose(consensusID string, task types2.DioneTa
|
||||
}
|
||||
|
||||
func (pcm *PBFTConsensusManager) handlePrePrepare(message *types.Message) {
|
||||
if message.Payload.Task.Miner == pcm.miner.address {
|
||||
return
|
||||
}
|
||||
if pcm.prePreparePool.IsExistingPrePrepare(message) {
|
||||
logrus.Debug("received existing pre_prepare msg, dropping...")
|
||||
return
|
||||
@ -94,6 +98,9 @@ func (pcm *PBFTConsensusManager) handlePrePrepare(message *types.Message) {
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to create prepare message: %w", err)
|
||||
}
|
||||
|
||||
pcm.createConsensusInfo(&message.Payload.Task, false)
|
||||
|
||||
pcm.psb.BroadcastToServiceTopic(prepareMsg)
|
||||
}
|
||||
|
||||
@ -114,7 +121,7 @@ func (pcm *PBFTConsensusManager) handlePrepare(message *types.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
if pcm.preparePool.PreparePoolSize(message.Payload.ConsensusID) >= pcm.minApprovals {
|
||||
if pcm.preparePool.PreparePoolSize(message.Payload.Task.ConsensusID) >= pcm.minApprovals {
|
||||
commitMsg, err := pcm.commitPool.CreateCommit(message, pcm.privKey)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to create commit message: %w", err)
|
||||
@ -141,21 +148,22 @@ func (pcm *PBFTConsensusManager) handleCommit(message *types.Message) {
|
||||
}
|
||||
|
||||
consensusMsg := message.Payload
|
||||
if pcm.commitPool.CommitSize(consensusMsg.ConsensusID) >= pcm.minApprovals {
|
||||
if info, ok := pcm.consensusInfo[consensusMsg.ConsensusID]; ok {
|
||||
info.mutex.Lock()
|
||||
defer info.mutex.Unlock()
|
||||
if info.alreadySubmitted {
|
||||
return
|
||||
}
|
||||
logrus.Infof("Submitting on-chain result for consensus ID: %s", consensusMsg.ConsensusID)
|
||||
reqID, ok := new(big.Int).SetString(consensusMsg.RequestID, 10)
|
||||
if pcm.commitPool.CommitSize(consensusMsg.Task.ConsensusID) >= pcm.minApprovals {
|
||||
info := pcm.consensusMap[consensusMsg.Task.ConsensusID]
|
||||
info.mutex.Lock()
|
||||
defer info.mutex.Unlock()
|
||||
if info.Finished {
|
||||
return
|
||||
}
|
||||
if info.IsCurrentMinerLeader {
|
||||
logrus.Infof("Submitting on-chain result for consensus ID: %s", consensusMsg.Task.ConsensusID)
|
||||
reqID, ok := new(big.Int).SetString(consensusMsg.Task.RequestID, 10)
|
||||
if !ok {
|
||||
logrus.Errorf("Failed to parse request ID: %v", consensusMsg.RequestID)
|
||||
logrus.Errorf("Failed to parse request ID: %v", consensusMsg.Task.RequestID)
|
||||
}
|
||||
callbackAddress := common.BytesToAddress(consensusMsg.CallbackAddress)
|
||||
callbackAddress := common.BytesToAddress(consensusMsg.Task.CallbackAddress)
|
||||
|
||||
request, err := pcm.eventCache.GetOracleRequestEvent("request_" + consensusMsg.RequestID)
|
||||
request, err := pcm.eventCache.GetOracleRequestEvent("request_" + consensusMsg.Task.RequestID)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to get request from cache: %v", err.Error())
|
||||
return
|
||||
@ -165,7 +173,25 @@ func (pcm *PBFTConsensusManager) handleCommit(message *types.Message) {
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to submit on-chain result: %v", err)
|
||||
}
|
||||
info.alreadySubmitted = true
|
||||
}
|
||||
|
||||
info.Finished = true
|
||||
}
|
||||
}
|
||||
|
||||
func (pcm *PBFTConsensusManager) createConsensusInfo(task *types2.DioneTask, isLeader bool) {
|
||||
pcm.consensusMap[task.ConsensusID] = &Consensus{
|
||||
IsCurrentMinerLeader: isLeader,
|
||||
Task: task,
|
||||
Finished: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (pcm *PBFTConsensusManager) GetConsensusInfo(consensusID string) *Consensus {
|
||||
c, ok := pcm.consensusMap[consensusID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
72
consensus/consensus_test.go
Normal file
72
consensus/consensus_test.go
Normal file
@ -0,0 +1,72 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Secured-Finance/dione/config"
|
||||
"github.com/Secured-Finance/dione/node"
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestConsensus(t *testing.T) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
// setting up nodes
|
||||
port := rand.Intn(100) + 10000
|
||||
|
||||
cfg := &config.Config{
|
||||
ListenPort: port,
|
||||
ListenAddr: "0.0.0.0",
|
||||
Rendezvous: "dione",
|
||||
PubSub: config.PubSubConfig{
|
||||
ProtocolID: "/dione/1.0",
|
||||
},
|
||||
ConsensusMinApprovals: 3,
|
||||
}
|
||||
|
||||
var nodes []*node.Node
|
||||
|
||||
bNode := newNode(cfg)
|
||||
t.Logf("Bootstrap ID: %s", bNode.Host.ID())
|
||||
cfg.BootstrapNodes = []string{bNode.Host.Addrs()[0].String() + fmt.Sprintf("/p2p/%s", bNode.Host.ID().String())}
|
||||
nodes = append(nodes, bNode)
|
||||
|
||||
maxNodes := 10
|
||||
|
||||
for i := 1; i <= maxNodes; i++ {
|
||||
cfg.ListenPort++
|
||||
node := newNode(cfg)
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
func newNode(cfg *config.Config) *node.Node {
|
||||
privKey, err := generatePrivateKey()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
node, err := node.NewNode(cfg, privKey, 1*time.Second)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func generatePrivateKey() (crypto.PrivKey, error) {
|
||||
r := crand.Reader
|
||||
// Creates a new RSA key pair for this host.
|
||||
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, 2048, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return prvKey, nil
|
||||
}
|
154
consensus/dispute_manager.go
Normal file
154
consensus/dispute_manager.go
Normal file
@ -0,0 +1,154 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/Secured-Finance/dione/contracts/dioneDispute"
|
||||
"github.com/Secured-Finance/dione/contracts/dioneOracle"
|
||||
"github.com/Secured-Finance/dione/ethclient"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
type DisputeManager struct {
|
||||
ctx context.Context
|
||||
ethClient *ethclient.EthereumClient
|
||||
pcm *PBFTConsensusManager
|
||||
submittionMap map[string]*dioneOracle.DioneOracleSubmittedOracleRequest
|
||||
disputeMap map[string]*dioneDispute.DioneDisputeNewDispute
|
||||
}
|
||||
|
||||
func NewDisputeManager(ctx context.Context, ethClient *ethclient.EthereumClient, pcm *PBFTConsensusManager) (*DisputeManager, error) {
|
||||
newSubmittionsChan, submSubscription, err := ethClient.SubscribeOnNewSubmittions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newDisputesChan, dispSubscription, err := ethClient.SubscribeOnNewDisputes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dm := &DisputeManager{
|
||||
ethClient: ethClient,
|
||||
pcm: pcm,
|
||||
ctx: ctx,
|
||||
submittionMap: map[string]*dioneOracle.DioneOracleSubmittedOracleRequest{},
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
{
|
||||
submSubscription.Unsubscribe()
|
||||
dispSubscription.Unsubscribe()
|
||||
return
|
||||
}
|
||||
case s := <-newSubmittionsChan:
|
||||
{
|
||||
dm.onNewSubmittion(s)
|
||||
}
|
||||
case d := <-newDisputesChan:
|
||||
{
|
||||
dm.onNewDispute(d)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return dm, nil
|
||||
}
|
||||
|
||||
func (dm *DisputeManager) onNewSubmittion(submittion *dioneOracle.DioneOracleSubmittedOracleRequest) {
|
||||
c := dm.pcm.GetConsensusInfo(submittion.ReqID.String())
|
||||
if c == nil {
|
||||
// todo: warn
|
||||
return
|
||||
}
|
||||
|
||||
dm.submittionMap[submittion.ReqID.String()] = submittion
|
||||
|
||||
submHashBytes := sha3.Sum256(submittion.Data)
|
||||
localHashBytes := sha3.Sum256(c.Task.Payload)
|
||||
submHash := hex.EncodeToString(submHashBytes[:])
|
||||
localHash := hex.EncodeToString(localHashBytes[:])
|
||||
if submHash != localHash {
|
||||
addr := common.HexToAddress(c.Task.MinerEth)
|
||||
reqID, ok := big.NewInt(0).SetString(c.Task.RequestID, 10)
|
||||
if !ok {
|
||||
logrus.Errorf("cannot parse request id: %s", c.Task.RequestID)
|
||||
return
|
||||
}
|
||||
err := dm.ethClient.BeginDispute(addr, reqID)
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
disputeFinishTimer := time.NewTimer(time.Minute * 5)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-dm.ctx.Done():
|
||||
return
|
||||
case <-disputeFinishTimer.C:
|
||||
{
|
||||
d, ok := dm.disputeMap[reqID.String()]
|
||||
if !ok {
|
||||
logrus.Error("cannot finish dispute: it doesn't exist in manager's dispute map!")
|
||||
return
|
||||
}
|
||||
err := dm.ethClient.FinishDispute(d.Dhash)
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DisputeManager) onNewDispute(dispute *dioneDispute.DioneDisputeNewDispute) {
|
||||
c := dm.pcm.GetConsensusInfo(dispute.RequestID.String())
|
||||
if c == nil {
|
||||
// todo: warn
|
||||
return
|
||||
}
|
||||
|
||||
subm, ok := dm.submittionMap[dispute.RequestID.String()]
|
||||
if !ok {
|
||||
// todo: warn
|
||||
return
|
||||
}
|
||||
|
||||
dm.disputeMap[dispute.RequestID.String()] = dispute
|
||||
|
||||
if dispute.DisputeInitiator.Hex() == dm.ethClient.GetEthAddress().Hex() {
|
||||
return
|
||||
}
|
||||
|
||||
submHashBytes := sha3.Sum256(subm.Data)
|
||||
localHashBytes := sha3.Sum256(c.Task.Payload)
|
||||
submHash := hex.EncodeToString(submHashBytes[:])
|
||||
localHash := hex.EncodeToString(localHashBytes[:])
|
||||
if submHash == localHash {
|
||||
err := dm.ethClient.VoteDispute(dispute.Dhash, false)
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err := dm.ethClient.VoteDispute(dispute.Dhash, true)
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
@ -34,16 +34,16 @@ func NewPrePreparePool(miner *Miner, evc cache.EventCache) *PrePreparePool {
|
||||
}
|
||||
}
|
||||
|
||||
func (pp *PrePreparePool) CreatePrePrepare(consensusID string, task types.DioneTask, requestID string, callbackAddress, callbackMethodID, privateKey []byte) (*types2.Message, error) {
|
||||
func (pp *PrePreparePool) CreatePrePrepare(task *types.DioneTask, requestID string, callbackAddress, callbackMethodID, 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)
|
||||
consensusMsg.Task.ConsensusID = requestID
|
||||
consensusMsg.Task.RequestID = requestID
|
||||
consensusMsg.Task.CallbackAddress = callbackAddress
|
||||
consensusMsg.Task.CallbackMethodID = callbackMethodID
|
||||
consensusMsg.Task = *task
|
||||
cHash, err := hashstructure.Hash(task, hashstructure.FormatV2, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (pp *PrePreparePool) CreatePrePrepare(consensusID string, task types.DioneT
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
consensusMsg.Signature = signature.Data
|
||||
consensusMsg.Task.Signature = signature.Data
|
||||
message.Payload = consensusMsg
|
||||
return &message, nil
|
||||
}
|
||||
@ -62,7 +62,7 @@ func (ppp *PrePreparePool) IsExistingPrePrepare(prepareMsg *types2.Message) bool
|
||||
|
||||
consensusMessage := prepareMsg.Payload
|
||||
var exists bool
|
||||
for _, v := range ppp.prePrepareMsgs[consensusMessage.ConsensusID] {
|
||||
for _, v := range ppp.prePrepareMsgs[consensusMessage.Task.ConsensusID] {
|
||||
if v.From == prepareMsg.From {
|
||||
exists = true
|
||||
}
|
||||
@ -83,13 +83,13 @@ func (ppp *PrePreparePool) IsValidPrePrepare(prePrepare *types2.Message) bool {
|
||||
/////////////////////////////////
|
||||
|
||||
// === verify if request exists in event log cache ===
|
||||
requestEvent, err := ppp.eventLogCache.GetOracleRequestEvent("request_" + consensusMsg.RequestID)
|
||||
requestEvent, err := ppp.eventLogCache.GetOracleRequestEvent("request_" + consensusMsg.Task.RequestID)
|
||||
if err != nil {
|
||||
logrus.Errorf("the incoming request task event doesn't exist in the EVC, or is broken: %v", err)
|
||||
return false
|
||||
}
|
||||
if bytes.Compare(requestEvent.CallbackAddress.Bytes(), consensusMsg.CallbackAddress) != 0 ||
|
||||
bytes.Compare(requestEvent.CallbackMethodID[:], consensusMsg.CallbackMethodID) != 0 ||
|
||||
if bytes.Compare(requestEvent.CallbackAddress.Bytes(), consensusMsg.Task.CallbackAddress) != 0 ||
|
||||
bytes.Compare(requestEvent.CallbackMethodID[:], consensusMsg.Task.CallbackMethodID) != 0 ||
|
||||
requestEvent.OriginChain != consensusMsg.Task.OriginChain ||
|
||||
requestEvent.RequestType != consensusMsg.Task.RequestType ||
|
||||
requestEvent.RequestParams != consensusMsg.Task.RequestParams {
|
||||
@ -185,7 +185,7 @@ func (ppp *PrePreparePool) AddPrePrepare(prePrepare *types2.Message) {
|
||||
ppp.mut.Lock()
|
||||
defer ppp.mut.Unlock()
|
||||
|
||||
consensusID := prePrepare.Payload.ConsensusID
|
||||
consensusID := prePrepare.Payload.Task.ConsensusID
|
||||
if _, ok := ppp.prePrepareMsgs[consensusID]; !ok {
|
||||
ppp.prePrepareMsgs[consensusID] = []*types2.Message{}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func (pp *PreparePool) IsExistingPrepare(prepareMsg *types2.Message) bool {
|
||||
|
||||
consensusMessage := prepareMsg.Payload
|
||||
var exists bool
|
||||
for _, v := range pp.prepareMsgs[consensusMessage.ConsensusID] {
|
||||
for _, v := range pp.prepareMsgs[consensusMessage.Task.ConsensusID] {
|
||||
if v.From == prepareMsg.From {
|
||||
exists = true
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (pp *PreparePool) AddPrepare(prepare *types2.Message) {
|
||||
pp.mut.Lock()
|
||||
defer pp.mut.Unlock()
|
||||
|
||||
consensusID := prepare.Payload.ConsensusID
|
||||
consensusID := prepare.Payload.Task.ConsensusID
|
||||
if _, ok := pp.prepareMsgs[consensusID]; !ok {
|
||||
pp.prepareMsgs[consensusID] = []*types2.Message{}
|
||||
}
|
||||
|
@ -16,12 +16,7 @@ const (
|
||||
)
|
||||
|
||||
type ConsensusMessage struct {
|
||||
ConsensusID string
|
||||
Signature []byte `hash:"-"`
|
||||
RequestID string
|
||||
CallbackAddress []byte
|
||||
CallbackMethodID []byte
|
||||
Task types.DioneTask
|
||||
Task types.DioneTask
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
|
@ -15,7 +15,7 @@ func verifyTaskSignature(msg types.ConsensusMessage) error {
|
||||
return err
|
||||
}
|
||||
err = sigs.Verify(
|
||||
&types2.Signature{Type: types2.SigTypeEd25519, Data: msg.Signature},
|
||||
&types2.Signature{Type: types2.SigTypeEd25519, Data: msg.Task.Signature},
|
||||
[]byte(msg.Task.Miner),
|
||||
[]byte(fmt.Sprintf("%v", cHash)),
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ var (
|
||||
)
|
||||
|
||||
// DioneDisputeABI is the input ABI used to generate the binding from.
|
||||
const DioneDisputeABI = "[{\"inputs\":[{\"internalType\":\"contractIDioneStaking\",\"name\":\"_dioneStaking\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"DisputeFinished\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"miner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"disputeInitiator\",\"type\":\"address\"}],\"name\":\"NewDispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"votedMiner\",\"type\":\"address\"}],\"name\":\"NewVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"dioneStaking\",\"outputs\":[{\"internalType\":\"contractIDioneStaking\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"miner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"beginDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"voteStatus\",\"type\":\"bool\"}],\"name\":\"vote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"}],\"name\":\"finishDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],"
|
||||
const DioneDisputeABI = "[{\"inputs\":[{\"internalType\":\"contractIDioneStaking\",\"name\":\"_dioneStaking\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"status\",\"type\":\"bool\"}],\"name\":\"DisputeFinished\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"miner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"disputeInitiator\",\"type\":\"address\"}],\"name\":\"NewDispute\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"votedMiner\",\"type\":\"address\"}],\"name\":\"NewVote\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"dioneStaking\",\"outputs\":[{\"internalType\":\"contractIDioneStaking\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"miner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"beginDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"voteStatus\",\"type\":\"bool\"}],\"name\":\"vote\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"dhash\",\"type\":\"bytes32\"}],\"name\":\"finishDispute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
|
||||
|
||||
// DioneDispute is an auto generated Go binding around an Ethereum contract.
|
||||
type DioneDispute struct {
|
||||
@ -470,14 +470,15 @@ func (it *DioneDisputeNewDisputeIterator) Close() error {
|
||||
// DioneDisputeNewDispute represents a NewDispute event raised by the DioneDispute contract.
|
||||
type DioneDisputeNewDispute struct {
|
||||
Dhash [32]byte
|
||||
RequestID *big.Int
|
||||
Miner common.Address
|
||||
DisputeInitiator common.Address
|
||||
Raw types.Log // Blockchain specific contextual infos
|
||||
}
|
||||
|
||||
// FilterNewDispute is a free log retrieval operation binding the contract event 0xcd3d2ebd72bbbf7e5659c6790b60f42174aafe2741b7ba3807007455faae522e.
|
||||
// FilterNewDispute is a free log retrieval operation binding the contract event 0x2ce1dcf0fdc2fa2126a7df604e89d10856ef74891a365a93e779a5c4aff5370a.
|
||||
//
|
||||
// Solidity: event NewDispute(bytes32 dhash, address indexed miner, address indexed disputeInitiator)
|
||||
// Solidity: event NewDispute(bytes32 dhash, uint256 requestID, address indexed miner, address indexed disputeInitiator)
|
||||
func (_DioneDispute *DioneDisputeFilterer) FilterNewDispute(opts *bind.FilterOpts, miner []common.Address, disputeInitiator []common.Address) (*DioneDisputeNewDisputeIterator, error) {
|
||||
|
||||
var minerRule []interface{}
|
||||
@ -496,9 +497,9 @@ func (_DioneDispute *DioneDisputeFilterer) FilterNewDispute(opts *bind.FilterOpt
|
||||
return &DioneDisputeNewDisputeIterator{contract: _DioneDispute.contract, event: "NewDispute", logs: logs, sub: sub}, nil
|
||||
}
|
||||
|
||||
// WatchNewDispute is a free log subscription operation binding the contract event 0xcd3d2ebd72bbbf7e5659c6790b60f42174aafe2741b7ba3807007455faae522e.
|
||||
// WatchNewDispute is a free log subscription operation binding the contract event 0x2ce1dcf0fdc2fa2126a7df604e89d10856ef74891a365a93e779a5c4aff5370a.
|
||||
//
|
||||
// Solidity: event NewDispute(bytes32 dhash, address indexed miner, address indexed disputeInitiator)
|
||||
// Solidity: event NewDispute(bytes32 dhash, uint256 requestID, address indexed miner, address indexed disputeInitiator)
|
||||
func (_DioneDispute *DioneDisputeFilterer) WatchNewDispute(opts *bind.WatchOpts, sink chan<- *DioneDisputeNewDispute, miner []common.Address, disputeInitiator []common.Address) (event.Subscription, error) {
|
||||
|
||||
var minerRule []interface{}
|
||||
@ -542,9 +543,9 @@ func (_DioneDispute *DioneDisputeFilterer) WatchNewDispute(opts *bind.WatchOpts,
|
||||
}), nil
|
||||
}
|
||||
|
||||
// ParseNewDispute is a log parse operation binding the contract event 0xcd3d2ebd72bbbf7e5659c6790b60f42174aafe2741b7ba3807007455faae522e.
|
||||
// ParseNewDispute is a log parse operation binding the contract event 0x2ce1dcf0fdc2fa2126a7df604e89d10856ef74891a365a93e779a5c4aff5370a.
|
||||
//
|
||||
// Solidity: event NewDispute(bytes32 dhash, address indexed miner, address indexed disputeInitiator)
|
||||
// Solidity: event NewDispute(bytes32 dhash, uint256 requestID, address indexed miner, address indexed disputeInitiator)
|
||||
func (_DioneDispute *DioneDisputeFilterer) ParseNewDispute(log types.Log) (*DioneDisputeNewDispute, error) {
|
||||
event := new(DioneDisputeNewDispute)
|
||||
if err := _DioneDispute.contract.UnpackLog(event, "NewDispute", log); err != nil {
|
||||
|
@ -21,7 +21,7 @@ contract DioneDispute {
|
||||
|
||||
mapping(bytes32 => Dispute) disputes;
|
||||
|
||||
event NewDispute(bytes32 dhash, address indexed miner, address indexed disputeInitiator);
|
||||
event NewDispute(bytes32 dhash, uint256 requestID, address indexed miner, address indexed disputeInitiator);
|
||||
event NewVote(bytes32 dhash, address indexed votedMiner);
|
||||
event DisputeFinished(bytes32 dhash, bool status);
|
||||
|
||||
@ -43,7 +43,7 @@ contract DioneDispute {
|
||||
|
||||
disputes[dhash] = dispute;
|
||||
|
||||
emit NewDispute(dhash, miner, msg.sender);
|
||||
emit NewDispute(dhash, requestID, miner, msg.sender);
|
||||
}
|
||||
|
||||
function vote(bytes32 dhash, bool voteStatus) public {
|
||||
|
@ -2,7 +2,6 @@ package ethclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
|
||||
"github.com/Secured-Finance/dione/contracts/dioneDispute"
|
||||
@ -158,14 +157,8 @@ func (c *EthereumClient) BeginDispute(miner common.Address, requestID *big.Int)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *EthereumClient) VoteDispute(dhash string, voteStatus bool) error {
|
||||
dhashRawSlice, err := hex.DecodeString(dhash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dhashRaw [32]byte
|
||||
copy(dhashRaw[:], dhashRawSlice)
|
||||
_, err = c.disputeContract.Vote(dhashRaw, voteStatus)
|
||||
func (c *EthereumClient) VoteDispute(dhash [32]byte, voteStatus bool) error {
|
||||
_, err := c.disputeContract.Vote(dhash, voteStatus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -173,14 +166,8 @@ func (c *EthereumClient) VoteDispute(dhash string, voteStatus bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *EthereumClient) FinishDispute(dhash string) error {
|
||||
dhashRawSlice, err := hex.DecodeString(dhash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var dhashRaw [32]byte
|
||||
copy(dhashRaw[:], dhashRawSlice)
|
||||
_, err = c.disputeContract.FinishDispute(dhashRaw)
|
||||
func (c *EthereumClient) FinishDispute(dhash [32]byte) error {
|
||||
_, err := c.disputeContract.FinishDispute(dhash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -205,7 +192,7 @@ func (c *EthereumClient) SubscribeOnNewSubmittions(ctx context.Context) (chan *d
|
||||
resChan := make(chan *dioneOracle.DioneOracleSubmittedOracleRequest)
|
||||
requestsFilter := c.dioneOracle.Contract.DioneOracleFilterer
|
||||
subscription, err := requestsFilter.WatchSubmittedOracleRequest(&bind.WatchOpts{
|
||||
Start: nil, //last block
|
||||
Start: nil, // last block
|
||||
Context: ctx,
|
||||
}, resChan)
|
||||
if err != nil {
|
||||
|
@ -19,16 +19,21 @@ func (e DrandRound) String() string {
|
||||
|
||||
// DioneTask represents the values of task computation
|
||||
type DioneTask struct {
|
||||
OriginChain uint8
|
||||
RequestType string
|
||||
RequestParams string
|
||||
Miner peer.ID
|
||||
MinerEth string
|
||||
Ticket *Ticket
|
||||
ElectionProof *ElectionProof
|
||||
BeaconEntries []BeaconEntry
|
||||
DrandRound DrandRound
|
||||
Payload []byte
|
||||
OriginChain uint8
|
||||
RequestType string
|
||||
RequestParams string
|
||||
Miner peer.ID
|
||||
MinerEth string
|
||||
Ticket *Ticket
|
||||
ElectionProof *ElectionProof
|
||||
BeaconEntries []BeaconEntry
|
||||
DrandRound DrandRound
|
||||
Payload []byte
|
||||
RequestID string
|
||||
CallbackAddress []byte
|
||||
CallbackMethodID []byte
|
||||
ConsensusID string
|
||||
Signature []byte `hash:"-"`
|
||||
}
|
||||
|
||||
func NewDioneTask(
|
||||
|
Loading…
Reference in New Issue
Block a user