diff --git a/consensus/miner.go b/consensus/miner.go index 9a0c995..20f1c24 100644 --- a/consensus/miner.go +++ b/consensus/miner.go @@ -2,16 +2,12 @@ package consensus import ( "context" - "encoding/json" - "strconv" "sync" - fil "github.com/Secured-Finance/dione/rpc/filecoin" - solana2 "github.com/Secured-Finance/dione/rpc/solana" + "github.com/Secured-Finance/dione/rpc" "github.com/Secured-Finance/dione/beacon" oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter" - solTypes "github.com/Secured-Finance/dione/rpc/solana/types" "github.com/libp2p/go-libp2p-core/peer" "github.com/Secured-Finance/dione/ethclient" @@ -23,16 +19,14 @@ import ( ) type Miner struct { - address peer.ID - ethAddress common.Address - api WalletAPI - mutex sync.Mutex - beacon beacon.BeaconNetworks - ethClient *ethclient.EthereumClient - filecoinClient *fil.LotusClient - solanaClient *solana2.SolanaClient - minerStake types.BigInt - networkStake types.BigInt + address peer.ID + ethAddress common.Address + api WalletAPI + mutex sync.Mutex + beacon beacon.BeaconNetworks + ethClient *ethclient.EthereumClient + minerStake types.BigInt + networkStake types.BigInt } func NewMiner( @@ -41,17 +35,13 @@ func NewMiner( api WalletAPI, beacon beacon.BeaconNetworks, ethClient *ethclient.EthereumClient, - filecoinClient *fil.LotusClient, - solanaClient *solana2.SolanaClient, ) *Miner { return &Miner{ - address: address, - ethAddress: ethAddress, - api: api, - beacon: beacon, - ethClient: ethClient, - filecoinClient: filecoinClient, - solanaClient: solanaClient, + address: address, + ethAddress: ethAddress, + api: api, + beacon: beacon, + ethClient: ethClient, } } @@ -107,28 +97,25 @@ func (m *Miner) MineTask(ctx context.Context, event *oracleEmitter.OracleEmitter return nil, nil } - // res, err := m.solanaClient.GetTransaction(event.RequestParams) - res, err := m.EventRequestType(event.RequestType, event.RequestParams) + rpcMethod := rpc.GetRPCMethod(event.OriginChain, event.RequestType) + if rpcMethod == nil { + return nil, xerrors.Errorf("invalid rpc method name/type") + } + res, err := rpcMethod(event.RequestParams) if err != nil { - return nil, xerrors.Errorf("Couldn't get solana request: %w", err) + return nil, xerrors.Errorf("couldn't do rpc request: %w", err) } - var txRes solTypes.TxResponse - if err = json.Unmarshal(res, &txRes); err != nil { - return nil, xerrors.Errorf("Couldn't unmarshal solana response: %w", err) - } - blockHash := txRes.Result.Transaction.Message.RecentBlockhash - signature, err := sign(ctx, m.address, res) + bres := []byte(res) + signature, err := sign(ctx, m.address, bres) if err != nil { return nil, xerrors.Errorf("Couldn't sign solana response: %w", err) } return &types.DioneTask{ - Miner: m.address, Ticket: ticket, ElectionProof: winner, BeaconEntries: bvals, - Payload: res, - BlockHash: blockHash, + Payload: bres, Signature: signature, DrandRound: types.DrandRound(rbase.Round), }, nil @@ -156,24 +143,3 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry) (*t VRFProof: vrfOut, }, nil } - -func (m *Miner) EventRequestType(rType uint8, params string) ([]byte, error) { - switch rType { - case 1: - return m.filecoinClient.GetTransaction(params) - case 2: - return m.filecoinClient.GetBlock(params) - case 3: - i, err := strconv.ParseInt(params, 10, 64) - if err != nil { - return nil, xerrors.Errorf("Couldn't parse int from string request params: %w", err) - } - return m.filecoinClient.GetTipSetByHeight(i) - case 4: - return m.filecoinClient.GetChainHead() - case 5: - return m.filecoinClient.GetNodeVersion() - default: - return m.filecoinClient.GetTransaction(params) - } -} diff --git a/contracts/oracleemitter/OracleEmitter.go b/contracts/oracleemitter/OracleEmitter.go index 7496bb3..b4e5a19 100644 --- a/contracts/oracleemitter/OracleEmitter.go +++ b/contracts/oracleemitter/OracleEmitter.go @@ -27,7 +27,7 @@ var ( ) // OracleEmitterABI is the input ABI used to generate the binding from. -const OracleEmitterABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"originChain\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"requestType\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"requestParams\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"callbackMethodID\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"NewOracleRequest\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"originChain\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"requestType\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"requestParams\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"callbackMethodID\",\"type\":\"bytes4\"}],\"name\":\"requestOracles\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" +const OracleEmitterABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"originChain\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"requestType\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"requestParams\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"callbackMethodID\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"NewOracleRequest\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"originChain\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"requestType\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"requestParams\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"callbackMethodID\",\"type\":\"bytes4\"}],\"name\":\"requestOracles\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" // OracleEmitter is an auto generated Go binding around an Ethereum contract. type OracleEmitter struct { @@ -137,7 +137,7 @@ func bindOracleEmitter(address common.Address, caller bind.ContractCaller, trans // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OracleEmitter *OracleEmitterRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_OracleEmitter *OracleEmitterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _OracleEmitter.Contract.OracleEmitterCaller.contract.Call(opts, result, method, params...) } @@ -156,7 +156,7 @@ func (_OracleEmitter *OracleEmitterRaw) Transact(opts *bind.TransactOpts, method // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OracleEmitter *OracleEmitterCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_OracleEmitter *OracleEmitterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _OracleEmitter.Contract.contract.Call(opts, result, method, params...) } @@ -171,24 +171,24 @@ func (_OracleEmitter *OracleEmitterTransactorRaw) Transact(opts *bind.TransactOp return _OracleEmitter.Contract.contract.Transact(opts, method, params...) } -// RequestOracles is a paid mutator transaction binding the contract method 0xa5bc5dfe. +// RequestOracles is a paid mutator transaction binding the contract method 0xe7c3712a. // -// Solidity: function requestOracles(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) -func (_OracleEmitter *OracleEmitterTransactor) RequestOracles(opts *bind.TransactOpts, originChain uint8, requestType uint8, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { +// Solidity: function requestOracles(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) +func (_OracleEmitter *OracleEmitterTransactor) RequestOracles(opts *bind.TransactOpts, originChain uint8, requestType string, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { return _OracleEmitter.contract.Transact(opts, "requestOracles", originChain, requestType, requestParams, callbackAddress, callbackMethodID) } -// RequestOracles is a paid mutator transaction binding the contract method 0xa5bc5dfe. +// RequestOracles is a paid mutator transaction binding the contract method 0xe7c3712a. // -// Solidity: function requestOracles(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) -func (_OracleEmitter *OracleEmitterSession) RequestOracles(originChain uint8, requestType uint8, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { +// Solidity: function requestOracles(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) +func (_OracleEmitter *OracleEmitterSession) RequestOracles(originChain uint8, requestType string, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { return _OracleEmitter.Contract.RequestOracles(&_OracleEmitter.TransactOpts, originChain, requestType, requestParams, callbackAddress, callbackMethodID) } -// RequestOracles is a paid mutator transaction binding the contract method 0xa5bc5dfe. +// RequestOracles is a paid mutator transaction binding the contract method 0xe7c3712a. // -// Solidity: function requestOracles(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) -func (_OracleEmitter *OracleEmitterTransactorSession) RequestOracles(originChain uint8, requestType uint8, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { +// Solidity: function requestOracles(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID) returns(uint256) +func (_OracleEmitter *OracleEmitterTransactorSession) RequestOracles(originChain uint8, requestType string, requestParams string, callbackAddress common.Address, callbackMethodID [4]byte) (*types.Transaction, error) { return _OracleEmitter.Contract.RequestOracles(&_OracleEmitter.TransactOpts, originChain, requestType, requestParams, callbackAddress, callbackMethodID) } @@ -262,7 +262,7 @@ func (it *OracleEmitterNewOracleRequestIterator) Close() error { // OracleEmitterNewOracleRequest represents a NewOracleRequest event raised by the OracleEmitter contract. type OracleEmitterNewOracleRequest struct { OriginChain uint8 - RequestType uint8 + RequestType string RequestParams string CallbackAddress common.Address CallbackMethodID [4]byte @@ -270,9 +270,9 @@ type OracleEmitterNewOracleRequest struct { Raw types.Log // Blockchain specific contextual infos } -// FilterNewOracleRequest is a free log retrieval operation binding the contract event 0xaa3cd18b7cba9d24d288b9b45616e263b5f40a939fe7f4341f789b955649ea4a. +// FilterNewOracleRequest is a free log retrieval operation binding the contract event 0x661106d02c3bf98eb59554e55d23c9517ad1f25020f83102a720ad27e3617760. // -// Solidity: event NewOracleRequest(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) +// Solidity: event NewOracleRequest(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) func (_OracleEmitter *OracleEmitterFilterer) FilterNewOracleRequest(opts *bind.FilterOpts) (*OracleEmitterNewOracleRequestIterator, error) { logs, sub, err := _OracleEmitter.contract.FilterLogs(opts, "NewOracleRequest") @@ -282,9 +282,9 @@ func (_OracleEmitter *OracleEmitterFilterer) FilterNewOracleRequest(opts *bind.F return &OracleEmitterNewOracleRequestIterator{contract: _OracleEmitter.contract, event: "NewOracleRequest", logs: logs, sub: sub}, nil } -// WatchNewOracleRequest is a free log subscription operation binding the contract event 0xaa3cd18b7cba9d24d288b9b45616e263b5f40a939fe7f4341f789b955649ea4a. +// WatchNewOracleRequest is a free log subscription operation binding the contract event 0x661106d02c3bf98eb59554e55d23c9517ad1f25020f83102a720ad27e3617760. // -// Solidity: event NewOracleRequest(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) +// Solidity: event NewOracleRequest(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) func (_OracleEmitter *OracleEmitterFilterer) WatchNewOracleRequest(opts *bind.WatchOpts, sink chan<- *OracleEmitterNewOracleRequest) (event.Subscription, error) { logs, sub, err := _OracleEmitter.contract.WatchLogs(opts, "NewOracleRequest") @@ -319,9 +319,9 @@ func (_OracleEmitter *OracleEmitterFilterer) WatchNewOracleRequest(opts *bind.Wa }), nil } -// ParseNewOracleRequest is a log parse operation binding the contract event 0xaa3cd18b7cba9d24d288b9b45616e263b5f40a939fe7f4341f789b955649ea4a. +// ParseNewOracleRequest is a log parse operation binding the contract event 0x661106d02c3bf98eb59554e55d23c9517ad1f25020f83102a720ad27e3617760. // -// Solidity: event NewOracleRequest(uint8 originChain, uint8 requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) +// Solidity: event NewOracleRequest(uint8 originChain, string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID) func (_OracleEmitter *OracleEmitterFilterer) ParseNewOracleRequest(log types.Log) (*OracleEmitterNewOracleRequest, error) { event := new(OracleEmitterNewOracleRequest) if err := _OracleEmitter.contract.UnpackLog(event, "NewOracleRequest", log); err != nil { diff --git a/eth-contracts/contracts/Mediator.sol b/eth-contracts/contracts/Mediator.sol index d054cab..75c9fee 100644 --- a/eth-contracts/contracts/Mediator.sol +++ b/eth-contracts/contracts/Mediator.sol @@ -18,7 +18,7 @@ contract Mediator is Ownable { aggregator = _aggregator; } - function request(uint8 originChain, uint8 requestType, string memory requestParams) public returns (uint256) { + function request(uint8 originChain, string memory requestType, string memory requestParams) public returns (uint256) { return oracleEmitter.requestOracles(originChain, requestType, requestParams, address(this), bytes4(keccak256("_receiveDataCallback(uint256, string)"))); } diff --git a/eth-contracts/contracts/OracleEmitter.sol b/eth-contracts/contracts/OracleEmitter.sol index 4409d73..36ae5d6 100644 --- a/eth-contracts/contracts/OracleEmitter.sol +++ b/eth-contracts/contracts/OracleEmitter.sol @@ -6,14 +6,14 @@ contract OracleEmitter { event NewOracleRequest( uint8 originChain, - uint8 requestType, + string requestType, string requestParams, address callbackAddress, bytes4 callbackMethodID, uint256 requestID ); - function requestOracles(uint8 originChain, uint8 requestType, string memory requestParams, address callbackAddress, bytes4 callbackMethodID) public returns (uint256) { + function requestOracles(uint8 originChain, string memory requestType, string memory requestParams, address callbackAddress, bytes4 callbackMethodID) public returns (uint256) { requestCounter++; emit NewOracleRequest(originChain, requestType, requestParams, callbackAddress, callbackMethodID, requestCounter); return requestCounter; diff --git a/node/node.go b/node/node.go index ea50d8b..4e30e5c 100644 --- a/node/node.go +++ b/node/node.go @@ -9,6 +9,9 @@ import ( "os" "time" + "github.com/Secured-Finance/dione/rpc" + rtypes "github.com/Secured-Finance/dione/rpc/types" + solana2 "github.com/Secured-Finance/dione/rpc/solana" "github.com/Secured-Finance/dione/rpc/filecoin" @@ -45,9 +48,7 @@ type Node struct { GlobalCtxCancel context.CancelFunc OracleTopic string Config *config.Config - Lotus *filecoin.LotusClient Ethereum *ethclient.EthereumClient - Solana *solana2.SolanaClient ConsensusManager *consensus.PBFTConsensusManager Miner *consensus.Miner Beacon beacon.BeaconNetworks @@ -69,12 +70,16 @@ func NewNode(configPath string) (*Node, error) { func (n *Node) setupNode(ctx context.Context, prvKey crypto.PrivKey, pexDiscoveryUpdateTime time.Duration) { n.setupLibp2pHost(context.TODO(), prvKey, pexDiscoveryUpdateTime) - //n.setupFilecoinClient() err := n.setupEthereumClient() if err != nil { logrus.Fatal(err) } - n.setupSolanaClient() + + err = n.setupRPCClients() + if err != nil { + logrus.Fatal(err) + } + n.setupPubsub() err = n.setupConsensusManager(prvKey, n.Config.ConsensusMinApprovals) if err != nil { @@ -96,7 +101,7 @@ func (n *Node) setupNode(ctx context.Context, prvKey crypto.PrivKey, pexDiscover } func (n *Node) setupMiner() error { - n.Miner = consensus.NewMiner(n.Host.ID(), *n.Ethereum.GetEthAddress(), n.Wallet, n.Beacon, n.Ethereum, n.Lotus, n.Solana) + n.Miner = consensus.NewMiner(n.Host.ID(), *n.Ethereum.GetEthAddress(), n.Wallet, n.Beacon, n.Ethereum) return nil } @@ -142,14 +147,18 @@ func (n *Node) setupEthereumClient() error { ) } -func (n *Node) setupFilecoinClient() { - lotus := filecoin.NewLotusClient() - n.Lotus = lotus -} +func (n *Node) setupRPCClients() error { + fc := filecoin.NewLotusClient() + rpc.RegisterRPC(rtypes.RPCTypeFilecoin, map[string]func(string) (string, error){ + "getTransaction": fc.GetTransaction, + }) -func (n *Node) setupSolanaClient() { - solana := solana2.NewSolanaClient() - n.Solana = solana + sl := solana2.NewSolanaClient() + rpc.RegisterRPC(rtypes.RPCTypeSolana, map[string]func(string) (string, error){ + "getTransaction": sl.GetTransaction, + }) + + return nil } func (n *Node) setupPubsub() { @@ -300,5 +309,3 @@ func generatePrivateKey() (crypto.PrivKey, error) { } return prvKey, nil } - -// TODO generate Miner for the node diff --git a/rpc/filecoin/filecoin.go b/rpc/filecoin/filecoin.go index 7f8ec68..afd9385 100644 --- a/rpc/filecoin/filecoin.go +++ b/rpc/filecoin/filecoin.go @@ -38,9 +38,10 @@ func (c *LotusClient) GetTipSetByHeight(chainEpoch int64) ([]byte, error) { return c.HandleRequest("Filecoin.ChainGetTipSetByHeight", i) } -func (c *LotusClient) GetTransaction(cid string) ([]byte, error) { +func (c *LotusClient) GetTransaction(cid string) (string, error) { i := ftypes.NewCidParam(cid) - return c.HandleRequest("Filecoin.ChainGetMessage", i) + resp, err := c.HandleRequest("Filecoin.ChainGetMessage", i) + return string(resp), err } func (c *LotusClient) GetNodeVersion() ([]byte, error) { diff --git a/rpc/rpc.go b/rpc/rpc.go index 717b7b4..68f41ee 100644 --- a/rpc/rpc.go +++ b/rpc/rpc.go @@ -1,5 +1,19 @@ package rpc -type RPCClient interface { - GetTransaction(txHash string) ([]byte, error) +var rpcs = map[uint8]map[string]func(string) (string, error){} // rpcType -> {rpcMethodName -> actual func var} + +func RegisterRPC(rpcType uint8, rpcMethods map[string]func(string) (string, error)) { + rpcs[rpcType] = rpcMethods +} + +func GetRPCMethod(rpcType uint8, rpcMethodName string) func(string) (string, error) { + rpcMethods, ok := rpcs[rpcType] + if !ok { + return nil + } + actualMethod, ok := rpcMethods[rpcMethodName] + if !ok { + return nil + } + return actualMethod } diff --git a/rpc/solana/solana.go b/rpc/solana/solana.go index cf9b0c1..9a9173a 100644 --- a/rpc/solana/solana.go +++ b/rpc/solana/solana.go @@ -39,7 +39,7 @@ func NewSolanaClient() *SolanaClient { } } -func (c *SolanaClient) GetTransaction(txHash string) ([]byte, error) { +func (c *SolanaClient) GetTransaction(txHash string) (string, error) { req := fasthttp.AcquireRequest() req.SetRequestURI(c.url) req.Header.SetMethod("POST") @@ -48,18 +48,18 @@ func (c *SolanaClient) GetTransaction(txHash string) ([]byte, error) { requestBody.Params = append(requestBody.Params, txHash, "json") body, err := json.Marshal(requestBody) if err != nil { - return nil, fmt.Errorf("Failed to marshal request body %v", err) + return "", fmt.Errorf("Failed to marshal request body %v", err) } req.AppendBody(body) resp := fasthttp.AcquireResponse() client := &fasthttp.Client{} if err = client.Do(req, resp); err != nil { logrus.Warn("Failed to construct solana node rpc request", err) - return nil, err + return "", err } bodyBytes := resp.Body() logrus.Info(string(bodyBytes)) - return bodyBytes, nil + return string(bodyBytes), nil } func (c *SolanaClient) subscribeOnProgram(programID string) { diff --git a/rpc/types/rpc_types.go b/rpc/types/rpc_types.go new file mode 100644 index 0000000..f314c2e --- /dev/null +++ b/rpc/types/rpc_types.go @@ -0,0 +1,8 @@ +package types + +const ( + RPCTypeEthereum = uint8(iota) + + RPCTypeFilecoin + RPCTypeSolana +) diff --git a/types/task.go b/types/task.go index 53b3a28..08027ed 100644 --- a/types/task.go +++ b/types/task.go @@ -29,14 +29,12 @@ func (e DrandRound) String() string { // Miner is an address of miner node type DioneTask struct { Type TaskType - Miner peer.ID Ticket *Ticket ElectionProof *ElectionProof BeaconEntries []BeaconEntry Signature *Signature DrandRound DrandRound Payload []byte - BlockHash string } func NewDioneTask( @@ -48,18 +46,15 @@ func NewDioneTask( sig *Signature, drand DrandRound, payload []byte, - blockHash string, ) *DioneTask { return &DioneTask{ Type: t, - Miner: miner, Ticket: ticket, ElectionProof: electionProof, BeaconEntries: beacon, Signature: sig, DrandRound: drand, Payload: payload, - BlockHash: blockHash, } }