[node.sh] added first test case as well as some print message for debugging

pull/3219/head
Jacky Wang 4 years ago
parent a5da06f382
commit 0a13765a51
No known key found for this signature in database
GPG Key ID: 1085CE5F4FF5842C
  1. 9
      cmd/harmony/blsloader/console.go
  2. 77
      cmd/harmony/blsloader/console_test.go
  3. 3
      cmd/harmony/blsloader/helper.go
  4. 5
      cmd/harmony/blsloader/loader.go
  5. 271
      cmd/harmony/blsloader/loader_test.go
  6. 3
      cmd/harmony/blsloader/passProvider.go
  7. 1
      cmd/harmony/blsloader/testdata/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  8. 1
      cmd/harmony/blsloader/testdata/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  9. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  10. 0
      cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass
  11. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  12. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass
  13. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  14. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass
  15. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  16. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass
  17. 2
      cmd/harmony/blsloader/utils.go

@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"os"
"strings"
"syscall"
"golang.org/x/crypto/ssh/terminal"
@ -27,12 +28,16 @@ func (console *stdConsole) readPassword() (string, error) {
if err != nil {
return "", err
}
return string(b), nil
return strings.TrimSpace(string(b)), nil
}
func (console *stdConsole) readln() (string, error) {
reader := bufio.NewReader(os.Stdin)
return reader.ReadString('\n')
raw, err := reader.ReadString('\n')
if err != nil {
return "", err
}
return strings.TrimSpace(raw), nil
}
func (console *stdConsole) print(a ...interface{}) {

@ -0,0 +1,77 @@
package blsloader
import (
"errors"
"fmt"
"time"
)
func setTestConsole(tc *testConsole) {
console = tc
}
type testConsole struct {
In chan string
Out chan string
}
func newTestConsole() *testConsole {
in := make(chan string, 100)
out := make(chan string, 100)
return &testConsole{in, out}
}
func (tc *testConsole) readPassword() (string, error) {
return tc.readln()
}
func (tc *testConsole) readln() (string, error) {
select {
case <-time.After(10 * time.Second):
return "", errors.New("timed out")
case <-tc.In:
msg, ok := <-tc.In
if !ok {
return "", errors.New("in channel closed")
}
return msg, nil
}
}
func (tc *testConsole) print(a ...interface{}) {
msg := fmt.Sprint(a...)
tc.Out <- msg
}
func (tc *testConsole) println(a ...interface{}) {
msg := fmt.Sprintln(a...)
tc.Out <- msg
}
func (tc *testConsole) printf(format string, a ...interface{}) {
msg := fmt.Sprintf(format, a...)
tc.Out <- msg
}
func (tc *testConsole) checkClean() (bool, string) {
select {
case msg := <-tc.In:
return false, "extra in message: " + msg
case msg := <-tc.Out:
return false, "extra out message: " + msg
default:
return true, ""
}
}
func (tc *testConsole) checkOutput(timeout time.Duration, checkFunc func(string) error) error {
if timeout == 0 {
timeout = 10 * time.Second
}
select {
case <-time.After(timeout):
return errors.New("timed out")
case msg := <-tc.Out:
return checkFunc(msg)
}
}

@ -26,12 +26,15 @@ type basicSingleBlsLoader struct {
func (loader *basicSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
providers, err := loader.getPassProviders()
if err != nil {
fmt.Println("not loaded 1")
return multibls.PrivateKeys{}, err
}
secretKey, err := loadBasicKey(loader.blsKeyFile, providers)
if err != nil {
fmt.Println("not loaded 2")
return multibls.PrivateKeys{}, err
}
fmt.Println("loaded secret key")
return multibls.GetPrivateKeys(secretKey), nil
}

@ -9,8 +9,10 @@ import (
)
func LoadKeys(cfg Config) (multibls.PrivateKeys, error) {
fmt.Println("start")
cfg.applyDefault()
if err := cfg.validate(); err != nil {
fmt.Println("validate")
return multibls.PrivateKeys{}, err
}
helper, err := getHelper(cfg)
@ -108,15 +110,18 @@ func (cfg *Config) getKmsProviderConfig() kmsProviderConfig {
}
func getHelper(cfg Config) (loadHelper, error) {
fmt.Println("getting helper")
switch {
case stringIsSet(cfg.BlsKeyFile):
switch filepath.Ext(*cfg.BlsKeyFile) {
case basicKeyExt:
fmt.Println("basic")
return &basicSingleBlsLoader{
blsKeyFile: *cfg.BlsKeyFile,
passProviderConfig: cfg.getPassProviderConfig(),
}, nil
case kmsKeyExt:
fmt.Println("kms")
return &kmsSingleBlsLoader{
blsKeyFile: *cfg.BlsKeyFile,
kmsProviderConfig: cfg.getKmsProviderConfig(),

@ -0,0 +1,271 @@
package blsloader
import (
"errors"
"fmt"
"strings"
"sync"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/multibls"
)
type testKey struct {
publicKey string
privateKey string
passphrase string
passFile string
path string
}
// validTestKeys are keys with valid password and valid .pass file
var validTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
passFile: "testData/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "testData/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "testData/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "testData/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
// emptyPassTestKeys are keys with valid password but empty .pass file
var emptyPassTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
path: "testData/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
path: "testData/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
// wrongPassTestKeys are keys with wrong pass file and wrong passphrase
var wrongPassTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "evil harmony",
passFile: "testData/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "testData/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "testData/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "testData/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
func TestLoadKeys_SingleBls_File(t *testing.T) {
tests := []struct {
cfg Config
inputs []string
expOutputs []string
expPubKeys []string
expErr error
}{
{
// load the default pass file
cfg: Config{
BlsKeyFile: &validTestKeys[0].path,
PassSrcType: PassSrcFile,
},
inputs: []string{},
expOutputs: []string{},
expPubKeys: []string{validTestKeys[0].publicKey},
},
}
for i, test := range tests {
ts := &testSuite{
cfg: test.cfg,
inputs: test.inputs,
expOutputs: test.expOutputs,
expErr: test.expErr,
expPubKeys: test.expPubKeys,
}
ts.init()
ts.process()
fmt.Println(111)
if err := ts.checkResult(); err != nil {
t.Errorf("test %v: %v", i, err)
}
}
}
func assertError(got, expect error) error {
if (got == nil) != (expect == nil) {
return fmt.Errorf("unexpected error [%v] / [%v]", got, expect)
}
if (got == nil) || (expect == nil) {
return nil
}
if !strings.Contains(got.Error(), expect.Error()) {
return fmt.Errorf("unexpected error [%v] / [%v]", got, expect)
}
return nil
}
type testSuite struct {
cfg Config
inputs []string
expOutputs []string
expPubKeys []string
expErr error
gotKeys multibls.PrivateKeys
gotOutputs []string
timeout time.Duration
console *testConsole
gotErr error // err returned from load key
errC chan error
wg sync.WaitGroup
}
func (ts *testSuite) init() {
ts.gotOutputs = make([]string, 0, len(ts.expOutputs))
ts.console = newTestConsole()
setTestConsole(ts.console)
ts.timeout = 1 * time.Second
ts.errC = make(chan error, 3)
}
func (ts *testSuite) process() {
ts.wg.Add(3)
go ts.threadedLoadOutputs()
go ts.threadedFeedConsoleInputs()
go ts.threadLoadKeys()
ts.wg.Wait()
}
func (ts *testSuite) checkResult() error {
if err := assertError(ts.gotErr, ts.expErr); err != nil {
return err
}
select {
case err := <-ts.errC:
return err
default:
}
if isClean, msg := ts.console.checkClean(); !isClean {
return fmt.Errorf("console not clean: %v", msg)
}
if ts.expErr != nil {
return nil
}
if err := ts.checkKeys(); err != nil {
return err
}
return nil
}
func (ts *testSuite) checkOutputs() error {
if len(ts.gotOutputs) != len(ts.expOutputs) {
return fmt.Errorf("output size not expected: %v / %v", len(ts.gotOutputs), len(ts.expOutputs))
}
for i, gotOutput := range ts.gotOutputs {
expOutput := ts.expOutputs[i]
if gotOutput != expOutput {
return fmt.Errorf("%vth output unexpected: [%v] / [%v]", i, gotOutput, expOutput)
}
}
return nil
}
func (ts *testSuite) checkKeys() error {
if len(ts.expPubKeys) != len(ts.gotKeys) {
return fmt.Errorf("loaded key size not expected: %v / %v", len(ts.gotKeys), len(ts.expPubKeys))
}
expKeyMap := make(map[bls.SerializedPublicKey]struct{})
for _, pubKeyStr := range ts.expPubKeys {
pubKey := pubStrToPubBytes(pubKeyStr)
if _, exist := expKeyMap[pubKey]; exist {
return fmt.Errorf("duplicate expect pubkey %x", pubKey)
}
expKeyMap[pubKey] = struct{}{}
}
gotVisited := make(map[bls.SerializedPublicKey]struct{})
for _, gotPubWrapper := range ts.gotKeys.GetPublicKeys() {
pubKey := gotPubWrapper.Bytes
if _, exist := gotVisited[pubKey]; exist {
return fmt.Errorf("duplicate got pubkey %x", pubKey)
}
if _, exist := expKeyMap[pubKey]; !exist {
return fmt.Errorf("got pubkey not found in expect %x", pubKey)
}
}
return nil
}
func (ts *testSuite) threadLoadKeys() {
defer ts.wg.Done()
ts.gotKeys, ts.gotErr = LoadKeys(ts.cfg)
return
}
func (ts *testSuite) threadedFeedConsoleInputs() {
defer ts.wg.Done()
i := 0
for i < len(ts.inputs) {
select {
case ts.console.In <- ts.inputs[i]:
i += 1
case <-time.After(ts.timeout):
ts.errC <- errors.New("feed inputs timed out")
return
}
}
}
func (ts *testSuite) threadedLoadOutputs() {
defer ts.wg.Done()
var (
i = 0
)
for i < len(ts.expOutputs) {
select {
case got := <-ts.console.Out:
ts.gotOutputs = append(ts.gotOutputs, got)
i++
case <-time.After(ts.timeout):
ts.errC <- errors.New("load outputs timed out")
return
}
}
}
func pubStrToPubBytes(str string) bls.SerializedPublicKey {
b := common.Hex2Bytes(str)
var pubKey bls.SerializedPublicKey
copy(pubKey[:], b)
return pubKey
}

@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
)
// passProviderConfig is the data structure of passProviders config
@ -120,7 +121,7 @@ func readPassFromFile(file string) (string, error) {
if err != nil {
return "", err
}
return string(b), nil
return strings.TrimSpace(string(b)), nil
}
// dirPassProvider provide the all bls password available in the directory.

@ -0,0 +1 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -0,0 +1 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -0,0 +1 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -0,0 +1 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -0,0 +1 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -0,0 +1 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -28,6 +28,7 @@ func loadBasicKey(blsKeyFile string, pps []passProvider) (*bls_core.SecretKey, e
secretKey, err := loadBasicKeyWithProvider(blsKeyFile, pp)
if err != nil {
console.println(err)
return nil, err
}
return secretKey, nil
}
@ -39,6 +40,7 @@ func loadBasicKeyWithProvider(blsKeyFile string, pp passProvider) (*bls_core.Sec
if err != nil {
return nil, errors.Wrapf(err, "unable to get passphrase from %s", pp.toStr())
}
fmt.Printf("password: %s\n", pass)
secretKey, err := blsgen.LoadBLSKeyWithPassPhrase(blsKeyFile, pass)
if err != nil {
return nil, errors.Wrapf(err, "unable to decrypt bls key with %s\n", pp.toStr())

Loading…
Cancel
Save