From 85d69b6527ed724f0785e180db12230b71f2e2a9 Mon Sep 17 00:00:00 2001 From: wz Date: Thu, 23 May 2019 17:07:27 +0800 Subject: [PATCH] store federation (#83) * store federation * fix test * fix unit * add deal err * fix review --- account/accounts_test.go | 3 ++- config/config.go | 39 ++++++++++++++++++++++++++++++++++----- config/genesis.go | 24 +++++++++++++++++++++++- database/store_test.go | 28 +++++++++++++++++++++++----- protocol/block_test.go | 2 ++ test/bench_blockchain_test.go | 2 ++ test/util.go | 2 ++ wallet/wallet_test.go | 24 +++++++++++++++++++----- 8 files changed, 107 insertions(+), 17 deletions(-) diff --git a/account/accounts_test.go b/account/accounts_test.go index 7d37f608..cd572198 100644 --- a/account/accounts_test.go +++ b/account/accounts_test.go @@ -9,6 +9,7 @@ import ( "github.com/vapor/blockchain/pseudohsm" "github.com/vapor/blockchain/signers" + "github.com/vapor/config" "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/database" dbm "github.com/vapor/database/leveldb" @@ -213,9 +214,9 @@ func mockAccountManager(t *testing.T) *Manager { testDB := dbm.NewDB("testdb", "memdb", dirPath) dispatcher := event.NewDispatcher() - store := database.NewStore(testDB) txPool := protocol.NewTxPool(store, dispatcher) + config.CommonConfig = config.DefaultConfig() chain, err := protocol.NewChain(store, txPool, dispatcher) if err != nil { t.Fatal(err) diff --git a/config/config.go b/config/config.go index 69b4882e..c04662ff 100644 --- a/config/config.go +++ b/config/config.go @@ -11,6 +11,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/vapor/crypto/ed25519" + "github.com/vapor/crypto/ed25519/chainkd" ) var ( @@ -22,11 +23,12 @@ type Config struct { // Top level options use an anonymous struct BaseConfig `mapstructure:",squash"` // Options for services - P2P *P2PConfig `mapstructure:"p2p"` - Wallet *WalletConfig `mapstructure:"wallet"` - Auth *RPCAuthConfig `mapstructure:"auth"` - Web *WebConfig `mapstructure:"web"` - Websocket *WebsocketConfig `mapstructure:"ws"` + P2P *P2PConfig `mapstructure:"p2p"` + Wallet *WalletConfig `mapstructure:"wallet"` + Auth *RPCAuthConfig `mapstructure:"auth"` + Web *WebConfig `mapstructure:"web"` + Websocket *WebsocketConfig `mapstructure:"ws"` + Federation *FederationConfig `mapstructure:"federation"` } // Default configurable parameters. @@ -38,6 +40,7 @@ func DefaultConfig() *Config { Auth: DefaultRPCAuthConfig(), Web: DefaultWebConfig(), Websocket: DefaultWebsocketConfig(), + Federation: DefaultFederationConfig(), } } @@ -193,6 +196,11 @@ type WebsocketConfig struct { MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"` } +type FederationConfig struct { + Xpubs []chainkd.XPub `json:"xpubs"` + Quorum int `json:"quorum"` +} + // Default configurable rpc's auth parameters. func DefaultRPCAuthConfig() *RPCAuthConfig { return &RPCAuthConfig{ @@ -224,6 +232,27 @@ func DefaultWebsocketConfig() *WebsocketConfig { } } +func DefaultFederationConfig() *FederationConfig { + return &FederationConfig{ + Xpubs: []chainkd.XPub{ + xpub("7f23aae65ee4307c38d342699e328f21834488e18191ebd66823d220b5a58303496c9d09731784372bade78d5e9a4a6249b2cfe2e3a85464e5a4017aa5611e47"), + xpub("585e20143db413e45fbc82f03cb61f177e9916ef1df0012daa8cbf6dbb1025ce8f98e51ae319327b63505b64fdbbf6d36ef916d79e6dd67d51b0bfe76fe544c5"), + xpub("b58170b51ca61604028ba1cb412377dfc2bc6567c0afc84c83aae1c0c297d0227ccf568561df70851f4144bbf069b525129f2434133c145e35949375b22a6c9d"), + xpub("983705ae71949c1a5d0fcf953658dd9ecc549f02c63e197b4d087ae31148097ece816bbc60d9012c316139fc550fa0f4b00beb0887f6b152f7a69bc8f392b9fa"), + xpub("d72fb92fa13bf3e0deb39de3a47c8d6eef5584719f7877c82a4c009f78fddf924d9706d48f15b2c782ec80b6bdd621a1f7ba2a0044b0e6f92245de9436885cb9"), + xpub("6798460919e8dc7095ee8b9f9d65033ef3da8c2334813149da5a1e52e9c6da07ba7d0e7379baaa0c8bdcb21890a54e6b7290bee077c645ee4b74b0c1ae9da59a"), + }, + Quorum: 4, + } +} + +func xpub(str string) (xpub chainkd.XPub) { + if err := xpub.UnmarshalText([]byte(str)); err != nil { + log.Panicf("Fail converts a string to xpub") + } + return xpub +} + //----------------------------------------------------------------------------- // Utils diff --git a/config/genesis.go b/config/genesis.go index 5f643a02..58ad266a 100644 --- a/config/genesis.go +++ b/config/genesis.go @@ -6,20 +6,42 @@ import ( log "github.com/sirupsen/logrus" "github.com/vapor/consensus" + "github.com/vapor/crypto" + "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" + "github.com/vapor/protocol/vm/vmutil" ) +func GenesisArguments(c *Config) []byte { + pubKeys := chainkd.XPubKeys(c.Federation.Xpubs) + fedpegScript, err := vmutil.P2SPMultiSigProgram(pubKeys, c.Federation.Quorum) + if err != nil { + log.Panicf("fail on decode genesis arguments for federation") + } + + scriptHash := crypto.Sha256(fedpegScript) + + control, err := vmutil.P2WSHProgram(scriptHash) + if err != nil { + log.Panicf("Fail converts scriptHash to program on GenesisArguments: %v", err) + } + + return control +} + func GenesisTx() *types.Tx { contract, err := hex.DecodeString("00148c9d063ff74ee6d9ffa88d83aeb038068366c4c4") if err != nil { log.Panicf("fail on decode genesis tx output control program") } + coinbaseInput := GenesisArguments(CommonConfig) + txData := types.TxData{ Version: 1, Inputs: []*types.TxInput{ - types.NewCoinbaseInput([]byte("Information is power. -- Jan/11/2013. Computing is power. -- Apr/24/2018.")), + types.NewCoinbaseInput(coinbaseInput[:]), }, Outputs: []*types.TxOutput{ types.NewIntraChainOutput(*consensus.BTMAssetID, consensus.InitialBlockSubsidy, contract), diff --git a/database/store_test.go b/database/store_test.go index deffc051..8b1b4435 100644 --- a/database/store_test.go +++ b/database/store_test.go @@ -15,9 +15,13 @@ import ( ) func TestLoadBlockIndex(t *testing.T) { - defer os.RemoveAll("temp") + config.CommonConfig = config.DefaultConfig() testDB := dbm.NewDB("testdb", "leveldb", "temp") store := NewStore(testDB) + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() block := config.GenesisBlock() txStatus := bc.NewTransactionStatus() @@ -70,8 +74,11 @@ func TestLoadBlockIndexBestHeight(t *testing.T) { }, } - defer os.RemoveAll("temp") testDB := dbm.NewDB("testdb", "leveldb", "temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() store := NewStore(testDB) var savedBlocks []types.Block @@ -104,9 +111,12 @@ func TestLoadBlockIndexBestHeight(t *testing.T) { } func TestLoadBlockIndexEquals(t *testing.T) { - defer os.RemoveAll("temp") testDB := dbm.NewDB("testdb", "leveldb", "temp") store := NewStore(testDB) + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() block := config.GenesisBlock() txStatus := bc.NewTransactionStatus() @@ -142,8 +152,12 @@ func TestLoadBlockIndexEquals(t *testing.T) { } } func TestSaveChainStatus(t *testing.T) { - defer os.RemoveAll("temp") testDB := dbm.NewDB("testdb", "leveldb", "temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() + store := NewStore(testDB) node := &state.BlockNode{Height: 100, Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}} @@ -181,8 +195,12 @@ func TestSaveChainStatus(t *testing.T) { } func TestSaveBlock(t *testing.T) { - defer os.RemoveAll("temp") testDB := dbm.NewDB("testdb", "leveldb", "temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() + store := NewStore(testDB) block := config.GenesisBlock() diff --git a/protocol/block_test.go b/protocol/block_test.go index 4e668eac..6fcece86 100644 --- a/protocol/block_test.go +++ b/protocol/block_test.go @@ -10,6 +10,7 @@ import ( ) func TestCalcReorganizeNodes(t *testing.T) { + config.CommonConfig = config.DefaultConfig() c := &Chain{index: state.NewBlockIndex()} header := config.GenesisBlock().BlockHeader initNode, err := state.NewBlockNode(&header, nil) @@ -55,6 +56,7 @@ func TestCalcReorganizeNodes(t *testing.T) { } func TestEdgeCalcReorganizeNodes(t *testing.T) { + config.CommonConfig = config.DefaultConfig() header := config.GenesisBlock().BlockHeader initNode, err := state.NewBlockNode(&header, nil) if err != nil { diff --git a/test/bench_blockchain_test.go b/test/bench_blockchain_test.go index e987946b..e691987e 100644 --- a/test/bench_blockchain_test.go +++ b/test/bench_blockchain_test.go @@ -11,6 +11,7 @@ import ( "github.com/vapor/blockchain/pseudohsm" "github.com/vapor/blockchain/signers" "github.com/vapor/blockchain/txbuilder" + "github.com/vapor/config" "github.com/vapor/consensus" "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/database" @@ -137,6 +138,7 @@ func GenerateChainData(dirPath string, testDB dbm.DB, txNumber, otherAssetNum in return nil, nil, nil, err } + config.CommonConfig = config.DefaultConfig() store := database.NewStore(testDB) dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) diff --git a/test/util.go b/test/util.go index d89ddd5b..54b9b05e 100644 --- a/test/util.go +++ b/test/util.go @@ -7,6 +7,7 @@ import ( "github.com/vapor/account" "github.com/vapor/blockchain/pseudohsm" "github.com/vapor/blockchain/txbuilder" + "github.com/vapor/config" "github.com/vapor/consensus" "github.com/vapor/crypto/ed25519/chainkd" "github.com/vapor/database" @@ -25,6 +26,7 @@ const ( // MockChain mock chain with genesis block func MockChain(testDB dbm.DB) (*protocol.Chain, *database.Store, *protocol.TxPool, error) { + config.CommonConfig = config.DefaultConfig() store := database.NewStore(testDB) dispatcher := event.NewDispatcher() txPool := protocol.NewTxPool(store, dispatcher) diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 3a65465d..823eab9e 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -53,7 +53,10 @@ func TestWalletVersion(t *testing.T) { defer os.RemoveAll(dirPath) testDB := dbm.NewDB("testdb", "leveldb", "temp") - defer os.RemoveAll("temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() dispatcher := event.NewDispatcher() w := mockWallet(testDB, nil, nil, nil, dispatcher, false) @@ -113,8 +116,12 @@ func TestWalletUpdate(t *testing.T) { } defer os.RemoveAll(dirPath) + config.CommonConfig = config.DefaultConfig() testDB := dbm.NewDB("testdb", "leveldb", "temp") - defer os.RemoveAll("temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() store := database.NewStore(testDB) dispatcher := event.NewDispatcher() @@ -206,8 +213,12 @@ func TestRescanWallet(t *testing.T) { } defer os.RemoveAll(dirPath) + config.CommonConfig = config.DefaultConfig() testDB := dbm.NewDB("testdb", "leveldb", "temp") - defer os.RemoveAll("temp") + defer func() { + testDB.Close() + os.RemoveAll("temp") + }() store := database.NewStore(testDB) dispatcher := event.NewDispatcher() @@ -253,9 +264,12 @@ func TestMemPoolTxQueryLoop(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.RemoveAll(dirPath) - + config.CommonConfig = config.DefaultConfig() testDB := dbm.NewDB("testdb", "leveldb", dirPath) + defer func() { + testDB.Close() + os.RemoveAll(dirPath) + }() store := database.NewStore(testDB) dispatcher := event.NewDispatcher() -- 2.11.0