mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
added admin api
This commit is contained in:
parent
969adf0c06
commit
719a23c6f6
14 changed files with 1108 additions and 802 deletions
|
|
@ -5,6 +5,23 @@ node admin bindings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (js *jsre) adminBindings() {
|
func (js *jsre) adminBindings() {
|
||||||
|
|
||||||
|
js.re.Set("admin", struct{}{})
|
||||||
|
t, _ := js.re.Get("admin")
|
||||||
|
admin := t.Object()
|
||||||
|
|
||||||
|
admin.Set("miner", struct{}{})
|
||||||
|
t, _ = admin.Get("miner")
|
||||||
|
miner := t.Object()
|
||||||
|
miner.Set("start", js.startMining)
|
||||||
|
// miner.Set("stop", js.stopMining)
|
||||||
|
// miner.Set("hashrate", js.hashrate)
|
||||||
|
// miner.Set("setExtra", js.setExtra)
|
||||||
|
// miner.Set("setGasPrice", js.setGasPrice)
|
||||||
|
// miner.Set("startAutoDAG", js.startAutoDAG)
|
||||||
|
// miner.Set("stopAutoDAG", js.stopAutoDAG)
|
||||||
|
// miner.Set("makeDAG", js.makeDAG)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ethO, _ := js.re.Get("eth")
|
ethO, _ := js.re.Get("eth")
|
||||||
eth := ethO.Object()
|
eth := ethO.Object()
|
||||||
|
|
@ -40,17 +57,7 @@ func (js *jsre) adminBindings() {
|
||||||
cinfo.Set("registerUrl", js.registerUrl)
|
cinfo.Set("registerUrl", js.registerUrl)
|
||||||
// cinfo.Set("verify", js.verify)
|
// cinfo.Set("verify", js.verify)
|
||||||
|
|
||||||
admin.Set("miner", struct{}{})
|
|
||||||
t, _ = admin.Get("miner")
|
|
||||||
miner := t.Object()
|
|
||||||
miner.Set("start", js.startMining)
|
|
||||||
miner.Set("stop", js.stopMining)
|
|
||||||
miner.Set("hashrate", js.hashrate)
|
|
||||||
miner.Set("setExtra", js.setExtra)
|
|
||||||
miner.Set("setGasPrice", js.setGasPrice)
|
|
||||||
miner.Set("startAutoDAG", js.startAutoDAG)
|
|
||||||
miner.Set("stopAutoDAG", js.stopAutoDAG)
|
|
||||||
miner.Set("makeDAG", js.makeDAG)
|
|
||||||
|
|
||||||
admin.Set("debug", struct{}{})
|
admin.Set("debug", struct{}{})
|
||||||
t, _ = admin.Get("debug")
|
t, _ = admin.Get("debug")
|
||||||
|
|
@ -67,777 +74,3 @@ func (js *jsre) adminBindings() {
|
||||||
debug.Set("waitForBlocks", js.waitForBlocks)
|
debug.Set("waitForBlocks", js.waitForBlocks)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// generic helper to getBlock by Number/Height or Hex depending on autodetected input
|
|
||||||
// if argument is missing the current block is returned
|
|
||||||
// if block is not found or there is problem with decoding
|
|
||||||
// the appropriate value is returned and block is guaranteed to be nil
|
|
||||||
func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
|
|
||||||
var block *types.Block
|
|
||||||
if len(call.ArgumentList) > 0 {
|
|
||||||
if call.Argument(0).IsNumber() {
|
|
||||||
num, _ := call.Argument(0).ToInteger()
|
|
||||||
block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
|
|
||||||
} else if call.Argument(0).IsString() {
|
|
||||||
hash, _ := call.Argument(0).ToString()
|
|
||||||
block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
|
|
||||||
} else {
|
|
||||||
return nil, errors.New("invalid argument for dump. Either hex string or number")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
block = js.ethereum.ChainManager().CurrentBlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
if block == nil {
|
|
||||||
return nil, errors.New("block not found")
|
|
||||||
}
|
|
||||||
return block, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) seedHash(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) > 0 {
|
|
||||||
if call.Argument(0).IsNumber() {
|
|
||||||
num, _ := call.Argument(0).ToInteger()
|
|
||||||
hash, err := ethash.GetSeedHash(uint64(num))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
v, _ := call.Otto.ToValue(fmt.Sprintf("0x%x", hash))
|
|
||||||
return v
|
|
||||||
} else {
|
|
||||||
fmt.Println("arg not a number")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("requires number argument")
|
|
||||||
}
|
|
||||||
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
|
|
||||||
txs := js.ethereum.TxPool().GetTransactions()
|
|
||||||
|
|
||||||
// grab the accounts from the account manager. This will help with determening which
|
|
||||||
// transactions should be returned.
|
|
||||||
accounts, err := js.ethereum.AccountManager().Accounts()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the accouns to a new set
|
|
||||||
accountSet := set.New()
|
|
||||||
for _, account := range accounts {
|
|
||||||
accountSet.Add(account.Address)
|
|
||||||
}
|
|
||||||
|
|
||||||
//ltxs := make([]*tx, len(txs))
|
|
||||||
var ltxs []*tx
|
|
||||||
for _, tx := range txs {
|
|
||||||
// no need to check err
|
|
||||||
if from, _ := tx.From(); accountSet.Has(from) {
|
|
||||||
ltxs = append(ltxs, newTx(tx))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v, _ := call.Otto.ToValue(ltxs)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) resend(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) == 0 {
|
|
||||||
fmt.Println("first argument must be a transaction")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := call.Argument(0).Export()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
if tx, ok := v.(*tx); ok {
|
|
||||||
gl, gp := tx.GasLimit, tx.GasPrice
|
|
||||||
if len(call.ArgumentList) > 1 {
|
|
||||||
gp = call.Argument(1).String()
|
|
||||||
}
|
|
||||||
if len(call.ArgumentList) > 2 {
|
|
||||||
gl = call.Argument(2).String()
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, err := js.xeth.Transact(tx.From, tx.To, tx.Nonce, tx.Value, gl, gp, tx.Data)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
js.ethereum.TxPool().RemoveTransactions(types.Transactions{tx.tx})
|
|
||||||
|
|
||||||
v, _ := call.Otto.ToValue(ret)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("first argument must be a transaction")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) sign(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) != 2 {
|
|
||||||
fmt.Println("requires 2 arguments: eth.sign(signer, data)")
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
signer, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := call.Argument(1).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
signed, err := js.xeth.Sign(signer, data, false)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
v, _ := call.Otto.ToValue(signed)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
|
|
||||||
block, err := js.getBlock(call)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
old := vm.Debug
|
|
||||||
vm.Debug = true
|
|
||||||
_, err = js.ethereum.BlockProcessor().RetryProcess(block)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
vm.Debug = old
|
|
||||||
|
|
||||||
fmt.Println("ok")
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
|
|
||||||
block, err := js.getBlock(call)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
js.ethereum.ChainManager().SetHead(block)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
|
|
||||||
pending, cached := js.ethereum.Downloader().Stats()
|
|
||||||
v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached})
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value {
|
|
||||||
block, err := js.getBlock(call)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
encoded, _ := rlp.EncodeToBytes(block)
|
|
||||||
v, _ := call.Otto.ToValue(fmt.Sprintf("%x", encoded))
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) setExtra(call otto.FunctionCall) otto.Value {
|
|
||||||
extra, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(extra) > 1024 {
|
|
||||||
fmt.Println("error: cannot exceed 1024 bytes")
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
js.ethereum.Miner().SetExtra([]byte(extra))
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) setGasPrice(call otto.FunctionCall) otto.Value {
|
|
||||||
gasPrice, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
js.ethereum.Miner().SetGasPrice(common.String2Big(gasPrice))
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) hashrate(call otto.FunctionCall) otto.Value {
|
|
||||||
v, _ := call.Otto.ToValue(js.ethereum.Miner().HashRate())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) makeDAG(call otto.FunctionCall) otto.Value {
|
|
||||||
blockNumber, err := call.Argument(1).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ethash.MakeDAG(uint64(blockNumber), "")
|
|
||||||
if err != nil {
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) startAutoDAG(otto.FunctionCall) otto.Value {
|
|
||||||
js.ethereum.StartAutoDAG()
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) stopAutoDAG(otto.FunctionCall) otto.Value {
|
|
||||||
js.ethereum.StopAutoDAG()
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) backtrace(call otto.FunctionCall) otto.Value {
|
|
||||||
tracestr, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
glog.GetTraceLocation().Set(tracestr)
|
|
||||||
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) verbosity(call otto.FunctionCall) otto.Value {
|
|
||||||
v, err := call.Argument(0).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
glog.SetV(int(v))
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) startMining(call otto.FunctionCall) otto.Value {
|
|
||||||
var (
|
|
||||||
threads int64
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(call.ArgumentList) > 0 {
|
|
||||||
threads, err = call.Argument(0).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
threads = int64(js.ethereum.MinerThreads)
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch on DAG autogeneration when miner starts
|
|
||||||
js.ethereum.StartAutoDAG()
|
|
||||||
|
|
||||||
err = js.ethereum.StartMining(int(threads))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) stopMining(call otto.FunctionCall) otto.Value {
|
|
||||||
js.ethereum.StopMining()
|
|
||||||
js.ethereum.StopAutoDAG()
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) startRPC(call otto.FunctionCall) otto.Value {
|
|
||||||
addr, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
port, err := call.Argument(1).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
corsDomain := js.corsDomain
|
|
||||||
if len(call.ArgumentList) > 2 {
|
|
||||||
corsDomain, err = call.Argument(2).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config := rpc.RpcConfig{
|
|
||||||
ListenAddress: addr,
|
|
||||||
ListenPort: uint(port),
|
|
||||||
CorsDomain: corsDomain,
|
|
||||||
}
|
|
||||||
|
|
||||||
xeth := xeth.New(js.ethereum, nil)
|
|
||||||
err = rpc.Start(xeth, config)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value {
|
|
||||||
if rpc.Stop() == nil {
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) addPeer(call otto.FunctionCall) otto.Value {
|
|
||||||
nodeURL, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
err = js.ethereum.AddPeer(nodeURL)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
|
|
||||||
addr, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
seconds, err := call.Argument(2).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
if seconds == 0 {
|
|
||||||
seconds = accounts.DefaultAccountUnlockDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
arg := call.Argument(1)
|
|
||||||
var passphrase string
|
|
||||||
if arg.IsUndefined() {
|
|
||||||
fmt.Println("Please enter a passphrase now.")
|
|
||||||
passphrase, err = utils.PromptPassword("Passphrase: ", true)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
passphrase, err = arg.ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
am := js.ethereum.AccountManager()
|
|
||||||
err = am.TimedUnlock(common.HexToAddress(addr), passphrase, time.Duration(seconds)*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Unlock account failed '%v'\n", err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
|
|
||||||
arg := call.Argument(0)
|
|
||||||
var passphrase string
|
|
||||||
if arg.IsUndefined() {
|
|
||||||
fmt.Println("The new account will be encrypted with a passphrase.")
|
|
||||||
fmt.Println("Please enter a passphrase now.")
|
|
||||||
auth, err := utils.PromptPassword("Passphrase: ", true)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
confirm, err := utils.PromptPassword("Repeat Passphrase: ", false)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
if auth != confirm {
|
|
||||||
fmt.Println("Passphrases did not match.")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
passphrase = auth
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
passphrase, err = arg.ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
acct, err := js.ethereum.AccountManager().NewAccount(passphrase)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Could not create the account: %v", err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
v, _ := call.Otto.ToValue(acct.Address.Hex())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {
|
|
||||||
v, _ := call.Otto.ToValue(js.ethereum.NodeInfo())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) peers(call otto.FunctionCall) otto.Value {
|
|
||||||
v, _ := call.Otto.ToValue(js.ethereum.PeersInfo())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) importChain(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) == 0 {
|
|
||||||
fmt.Println("require file name. admin.importChain(filename)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
fn, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil {
|
|
||||||
fmt.Println("Import error: ", err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) exportChain(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) == 0 {
|
|
||||||
fmt.Println("require file name: admin.exportChain(filename)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) printBlock(call otto.FunctionCall) otto.Value {
|
|
||||||
block, err := js.getBlock(call)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(block)
|
|
||||||
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
|
|
||||||
block, err := js.getBlock(call)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
statedb := state.New(block.Root(), js.ethereum.StateDb())
|
|
||||||
dump := statedb.RawDump()
|
|
||||||
v, _ := call.Otto.ToValue(dump)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) waitForBlocks(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) > 2 {
|
|
||||||
fmt.Println("requires 0, 1 or 2 arguments: admin.debug.waitForBlock(minHeight, timeout)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
var n, timeout int64
|
|
||||||
var timer <-chan time.Time
|
|
||||||
var height *big.Int
|
|
||||||
var err error
|
|
||||||
args := len(call.ArgumentList)
|
|
||||||
if args == 2 {
|
|
||||||
timeout, err = call.Argument(1).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
timer = time.NewTimer(time.Duration(timeout) * time.Second).C
|
|
||||||
}
|
|
||||||
if args >= 1 {
|
|
||||||
n, err = call.Argument(0).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
height = big.NewInt(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args == 0 {
|
|
||||||
height = js.xeth.CurrentBlock().Number()
|
|
||||||
height.Add(height, common.Big1)
|
|
||||||
}
|
|
||||||
|
|
||||||
wait := js.wait
|
|
||||||
js.wait <- height
|
|
||||||
select {
|
|
||||||
case <-timer:
|
|
||||||
// if times out make sure the xeth loop does not block
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case wait <- nil:
|
|
||||||
case <-wait:
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
case height = <-wait:
|
|
||||||
}
|
|
||||||
v, _ := call.Otto.ToValue(height.Uint64())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) sleep(call otto.FunctionCall) otto.Value {
|
|
||||||
sec, err := call.Argument(0).ToInteger()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
time.Sleep(time.Duration(sec) * time.Second)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) setSolc(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) != 1 {
|
|
||||||
fmt.Println("needs 1 argument: admin.contractInfo.setSolc(solcPath)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
solcPath, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
solc, err := js.xeth.SetSolc(solcPath)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
fmt.Println(solc.Info())
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) register(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) != 4 {
|
|
||||||
fmt.Println("requires 4 arguments: admin.contractInfo.register(fromaddress, contractaddress, contract, filename)")
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
sender, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
address, err := call.Argument(1).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
raw, err := call.Argument(2).Export()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
jsonraw, err := json.Marshal(raw)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
var contract compiler.Contract
|
|
||||||
err = json.Unmarshal(jsonraw, &contract)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
filename, err := call.Argument(3).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
contenthash, err := compiler.ExtractInfo(&contract, filename)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
// sender and contract address are passed as hex strings
|
|
||||||
codeb := js.xeth.CodeAtBytes(address)
|
|
||||||
codehash := common.BytesToHash(crypto.Sha3(codeb))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
registry := resolver.New(js.xeth)
|
|
||||||
|
|
||||||
_, err = registry.RegisterContentHash(common.HexToAddress(sender), codehash, contenthash)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
v, _ := call.Otto.ToValue(contenthash.Hex())
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) registerUrl(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) != 3 {
|
|
||||||
fmt.Println("requires 3 arguments: admin.contractInfo.register(fromaddress, contenthash, filename)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
sender, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
contenthash, err := call.Argument(1).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
url, err := call.Argument(2).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
registry := resolver.New(js.xeth)
|
|
||||||
|
|
||||||
_, err = registry.RegisterUrl(common.HexToAddress(sender), common.HexToHash(contenthash), url)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) getContractInfo(call otto.FunctionCall) otto.Value {
|
|
||||||
if len(call.ArgumentList) != 1 {
|
|
||||||
fmt.Println("requires 1 argument: admin.contractInfo.register(contractaddress)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
addr, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
infoDoc, err := natspec.FetchDocsForContract(addr, js.xeth, ds)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
var info compiler.ContractInfo
|
|
||||||
err = json.Unmarshal(infoDoc, &info)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.UndefinedValue()
|
|
||||||
}
|
|
||||||
v, _ := call.Otto.ToValue(info)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) startNatSpec(call otto.FunctionCall) otto.Value {
|
|
||||||
js.ethereum.NatSpec = true
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) stopNatSpec(call otto.FunctionCall) otto.Value {
|
|
||||||
js.ethereum.NatSpec = false
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (js *jsre) newRegistry(call otto.FunctionCall) otto.Value {
|
|
||||||
|
|
||||||
if len(call.ArgumentList) != 1 {
|
|
||||||
fmt.Println("requires 1 argument: admin.contractInfo.newRegistry(adminaddress)")
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
addr, err := call.Argument(0).ToString()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
registry := resolver.New(js.xeth)
|
|
||||||
err = registry.CreateContracts(common.HexToAddress(addr))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
return otto.FalseValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
return otto.TrueValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// internal transaction type which will allow us to resend transactions using `eth.resend`
|
|
||||||
type tx struct {
|
|
||||||
tx *types.Transaction
|
|
||||||
|
|
||||||
To string
|
|
||||||
From string
|
|
||||||
Nonce string
|
|
||||||
Value string
|
|
||||||
Data string
|
|
||||||
GasLimit string
|
|
||||||
GasPrice string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTx(t *types.Transaction) *tx {
|
|
||||||
from, _ := t.From()
|
|
||||||
var to string
|
|
||||||
if t := t.To(); t != nil {
|
|
||||||
to = t.Hex()
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tx{
|
|
||||||
tx: t,
|
|
||||||
To: to,
|
|
||||||
From: from.Hex(),
|
|
||||||
Value: t.Amount.String(),
|
|
||||||
Nonce: strconv.Itoa(int(t.Nonce())),
|
|
||||||
Data: "0x" + common.Bytes2Hex(t.Data()),
|
|
||||||
GasLimit: t.GasLimit.String(),
|
|
||||||
GasPrice: t.GasPrice().String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -392,8 +392,9 @@ func StartIPC(eth *eth.Ethereum, ctx *cli.Context) error {
|
||||||
web3Api := api.NewWeb3(xeth, codec)
|
web3Api := api.NewWeb3(xeth, codec)
|
||||||
ethApi := api.NewEth(xeth, codec)
|
ethApi := api.NewEth(xeth, codec)
|
||||||
netApi := api.NewNet(xeth, codec)
|
netApi := api.NewNet(xeth, codec)
|
||||||
|
minerApi := api.NewMiner(eth, codec)
|
||||||
|
|
||||||
return comms.StartIpc(config, codec, web3Api, ethApi, netApi)
|
return comms.StartIpc(config, codec, web3Api, ethApi, netApi, minerApi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartPProf(ctx *cli.Context) {
|
func StartPProf(ctx *cli.Context) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/pow"
|
"github.com/ethereum/go-ethereum/pow"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAX_EXTRA_DATA_SIZE = 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
|
|
@ -126,8 +131,13 @@ func (self *Miner) HashRate() int64 {
|
||||||
return self.pow.GetHashrate()
|
return self.pow.GetHashrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) SetExtra(extra []byte) {
|
func (self *Miner) SetExtra(extra []byte) error {
|
||||||
|
if len(extra) > MAX_EXTRA_DATA_SIZE {
|
||||||
|
return fmt.Errorf("Miner extra data cannot exceed %d bytes", MAX_EXTRA_DATA_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
self.worker.extra = extra
|
self.worker.extra = extra
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) PendingState() *state.StateDB {
|
func (self *Miner) PendingState() *state.StateDB {
|
||||||
|
|
|
||||||
48
rpc/api/admin.go
Normal file
48
rpc/api/admin.go
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
ethereum "github.com/ethereum/go-ethereum/eth"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AdminVersion = "1.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// mapping between methods and handlers
|
||||||
|
AdminMapping = map[string]adminhandler{
|
||||||
|
//"admin_startMiner": (*admin).StartMiner,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// admin callback handler
|
||||||
|
type adminhandler func(*admin, *shared.Request) (interface{}, error)
|
||||||
|
|
||||||
|
// admin api provider
|
||||||
|
type admin struct {
|
||||||
|
ethereum ethereum.Ethereum
|
||||||
|
methods map[string]adminhandler
|
||||||
|
codec codec.ApiCoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new admin api instance
|
||||||
|
func NewAdmin(ethereum ethereum.Ethereum, coder codec.Codec) *admin {
|
||||||
|
return &admin{
|
||||||
|
ethereum: ethereum,
|
||||||
|
methods: AdminMapping,
|
||||||
|
codec: coder.New(nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collection with supported methods
|
||||||
|
func (self *admin) Methods() []string {
|
||||||
|
methods := make([]string, len(self.methods))
|
||||||
|
i := 0
|
||||||
|
for k := range self.methods {
|
||||||
|
methods[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return methods
|
||||||
|
}
|
||||||
1
rpc/api/admin_args.go
Normal file
1
rpc/api/admin_args.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import "github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
"github.com/ethereum/go-ethereum/rpc/shared"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Descriptor for all API implementations
|
// Descriptor for all API implementations
|
||||||
type Ethereum interface {
|
type Ethereum interface {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package api
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type NotImplementedError struct {
|
|
||||||
Method string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *NotImplementedError) Error() string {
|
|
||||||
return fmt.Sprintf("%s method not implemented", e.Method)
|
|
||||||
}
|
|
||||||
835
rpc/api/eth_args.go
Normal file
835
rpc/api/eth_args.go
Normal file
|
|
@ -0,0 +1,835 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultLogLimit = 100
|
||||||
|
defaultLogOffset = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetBalanceArgs struct {
|
||||||
|
Address string
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStorageArgs struct {
|
||||||
|
Address string
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStorageAtArgs struct {
|
||||||
|
Address string
|
||||||
|
BlockNumber int64
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
keystr, ok := obj[1].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("key", "not a string")
|
||||||
|
}
|
||||||
|
args.Key = keystr
|
||||||
|
|
||||||
|
if len(obj) > 2 {
|
||||||
|
if err := blockHeight(obj[2], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTxCountArgs struct {
|
||||||
|
Address string
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type HashArgs struct {
|
||||||
|
Hash string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *HashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("hash", "not a string")
|
||||||
|
}
|
||||||
|
args.Hash = arg0
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockNumArg struct {
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetDataArgs struct {
|
||||||
|
Address string
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
addstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("address", "not a string")
|
||||||
|
}
|
||||||
|
args.Address = addstr
|
||||||
|
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NewSignArgs struct {
|
||||||
|
From string
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []json.RawMessage
|
||||||
|
var ext struct {
|
||||||
|
From string
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode byte slice to array of RawMessages
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for sufficient params
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 0th RawMessage to temporary struct
|
||||||
|
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ext.From) == 0 {
|
||||||
|
return shared.NewValidationError("from", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ext.Data) == 0 {
|
||||||
|
return shared.NewValidationError("data", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.From = ext.From
|
||||||
|
args.Data = ext.Data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NewTxArgs struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Nonce *big.Int
|
||||||
|
Value *big.Int
|
||||||
|
Gas *big.Int
|
||||||
|
GasPrice *big.Int
|
||||||
|
Data string
|
||||||
|
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []json.RawMessage
|
||||||
|
var ext struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Nonce interface{}
|
||||||
|
Value interface{}
|
||||||
|
Gas interface{}
|
||||||
|
GasPrice interface{}
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode byte slice to array of RawMessages
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for sufficient params
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 0th RawMessage to temporary struct
|
||||||
|
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ext.From) == 0 {
|
||||||
|
return shared.NewValidationError("from", "is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.From = ext.From
|
||||||
|
args.To = ext.To
|
||||||
|
args.Data = ext.Data
|
||||||
|
|
||||||
|
var num *big.Int
|
||||||
|
if ext.Nonce != nil {
|
||||||
|
num, err = numString(ext.Nonce)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Nonce = num
|
||||||
|
|
||||||
|
if ext.Value == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
num, err = numString(ext.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Value = num
|
||||||
|
|
||||||
|
num = nil
|
||||||
|
if ext.Gas == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.Gas); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Gas = num
|
||||||
|
|
||||||
|
num = nil
|
||||||
|
if ext.GasPrice == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.GasPrice); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.GasPrice = num
|
||||||
|
|
||||||
|
// Check for optional BlockNumber param
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SourceArgs struct {
|
||||||
|
Source string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("source code", "not a string")
|
||||||
|
}
|
||||||
|
args.Source = arg0
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CallArgs struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Value *big.Int
|
||||||
|
Gas *big.Int
|
||||||
|
GasPrice *big.Int
|
||||||
|
Data string
|
||||||
|
|
||||||
|
BlockNumber int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []json.RawMessage
|
||||||
|
var ext struct {
|
||||||
|
From string
|
||||||
|
To string
|
||||||
|
Value interface{}
|
||||||
|
Gas interface{}
|
||||||
|
GasPrice interface{}
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode byte slice to array of RawMessages
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for sufficient params
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode 0th RawMessage to temporary struct
|
||||||
|
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
args.From = ext.From
|
||||||
|
|
||||||
|
if len(ext.To) == 0 {
|
||||||
|
return shared.NewValidationError("to", "is required")
|
||||||
|
}
|
||||||
|
args.To = ext.To
|
||||||
|
|
||||||
|
var num *big.Int
|
||||||
|
if ext.Value == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.Value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Value = num
|
||||||
|
|
||||||
|
if ext.Gas == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.Gas); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Gas = num
|
||||||
|
|
||||||
|
if ext.GasPrice == nil {
|
||||||
|
num = big.NewInt(0)
|
||||||
|
} else {
|
||||||
|
if num, err = numString(ext.GasPrice); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.GasPrice = num
|
||||||
|
|
||||||
|
args.Data = ext.Data
|
||||||
|
|
||||||
|
// Check for optional BlockNumber param
|
||||||
|
if len(obj) > 1 {
|
||||||
|
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.BlockNumber = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type HashIndexArgs struct {
|
||||||
|
Hash string
|
||||||
|
Index int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg0, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("hash", "not a string")
|
||||||
|
}
|
||||||
|
args.Hash = arg0
|
||||||
|
|
||||||
|
arg1, ok := obj[1].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("index", "not a string")
|
||||||
|
}
|
||||||
|
args.Index = common.Big(arg1).Int64()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockNumIndexArgs struct {
|
||||||
|
BlockNumber int64
|
||||||
|
Index int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var arg1 *big.Int
|
||||||
|
if arg1, err = numString(obj[1]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Index = arg1.Int64()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBlockByHashArgs struct {
|
||||||
|
BlockHash string
|
||||||
|
IncludeTxs bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
argstr, ok := obj[0].(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError("blockHash", "not a string")
|
||||||
|
}
|
||||||
|
args.BlockHash = argstr
|
||||||
|
|
||||||
|
args.IncludeTxs = obj[1].(bool)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBlockByNumberArgs struct {
|
||||||
|
BlockNumber int64
|
||||||
|
IncludeTxs bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 2 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
args.IncludeTxs = obj[1].(bool)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockFilterArgs struct {
|
||||||
|
Earliest int64
|
||||||
|
Latest int64
|
||||||
|
Address []string
|
||||||
|
Topics [][]string
|
||||||
|
Skip int
|
||||||
|
Max int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []struct {
|
||||||
|
FromBlock interface{} `json:"fromBlock"`
|
||||||
|
ToBlock interface{} `json:"toBlock"`
|
||||||
|
Limit interface{} `json:"limit"`
|
||||||
|
Offset interface{} `json:"offset"`
|
||||||
|
Address interface{} `json:"address"`
|
||||||
|
Topics interface{} `json:"topics"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// args.Earliest, err = toNumber(obj[0].ToBlock)
|
||||||
|
// if err != nil {
|
||||||
|
// return shared.NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
|
||||||
|
// }
|
||||||
|
// args.Latest, err = toNumber(obj[0].FromBlock)
|
||||||
|
// if err != nil {
|
||||||
|
// return shared.NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
|
||||||
|
|
||||||
|
var num int64
|
||||||
|
var numBig *big.Int
|
||||||
|
|
||||||
|
// if blank then latest
|
||||||
|
if obj[0].FromBlock == nil {
|
||||||
|
num = -1
|
||||||
|
} else {
|
||||||
|
if err := blockHeight(obj[0].FromBlock, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if -2 or other "silly" number, use latest
|
||||||
|
if num < 0 {
|
||||||
|
args.Earliest = -1 //latest block
|
||||||
|
} else {
|
||||||
|
args.Earliest = num
|
||||||
|
}
|
||||||
|
|
||||||
|
// if blank than latest
|
||||||
|
if obj[0].ToBlock == nil {
|
||||||
|
num = -1
|
||||||
|
} else {
|
||||||
|
if err := blockHeight(obj[0].ToBlock, &num); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Latest = num
|
||||||
|
|
||||||
|
if obj[0].Limit == nil {
|
||||||
|
numBig = big.NewInt(defaultLogLimit)
|
||||||
|
} else {
|
||||||
|
if numBig, err = numString(obj[0].Limit); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Max = int(numBig.Int64())
|
||||||
|
|
||||||
|
if obj[0].Offset == nil {
|
||||||
|
numBig = big.NewInt(defaultLogOffset)
|
||||||
|
} else {
|
||||||
|
if numBig, err = numString(obj[0].Offset); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Skip = int(numBig.Int64())
|
||||||
|
|
||||||
|
if obj[0].Address != nil {
|
||||||
|
marg, ok := obj[0].Address.([]interface{})
|
||||||
|
if ok {
|
||||||
|
v := make([]string, len(marg))
|
||||||
|
for i, arg := range marg {
|
||||||
|
argstr, ok := arg.(string)
|
||||||
|
if !ok {
|
||||||
|
return shared.NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string")
|
||||||
|
}
|
||||||
|
v[i] = argstr
|
||||||
|
}
|
||||||
|
args.Address = v
|
||||||
|
} else {
|
||||||
|
argstr, ok := obj[0].Address.(string)
|
||||||
|
if ok {
|
||||||
|
v := make([]string, 1)
|
||||||
|
v[0] = argstr
|
||||||
|
args.Address = v
|
||||||
|
} else {
|
||||||
|
return shared.NewInvalidTypeError("address", "is not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if obj[0].Topics != nil {
|
||||||
|
other, ok := obj[0].Topics.([]interface{})
|
||||||
|
if ok {
|
||||||
|
topicdbl := make([][]string, len(other))
|
||||||
|
for i, iv := range other {
|
||||||
|
if argstr, ok := iv.(string); ok {
|
||||||
|
// Found a string, push into first element of array
|
||||||
|
topicsgl := make([]string, 1)
|
||||||
|
topicsgl[0] = argstr
|
||||||
|
topicdbl[i] = topicsgl
|
||||||
|
} else if argarray, ok := iv.([]interface{}); ok {
|
||||||
|
// Found an array of other
|
||||||
|
topicdbl[i] = make([]string, len(argarray))
|
||||||
|
for j, jv := range argarray {
|
||||||
|
if v, ok := jv.(string); ok {
|
||||||
|
topicdbl[i][j] = v
|
||||||
|
} else if jv == nil {
|
||||||
|
topicdbl[i][j] = ""
|
||||||
|
} else {
|
||||||
|
return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if iv == nil {
|
||||||
|
topicdbl[i] = []string{""}
|
||||||
|
} else {
|
||||||
|
return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.Topics = topicdbl
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return shared.NewInvalidTypeError("topic", "is not a string or array")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterIdArgs struct {
|
||||||
|
Id int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 1 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var num *big.Int
|
||||||
|
if num, err = numString(obj[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args.Id = int(num.Int64())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type LogRes struct {
|
||||||
|
Address *hexdata `json:"address"`
|
||||||
|
Topics []*hexdata `json:"topics"`
|
||||||
|
Data *hexdata `json:"data"`
|
||||||
|
BlockNumber *hexnum `json:"blockNumber"`
|
||||||
|
LogIndex *hexnum `json:"logIndex"`
|
||||||
|
BlockHash *hexdata `json:"blockHash"`
|
||||||
|
TransactionHash *hexdata `json:"transactionHash"`
|
||||||
|
TransactionIndex *hexnum `json:"transactionIndex"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogRes(log *state.Log) LogRes {
|
||||||
|
var l LogRes
|
||||||
|
l.Topics = make([]*hexdata, len(log.Topics))
|
||||||
|
for j, topic := range log.Topics {
|
||||||
|
l.Topics[j] = newHexData(topic)
|
||||||
|
}
|
||||||
|
l.Address = newHexData(log.Address)
|
||||||
|
l.Data = newHexData(log.Data)
|
||||||
|
l.BlockNumber = newHexNum(log.Number)
|
||||||
|
l.LogIndex = newHexNum(log.Index)
|
||||||
|
l.TransactionHash = newHexData(log.TxHash)
|
||||||
|
l.TransactionIndex = newHexNum(log.TxIndex)
|
||||||
|
l.BlockHash = newHexData(log.BlockHash)
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogsRes(logs state.Logs) (ls []LogRes) {
|
||||||
|
ls = make([]LogRes, len(logs))
|
||||||
|
|
||||||
|
for i, log := range logs {
|
||||||
|
ls[i] = NewLogRes(log)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHashesRes(hs []common.Hash) []string {
|
||||||
|
hashes := make([]string, len(hs))
|
||||||
|
|
||||||
|
for i, hash := range hs {
|
||||||
|
hashes[i] = hash.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashes
|
||||||
|
}
|
||||||
|
|
||||||
|
type SubmitWorkArgs struct {
|
||||||
|
Nonce uint64
|
||||||
|
Header string
|
||||||
|
Digest string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
var obj []interface{}
|
||||||
|
if err = json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) < 3 {
|
||||||
|
return shared.NewInsufficientParamsError(len(obj), 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
var objstr string
|
||||||
|
var ok bool
|
||||||
|
if objstr, ok = obj[0].(string); !ok {
|
||||||
|
return shared.NewInvalidTypeError("nonce", "not a string")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Nonce = common.String2Big(objstr).Uint64()
|
||||||
|
if objstr, ok = obj[1].(string); !ok {
|
||||||
|
return shared.NewInvalidTypeError("header", "not a string")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Header = objstr
|
||||||
|
|
||||||
|
if objstr, ok = obj[2].(string); !ok {
|
||||||
|
return shared.NewInvalidTypeError("digest", "not a string")
|
||||||
|
}
|
||||||
|
|
||||||
|
args.Digest = objstr
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
138
rpc/api/miner.go
Normal file
138
rpc/api/miner.go
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
ethereum "github.com/ethereum/go-ethereum/eth"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/codec"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MinerVersion = "1.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// mapping between methods and handlers
|
||||||
|
MinerMapping = map[string]minerhandler{
|
||||||
|
"miner_hashrate": (*miner).Hashrate,
|
||||||
|
"miner_makeDAG": (*miner).MakeDAG,
|
||||||
|
"miner_setExtra": (*miner).SetExtra,
|
||||||
|
"miner_setGasPrice": (*miner).SetGasPrice,
|
||||||
|
"miner_startAutoDAG": (*miner).StartAutoDAG,
|
||||||
|
"miner_start": (*miner).StartMiner,
|
||||||
|
"miner_stopAutoDAG": (*miner).StopAutoDAG,
|
||||||
|
"miner_stop": (*miner).StopMiner,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// miner callback handler
|
||||||
|
type minerhandler func(*miner, *shared.Request) (interface{}, error)
|
||||||
|
|
||||||
|
// miner api provider
|
||||||
|
type miner struct {
|
||||||
|
ethereum *ethereum.Ethereum
|
||||||
|
methods map[string]minerhandler
|
||||||
|
codec codec.ApiCoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new miner api instance
|
||||||
|
func NewMiner(ethereum *ethereum.Ethereum, coder codec.Codec) *miner {
|
||||||
|
return &miner{
|
||||||
|
ethereum: ethereum,
|
||||||
|
methods: MinerMapping,
|
||||||
|
codec: coder.New(nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute given request
|
||||||
|
func (self *miner) Execute(req *shared.Request) (interface{}, error) {
|
||||||
|
if callback, ok := self.methods[req.Method]; ok {
|
||||||
|
return callback(self, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, &shared.NotImplementedError{req.Method}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collection with supported methods
|
||||||
|
func (self *miner) Methods() []string {
|
||||||
|
methods := make([]string, len(self.methods))
|
||||||
|
i := 0
|
||||||
|
for k := range self.methods {
|
||||||
|
methods[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return methods
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) StartMiner(req *shared.Request) (interface{}, error) {
|
||||||
|
args := new(StartMinerArgs)
|
||||||
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if args.Threads == -1 { // (-1 is set in unmarshalljson when not specified in req)
|
||||||
|
args.Threads = self.ethereum.MinerThreads
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ethereum.StartAutoDAG()
|
||||||
|
err := self.ethereum.StartMining(args.Threads)
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) StopMiner(req *shared.Request) (interface{}, error) {
|
||||||
|
self.ethereum.StopMining()
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) Hashrate(req *shared.Request) (interface{}, error) {
|
||||||
|
return self.ethereum.Miner().HashRate(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) SetExtra(req *shared.Request) (interface{}, error) {
|
||||||
|
args := new(SetExtraArgs)
|
||||||
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err := self.ethereum.Miner().SetExtra([]byte(args.Data))
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) SetGasPrice(req *shared.Request) (interface{}, error) {
|
||||||
|
args := new(GasPriceArgs)
|
||||||
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ethereum.Miner().SetGasPrice(common.String2Big(args.Price))
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) StartAutoDAG(req *shared.Request) (interface{}, error) {
|
||||||
|
self.ethereum.StartAutoDAG()
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) StopAutoDAG(req *shared.Request) (interface{}, error) {
|
||||||
|
self.ethereum.StopAutoDAG()
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *miner) MakeDAG(req *shared.Request) (interface{}, error) {
|
||||||
|
args := new(MakeDAGArgs)
|
||||||
|
if err := self.codec.Decode(req.Params, &args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err := ethash.MakeDAG(args.BlockNumber, "")
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
47
rpc/api/miner_args.go
Normal file
47
rpc/api/miner_args.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package api
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc/shared"
|
||||||
|
"math/big"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StartMinerArgs struct {
|
||||||
|
Threads int `json:"threads"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (args *StartMinerArgs) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
fmt.Printf("b=%s\n", string(b))
|
||||||
|
var obj []interface{}
|
||||||
|
if err := json.Unmarshal(b, &obj); err != nil {
|
||||||
|
return shared.NewDecodeParamError(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(obj) == 0 {
|
||||||
|
args.Threads = -1
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var arg0 *big.Int
|
||||||
|
if arg0, err = numString(obj[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if arg0.Int64() >= 0 && arg0.Int64() <= 256 {
|
||||||
|
args.Threads = int(arg0.Int64())
|
||||||
|
}
|
||||||
|
|
||||||
|
return shared.NewValidationError("threads", "Must be in range [0...256]")
|
||||||
|
}
|
||||||
|
|
||||||
|
type SetExtraArgs struct {
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GasPriceArgs struct {
|
||||||
|
Price string `json:"price"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MakeDAGArgs struct {
|
||||||
|
BlockNumber uint64 `json:"blockNumber"`
|
||||||
|
}
|
||||||
1
rpc/api/types.go
Normal file
1
rpc/api/types.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
package api
|
||||||
|
|
@ -56,7 +56,7 @@ func (self *web3) Execute(req *shared.Request) (interface{}, error) {
|
||||||
return callback(self, req)
|
return callback(self, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, &NotImplementedError{req.Method}
|
return nil, &shared.NotImplementedError{req.Method}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version of the API this instance provides
|
// Version of the API this instance provides
|
||||||
|
|
|
||||||
5
rpc/api/web3_args.go
Normal file
5
rpc/api/web3_args.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
type Sha3Args struct {
|
||||||
|
Data string
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue