account bindings update, return format, and tests
This commit is contained in:
parent
72bf6a236a
commit
9272538432
|
@ -3,9 +3,12 @@ package main
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
errextra "github.com/pkg/errors"
|
||||
|
@ -23,17 +26,23 @@ func createAccount(password, keydir string) (string, string, error) {
|
|||
w := true
|
||||
accman := accounts.NewManager(keydir, scryptN, scryptP, sync)
|
||||
|
||||
// generate the account
|
||||
account, err := accman.NewAccount(password, w)
|
||||
if err != nil {
|
||||
return "", "", errextra.Wrap(err, "Account manager could not create the account")
|
||||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
|
||||
|
@ -42,7 +51,7 @@ func createAccount(password, keydir string) (string, string, error) {
|
|||
// unlockAccount unlocks an existing account for a certain duration and
|
||||
// inject the account as a whisper identity if the account was created as
|
||||
// a whisper enabled account
|
||||
func unlockAccount(address, password string) error {
|
||||
func unlockAccount(address, password string, seconds int) error {
|
||||
|
||||
if currentNode != nil {
|
||||
|
||||
|
@ -52,7 +61,7 @@ func unlockAccount(address, password string) error {
|
|||
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 {
|
||||
return errextra.Wrap(err, "Could not decrypt account")
|
||||
}
|
||||
|
@ -69,7 +78,7 @@ func unlockAccount(address, password string) error {
|
|||
// node running locally
|
||||
func createAndStartNode(datadir string) error {
|
||||
|
||||
currentNode := MakeNode(datadir)
|
||||
currentNode = MakeNode(datadir)
|
||||
if currentNode != nil {
|
||||
StartNode(currentNode)
|
||||
return nil
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
@ -11,37 +12,45 @@ func doCreateAccount(password, keydir *C.char) *C.char {
|
|||
// This is equivalent to creating an account from the command line,
|
||||
// just modified to handle the function arg passing
|
||||
address, pubKey, err := createAccount(C.GoString(password), C.GoString(keydir))
|
||||
out := fmt.Sprintf(`{
|
||||
"address": %s,
|
||||
"pubkey": %s,
|
||||
"error": %s
|
||||
}`, address, pubKey, err.Error())
|
||||
out := AccountInfo{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
Error: err.Error(),
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
return C.CString(out)
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
return C.CString(string(outBytes))
|
||||
|
||||
}
|
||||
|
||||
//export doUnlockAccount
|
||||
func doUnlockAccount(address, password *C.char) *C.char {
|
||||
func doUnlockAccount(address, password *C.char, seconds int) *C.char {
|
||||
// This is equivalent to unlocking an account from the command line,
|
||||
// just modified to unlock the account for the currently running geth node
|
||||
// based on the provided arguments
|
||||
err := unlockAccount(C.GoString(address), C.GoString(password))
|
||||
out := fmt.Sprintf("{\"error\": %s}", err.Error())
|
||||
err := unlockAccount(C.GoString(address), C.GoString(password), seconds)
|
||||
out := JSONError{
|
||||
Error: err.Error(),
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
return C.CString(out)
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
//export doStartNode
|
||||
func doStartNode(datadir *C.char) *C.char {
|
||||
// This starts a geth node with the given datadir
|
||||
err := createAndStartNode(C.GoString(datadir))
|
||||
out := fmt.Sprintf("{\"error\": %s}", err.Error())
|
||||
out := JSONError{
|
||||
Error: err.Error(),
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
return C.CString(out)
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
Loading…
Reference in New Issue