Skip to content

Commit

Permalink
testutils
Browse files Browse the repository at this point in the history
  • Loading branch information
lochjin committed Dec 18, 2023
1 parent db10ce4 commit 1c8a27b
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 158 deletions.
6 changes: 0 additions & 6 deletions common/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,6 @@ func MustHexToHash(i string) Hash {
return nh
}

// convert hex string to a hash pointer. Must means it panics for invalid input.
func MustHexToHashPointer(i string) *Hash {
nh := MustHexToHash(i)
return &nh
}

// convert hex string to a byte-reversed hash, Must means it panics for invalid input.
func MustHexToDecodedHash(i string) Hash {
h, err := NewHashFromStr(i)
Expand Down
9 changes: 8 additions & 1 deletion services/address/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@ package address

import (
"encoding/hex"
"github.com/Qitmeer/qng/params"
"github.com/Qitmeer/qng/testutils/simulator/testprivatekey"
"testing"
)

func TestNewAddresses(t *testing.T) {
privateKeyHex := "fff2cefe258ca60ae5f5abec99b5d63e2a561c40d784ee50b04eddf8efc84b0d"
params.ActiveNetParams = &params.PrivNetParam
pb, err := testprivatekey.NewBuilder(0)
if err != nil {
t.Fatal(err)
}
privateKeyHex := hex.EncodeToString(pb.Get(0))
privateKey, addr, eaddr, err := NewAddresses(privateKeyHex)
if err != nil {
t.Fatal(err)
Expand Down
1 change: 1 addition & 0 deletions testutils/simulator/evm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package simulator
103 changes: 84 additions & 19 deletions testutils/simulator/mocknode.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package simulator

import (
"fmt"
"github.com/Qitmeer/qng/common/system"
"github.com/Qitmeer/qng/config"
"github.com/Qitmeer/qng/core/blockchain"
Expand All @@ -9,15 +10,21 @@ import (
_ "github.com/Qitmeer/qng/meerevm/common"
"github.com/Qitmeer/qng/node"
"github.com/Qitmeer/qng/params"
"github.com/Qitmeer/qng/services/acct"
"github.com/Qitmeer/qng/services/address"
"github.com/Qitmeer/qng/services/common"
"github.com/Qitmeer/qng/services/miner"
"github.com/Qitmeer/qng/services/tx"
"github.com/Qitmeer/qng/services/wallet"
"github.com/Qitmeer/qng/testutils/simulator/testprivatekey"
"github.com/Qitmeer/qng/version"
"os"
"path"
"runtime"
)

func DefaultConfig() *config.Config {
cfg := common.DefaultConfig(os.TempDir())
cfg := common.DefaultConfig(path.Join(os.TempDir(), "qng_test"))
cfg.DataDir = ""
cfg.DevNextGDB = true
cfg.NoFileLogging = true
Expand All @@ -26,6 +33,7 @@ func DefaultConfig() *config.Config {
cfg.DisableListen = true
cfg.NoDiscovery = true
cfg.Miner = true
cfg.AcctMode = true
return cfg
}

Expand All @@ -34,13 +42,21 @@ var mockNodeGlobalID uint
type MockNode struct {
id uint
n *node.Node
wallet *testWallet
pb *testprivatekey.Builder
overrideCfg func(cfg *config.Config) error
//
publicMinerAPI *miner.PublicMinerAPI
privateMinerAPI *miner.PrivateMinerAPI
publicBlockAPI *blockchain.PublicBlockAPI
publicBlockChainAPI *node.PublicBlockChainAPI
publicMinerAPI *miner.PublicMinerAPI
privateMinerAPI *miner.PrivateMinerAPI
publicBlockAPI *blockchain.PublicBlockAPI
publicBlockChainAPI *node.PublicBlockChainAPI
publicTxAPI *tx.PublicTxAPI
privateTxAPI *tx.PrivateTxAPI
publicAccountManagerAPI *acct.PublicAccountManagerAPI
privateWalletManagerAPI *wallet.PrivateWalletManagerAPI
}

func (mn *MockNode) ID() uint {
return mn.id
}

func (mn *MockNode) Start(cfg *config.Config) error {
Expand Down Expand Up @@ -77,7 +93,7 @@ func (mn *MockNode) Start(cfg *config.Config) error {
return err
}

return nil
return mn.setup()
}

func (mn *MockNode) Stop() {
Expand All @@ -90,6 +106,31 @@ func (mn *MockNode) Stop() {
log.Error(err.Error())
}
}
// remove temp dir
log.Info("Try remove home dir", "path", mn.n.Config.HomeDir)
err := os.RemoveAll(mn.n.Config.HomeDir)
if err != nil {
log.Error(err.Error())
}
}

func (mn *MockNode) setup() error {
// init
coinbasePKHex := mn.pb.GetHex(testprivatekey.CoinbaseIdx)
_, err := mn.GetPrivateWalletManagerAPI().ImportRawKey(coinbasePKHex, testprivatekey.Password)
if err != nil {
return err
}
accounts, err := mn.GetPrivateWalletManagerAPI().ListAccount()
if err != nil {
return err
}
log.Info(fmt.Sprintf("%v", accounts))
if len(mn.n.Config.MiningAddrs) <= 0 {
_, addr, _, _ := address.NewAddresses(coinbasePKHex)
mn.n.Config.SetMiningAddrs(addr)
}
return nil
}

func (mn *MockNode) GetPublicMinerAPI() *miner.PublicMinerAPI {
Expand Down Expand Up @@ -120,28 +161,52 @@ func (mn *MockNode) GetPublicBlockChainAPI() *node.PublicBlockChainAPI {
return mn.publicBlockChainAPI
}

func (mn *MockNode) GetPublicTxAPI() *tx.PublicTxAPI {
if mn.publicTxAPI == nil {
mn.publicTxAPI = tx.NewPublicTxAPI(mn.n.GetQitmeerFull().GetTxManager())
}
return mn.publicTxAPI
}

func (mn *MockNode) GetPrivateTxAPI() *tx.PrivateTxAPI {
if mn.privateTxAPI == nil {
mn.privateTxAPI = tx.NewPrivateTxAPI(mn.n.GetQitmeerFull().GetTxManager())
}
return mn.privateTxAPI
}

func (mn *MockNode) GetPublicAccountManagerAPI() *acct.PublicAccountManagerAPI {
if mn.publicAccountManagerAPI == nil {
mn.publicAccountManagerAPI = acct.NewPublicAccountManagerAPI(mn.n.GetQitmeerFull().GetAccountManager())
}
return mn.publicAccountManagerAPI
}

func (mn *MockNode) GetPrivateWalletManagerAPI() *wallet.PrivateWalletManagerAPI {
if mn.privateWalletManagerAPI == nil {
mn.privateWalletManagerAPI = wallet.NewPrivateWalletAPI(mn.n.GetQitmeerFull().GetWalletManager())
}
return mn.privateWalletManagerAPI
}

func StartMockNode(overrideCfg func(cfg *config.Config) error) (*MockNode, error) {
mn := &MockNode{id: mockNodeGlobalID}
pb, err := testprivatekey.NewBuilder(uint32(mockNodeGlobalID))
if err != nil {
return nil, err
}
mn := &MockNode{id: mockNodeGlobalID, pb: pb}
cfg := DefaultConfig()
if overrideCfg != nil {
err := overrideCfg(cfg)
if err != nil {
return nil, err
}
}

mockNodeGlobalID++
err := mn.Start(cfg)
if err != nil {
return nil, err
}
wallet, err := newTestWallet(uint32(mn.id))
err = mn.Start(cfg)
if err != nil {
return nil, err
}
mn.wallet = wallet
if len(mn.n.Config.MiningAddrs) <= 0 {
mn.n.Config.SetMiningAddrs(wallet.miningAddr())
}

mockNodeGlobalID++
return mn, nil
}
96 changes: 96 additions & 0 deletions testutils/simulator/testprivatekey/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) 2020 The qitmeer developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package testprivatekey

import (
"encoding/binary"
"encoding/hex"
"github.com/Qitmeer/qng/common/hash"
"github.com/Qitmeer/qng/crypto/bip32"
"github.com/Qitmeer/qng/params"
)

const (
CoinbaseIdx = 0
Password = "12345"
)

var (
// the default seed used in the testWallet
defaultSeed = [hash.HashSize]byte{
0x7e, 0x44, 0x5a, 0xa5, 0xff, 0xd8, 0x34, 0xcb,
0x2d, 0x3b, 0x2d, 0xb5, 0x0f, 0x89, 0x97, 0xdd,
0x21, 0xaf, 0x29, 0xbe, 0xc3, 0xd2, 0x96, 0xaa,
0xa0, 0x66, 0xd9, 0x02, 0xb9, 0x3f, 0x48, 0x4b,
}
)

type Builder struct {
// the bip32 master extended private key from a seed
hdMaster *bip32.Key
// the next hd child number from the master
hdChildNumer uint32
// privkeys cached all private keys which derived from the master private key.
// the keys of the private key map are their hd child number.
privkeys map[uint32][]byte
}

func NewBuilder(id uint32) (*Builder, error) {
params := params.ActiveNetParams.Params
// The final seed is seed || nodeId, the purpose to make sure that each harness
// node use a deterministic private key based on the its node id.
var finalSeed [hash.HashSize + 4]byte
// t.Logf("seed is %v",hexutil.Encode(seed[:]))
copy(finalSeed[:], defaultSeed[:])
// t.Logf("finalseed is %v",hexutil.Encode(finalSeed[:]))
binary.LittleEndian.PutUint32(finalSeed[hash.HashSize:], id)
version := bip32.Bip32Version{
PrivKeyVersion: params.HDPrivateKeyID[:],
PubKeyVersion: params.HDPublicKeyID[:],
}
// t.Logf("finalseed is %v",hexutil.Encode(finalSeed[:]))
hdMaster, err := bip32.NewMasterKey2(finalSeed[:], version)
if err != nil {
return nil, err
}
child0, err := hdMaster.NewChildKey(0)
if err != nil {
return nil, err
}
key0 := child0.Key
privkeys := make(map[uint32][]byte)
privkeys[0] = key0

return &Builder{
hdMaster: hdMaster,
hdChildNumer: 1,
privkeys: privkeys,
}, nil
}

func (b *Builder) Build() ([]byte, error) {
num := b.hdChildNumer
childx, err := b.hdMaster.NewChildKey(num)
if err != nil {
return nil, err
}
b.privkeys[num] = childx.Key
b.hdChildNumer++
return childx.Key, nil
}

func (b *Builder) Get(idx int) []byte {
if idx >= len(b.privkeys) {
return nil
}
return b.privkeys[uint32(idx)]
}

func (b *Builder) GetHex(idx int) string {
if idx >= len(b.privkeys) {
return ""
}
return hex.EncodeToString(b.privkeys[uint32(idx)])
}
52 changes: 52 additions & 0 deletions testutils/simulator/testprivatekey/builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package testprivatekey

import (
"github.com/Qitmeer/qng/common/util/hexutil"
"github.com/Qitmeer/qng/params"
"testing"
)

var (
expect = struct {
ver string
key string
chaincode string
priv0 string
priv1 string
}{
"0x040bee6e",
"0x38015593945529cc0bd761108ad2fbd98a3f5f8e030c5acd3747ce3e54d95c16",
"0x4eb4e56ada09795313734db329c362923c5b6fac75b924780e68b9c9b18a24b3",
"0xe0b26a52b1a9676a365d6452fb04a1c05b58e959683862d73105e58d4416baba",
"0xfff2cefe258ca60ae5f5abec99b5d63e2a561c40d784ee50b04eddf8efc84b0d",
}
)

func TestPrivateKeyBuild(t *testing.T) {
params.ActiveNetParams = &params.PrivNetParam
pb, err := NewBuilder(0)
if err != nil {
t.Fatal(err)
}

if hexutil.Encode(pb.hdMaster.Key) != expect.key {
t.Fatalf("hd master key not matched, expect %v but got %v", pb.hdMaster.Key, expect.key)
}
if hexutil.Encode(pb.hdMaster.Version) != expect.ver {
t.Fatalf("hd master version not matched, expect %v but got %v", pb.hdMaster.Version, expect.ver)
}
if hexutil.Encode(pb.hdMaster.ChainCode) != expect.chaincode {
t.Fatalf("hd master chain code not matched, expect %v but got %v", pb.hdMaster.ChainCode, expect.chaincode)
}

_, err = pb.Build()
if err != nil {
t.Fatalf("failed get new address : %v", err)
}
if hexutil.Encode(pb.Get(0)) != expect.priv0 {
t.Fatalf("hd key0 priv key not matched, expect %x but got %v", pb.Get(0), expect.priv0)
}
if hexutil.Encode(pb.Get(1)) != expect.priv1 {
t.Fatalf("hd key0 priv key not matched, expect %x but got %v", pb.Get(1), expect.priv1)
}
}
Loading

0 comments on commit 1c8a27b

Please sign in to comment.