diff --git a/rpc/api.go b/rpc/api.go index d5e18eec86..1102b7cb20 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -348,13 +348,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error opts := toFilterOptions(args) *reply = NewLogsRes(p.xeth().AllLogs(opts)) case "eth_getWork": - *reply = p.getWork() + p.xeth().SetMining(true) + *reply = p.agent.GetWork().Hex() case "eth_submitWork": - // TODO what is the reply here? - // TODO what are the arguments? - p.agent.SetResult(0, common.Hash{}, common.Hash{}) - - return NewNotImplementedError(req.Method) + args := new(SubmitWorkArgs) + if err := json.Unmarshal(req.Params, &args); err != nil { + return err + } + *reply = p.agent.SetResult(args.Nonce, args.Digest, args.Header) case "db_putString": args := new(DbArgs) if err := json.Unmarshal(req.Params, &args); err != nil { @@ -466,11 +467,6 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return nil } -func (p *EthereumApi) getWork() string { - p.xeth().SetMining(true) - return p.agent.GetWork().Hex() -} - func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions { var opts core.FilterOptions diff --git a/rpc/args.go b/rpc/args.go index e50c9b1f5b..504e67c07e 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -686,3 +686,42 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { return nil } + +type SubmitWorkArgs struct { + Nonce uint64 + Header common.Hash + Digest common.Hash +} + +func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err = json.Unmarshal(b, &obj); err != nil { + return NewDecodeParamError(err.Error()) + } + + if len(obj) < 3 { + return NewInsufficientParamsError(len(obj), 3) + } + + var objstr string + var ok bool + if objstr, ok = obj[0].(string); !ok { + return NewDecodeParamError("Nonce is not a string") + } + + args.Nonce = common.BytesToNumber(common.Hex2Bytes(objstr)) + + if objstr, ok = obj[1].(string); !ok { + return NewDecodeParamError("Header is not a string") + } + + args.Header = common.HexToHash(objstr) + + if objstr, ok = obj[2].(string); !ok { + return NewDecodeParamError("Digest is not a string") + } + + args.Digest = common.HexToHash(objstr) + + return nil +} diff --git a/rpc/miner_agest.go b/rpc/miner_agest.go index 64dba82a64..46fb872071 100644 --- a/rpc/miner_agest.go +++ b/rpc/miner_agest.go @@ -55,6 +55,8 @@ out: } func (a *Agent) GetWork() common.Hash { + // TODO return HashNoNonce, DAGSeedHash, Difficulty + // XXX Wait here untill work != nil ?. if a.work != nil { return a.work.HashNoNonce() @@ -62,9 +64,14 @@ func (a *Agent) GetWork() common.Hash { return common.Hash{} } -func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) { +func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) bool { + // Return true or false, but does not indicate if the PoW was correct + // Make sure the external miner was working on the right hash if a.currentWork != nil && a.work != nil && a.currentWork.Hash() == a.work.Hash() { a.returnCh <- miner.Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()} + return true } + + return false }