Merge branch 'node-object' into jail

This commit is contained in:
Roman Volosovskyi 2016-06-23 16:17:00 +03:00
commit 6f02c4cc3c
4 changed files with 96 additions and 20 deletions

View File

@ -3,9 +3,12 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"time"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
errextra "github.com/pkg/errors" errextra "github.com/pkg/errors"
@ -23,17 +26,23 @@ func createAccount(password, keydir string) (string, string, error) {
w := true w := true
accman := accounts.NewManager(keydir, scryptN, scryptP, sync) accman := accounts.NewManager(keydir, scryptN, scryptP, sync)
// generate the account
account, err := accman.NewAccount(password, w) account, err := accman.NewAccount(password, w)
if err != nil { if err != nil {
return "", "", errextra.Wrap(err, "Account manager could not create the account") return "", "", errextra.Wrap(err, "Account manager could not create the account")
} }
address := fmt.Sprintf("%x", account.Address) address := fmt.Sprintf("%x", account.Address)
key, err := crypto.LoadECDSA(account.File)
// recover the public key to return
keyContents, err := ioutil.ReadFile(account.File)
if err != nil { if err != nil {
return address, "", errextra.Wrap(err, "Could not load the key") return address, "", errextra.Wrap(err, "Could not load the key contents")
} }
pubKey := string(crypto.FromECDSAPub(&key.PublicKey)) key, err := accounts.DecryptKey(keyContents, password)
if err != nil {
return address, "", errextra.Wrap(err, "Could not recover the key")
}
pubKey := common.ToHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
return address, pubKey, nil return address, pubKey, nil
@ -42,7 +51,7 @@ func createAccount(password, keydir string) (string, string, error) {
// unlockAccount unlocks an existing account for a certain duration and // unlockAccount unlocks an existing account for a certain duration and
// inject the account as a whisper identity if the account was created as // inject the account as a whisper identity if the account was created as
// a whisper enabled account // a whisper enabled account
func unlockAccount(address, password string) error { func unlockAccount(address, password string, seconds int) error {
if currentNode != nil { if currentNode != nil {
@ -52,7 +61,7 @@ func unlockAccount(address, password string) error {
return errextra.Wrap(err, "Could not retrieve account from address") return errextra.Wrap(err, "Could not retrieve account from address")
} }
err = accman.Unlock(account, password) err = accman.TimedUnlock(account, password, time.Duration(seconds)*time.Second)
if err != nil { if err != nil {
return errextra.Wrap(err, "Could not decrypt account") return errextra.Wrap(err, "Could not decrypt account")
} }
@ -69,7 +78,7 @@ func unlockAccount(address, password string) error {
// node running locally // node running locally
func createAndStartNode(datadir string) error { func createAndStartNode(datadir string) error {
currentNode := MakeNode(datadir) currentNode = MakeNode(datadir)
if currentNode != nil { if currentNode != nil {
StartNode(currentNode) StartNode(currentNode)
return nil return nil

41
src/gethdep_test.go Normal file
View File

@ -0,0 +1,41 @@
package main
import (
"fmt"
"os"
"testing"
"time"
)
// TestAccountBindings makes sure we can create an account and subsequently
// unlock that account
func TestAccountBindings(t *testing.T) {
// create an account
address, _, err := createAccount("badpassword", ".ethereumtest/keystore")
if err != nil {
fmt.Println(err.Error())
t.Error("Test failed: could not create account")
}
// start geth node and wait for it to initialize
go createAndStartNode(".ethereumtest")
time.Sleep(5 * time.Second)
if currentNode == nil {
t.Error("Test failed: could not start geth node")
}
// unlock the created account
err = unlockAccount(address, "badpassword", 10)
if err != nil {
fmt.Println(err)
t.Error("Test failed: could not unlock account")
}
// clean up
err = os.RemoveAll(".ethereumtest")
if err != nil {
t.Error("Test failed: could not clean up temporary datadir")
}
}

View File

@ -2,42 +2,57 @@ package main
import "C" import "C"
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
) )
//export doCreateAccount //export doCreateAccount
func doCreateAccount(password, keydir *C.char) (*C.char, *C.char, C.int) { func doCreateAccount(password, keydir *C.char) *C.char {
// This is equivalent to creating an account from the command line, // This is equivalent to creating an account from the command line,
// just modified to handle the function arg passing // just modified to handle the function arg passing
address, pubKey, err := createAccount(C.GoString(password), C.GoString(keydir)) address, pubKey, err := createAccount(C.GoString(password), C.GoString(keydir))
out := AccountInfo{
Address: address,
PubKey: pubKey,
Error: err.Error(),
}
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
return C.CString(""), C.CString(""), -1
} }
return C.CString(address), C.CString(pubKey), 0 outBytes, _ := json.Marshal(&out)
return C.CString(string(outBytes))
} }
//export doUnlockAccount //export doUnlockAccount
func doUnlockAccount(address, password *C.char) C.int { func doUnlockAccount(address, password *C.char, seconds int) *C.char {
// This is equivalent to unlocking an account from the command line, // This is equivalent to unlocking an account from the command line,
// just modified to unlock the account for the currently running geth node // just modified to unlock the account for the currently running geth node
// based on the provided arguments // based on the provided arguments
if err := unlockAccount(C.GoString(address), C.GoString(password)); err != nil { err := unlockAccount(C.GoString(address), C.GoString(password), seconds)
fmt.Fprintln(os.Stderr, err) out := JSONError{
return -1 Error: err.Error(),
} }
return 0 if err != nil {
fmt.Fprintln(os.Stderr, err)
}
outBytes, _ := json.Marshal(&out)
return C.CString(string(outBytes))
} }
//export doStartNode //export doStartNode
func doStartNode(datadir *C.char) C.int { func doStartNode(datadir *C.char) *C.char {
// This starts a geth node with the given datadir // This starts a geth node with the given datadir
if err := createAndStartNode(C.GoString(datadir)); err != nil { err := createAndStartNode(C.GoString(datadir))
fmt.Fprintln(os.Stderr, err) out := JSONError{
return -1 Error: err.Error(),
} }
return 0 if err != nil {
fmt.Fprintln(os.Stderr, err)
}
outBytes, _ := json.Marshal(&out)
return C.CString(string(outBytes))
} }
//export parse //export parse

11
src/types.go Normal file
View File

@ -0,0 +1,11 @@
package main
type AccountInfo struct {
Address string `json:"address"`
PubKey string `json:"pubkey"`
Error string `json:"error"`
}
type JSONError struct {
Error string `json:"error"`
}