Commit c67c3566 authored by vipwzw's avatar vipwzw Committed by 33cn

update chain33 06/05

parent 350b2a9a
...@@ -58,6 +58,6 @@ matrix: ...@@ -58,6 +58,6 @@ matrix:
- sudo mv docker-compose /usr/local/bin - sudo mv docker-compose /usr/local/bin
script: script:
- make build_ci - make build_ci
- make autotest_ci - make autotest dapp=all
- make docker-compose && make docker-compose-down - make docker-compose && make docker-compose-down
...@@ -49,14 +49,6 @@ function config_chain33() { ...@@ -49,14 +49,6 @@ function config_chain33() {
else else
sed -i $sedfix '/^Title/a TestNet=true' ${chain33Config} sed -i $sedfix '/^Title/a TestNet=true' ${chain33Config}
fi fi
#update fee
sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config}
#update block time
#update wallet store driver
sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config}
} }
function config_autotest() { function config_autotest() {
......
...@@ -40,12 +40,10 @@ function config_chain33() { ...@@ -40,12 +40,10 @@ function config_chain33() {
fi fi
#update fee #update fee
sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config} # sed -i $sedfix 's/Fee=.*/Fee=100000/' ${chain33Config}
#update block time
#update wallet store driver #update wallet store driver
sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config} # sed -i $sedfix '/^\[wallet\]/,/^\[wallet./ s/^driver.*/driver="leveldb"/' ${chain33Config}
} }
autotestConfig="autotest.toml" autotestConfig="autotest.toml"
......
...@@ -138,13 +138,17 @@ chain33_GetHeaders() { ...@@ -138,13 +138,17 @@ chain33_GetHeaders() {
chain33_GetLastMemPool() { chain33_GetLastMemPool() {
req='"method":"Chain33.GetLastMemPool", "params":[{}]' if [ "$IS_PARA" == true ]; then
echo "#request: $req" echo_rst "$FUNCNAME" 2
resp=$(curl -ksd "{$req}" "$1") else
# echo "#response: $resp" req='"method":"Chain33.GetLastMemPool", "params":[{}]'
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp") echo "#request: $req"
[ "$ok" == true ] resp=$(curl -ksd "{$req}" "$1")
echo_rst "$FUNCNAME" "$?" #echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
fi
} }
chain33_GetProperFee() { chain33_GetProperFee() {
...@@ -394,11 +398,16 @@ chain33_GetTxByHashes() { ...@@ -394,11 +398,16 @@ chain33_GetTxByHashes() {
} }
chain33_GetMempool() { chain33_GetMempool() {
resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetMempool","params":[{}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp") if [ "$IS_PARA" == true ]; then
[ "$ok" == true ] echo_rst "$FUNCNAME" 2
rst=$? else
echo_rst "$FUNCNAME" "$rst" resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetMempool","params":[{}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.txs|length >= 0)' <<<"$resp")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
fi
} }
chain33_GetAccountsV2() { chain33_GetAccountsV2() {
......
...@@ -54,6 +54,8 @@ dbPath="datadir/addrbook" ...@@ -54,6 +54,8 @@ dbPath="datadir/addrbook"
dbCache=4 dbCache=4
# GRPC请求日志文件 # GRPC请求日志文件
grpcLogFile="grpc33.log" grpcLogFile="grpc33.log"
#waitPid 等待seed导入
waitPid=false
[rpc] [rpc]
# jrpc绑定地址 # jrpc绑定地址
......
...@@ -53,6 +53,8 @@ grpcLogFile="grpc33.log" ...@@ -53,6 +53,8 @@ grpcLogFile="grpc33.log"
version=216 version=216
verMix=216 verMix=216
verMax=217 verMax=217
#waitPid 等待seed导入
waitPid=false
[rpc] [rpc]
jrpcBindAddr="localhost:8801" jrpcBindAddr="localhost:8801"
...@@ -69,6 +71,7 @@ name="timeline" ...@@ -69,6 +71,7 @@ name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFee=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
isLevelFee=false
[mempool.sub.timeline] [mempool.sub.timeline]
poolCacheSize=10240 poolCacheSize=10240
...@@ -163,6 +166,7 @@ minerwhitelist=["*"] ...@@ -163,6 +166,7 @@ minerwhitelist=["*"]
[exec] [exec]
isFree=false isFree=false
minExecFee=100000 minExecFee=100000
maxExecFee=1000000000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
Title="chain33" Title="chain33"
TestNet=true TestNet=true
FixTime=false FixTime=false
# 配置主币的名称: 比特元链bty, 部分未配置的平行链需要配置为 bty, 新的平行链配置 para或其他, 不配置panic
CoinSymbol="bty" CoinSymbol="bty"
[log] [log]
...@@ -77,6 +78,8 @@ dbPath="datadir/addrbook" ...@@ -77,6 +78,8 @@ dbPath="datadir/addrbook"
dbCache=4 dbCache=4
# GRPC请求日志文件 # GRPC请求日志文件
grpcLogFile="grpc33.log" grpcLogFile="grpc33.log"
#waitPid 等待seed导入
waitPid=false
[rpc] [rpc]
# jrpc绑定地址 # jrpc绑定地址
...@@ -105,7 +108,10 @@ poolCacheSize=10240 ...@@ -105,7 +108,10 @@ poolCacheSize=10240
minTxFee=100000 minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=100 maxTxNumPerAccount=100
# 最大得交易手续费用,这个没有默认值,必填,一般是100000
maxTxFee=1000000000 maxTxFee=1000000000
# 是否开启阶梯手续费
isLevelFee=false
[mempool.sub.timeline] [mempool.sub.timeline]
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
......
...@@ -243,15 +243,7 @@ func (a *AddrBook) genPubkey(privkey string) string { ...@@ -243,15 +243,7 @@ func (a *AddrBook) genPubkey(privkey string) string {
func (a *AddrBook) loadDb() bool { func (a *AddrBook) loadDb() bool {
a.bookDb = db.NewDB("addrbook", a.cfg.Driver, a.cfg.DbPath, a.cfg.DbCache) a.bookDb = db.NewDB("addrbook", a.cfg.Driver, a.cfg.DbPath, a.cfg.DbCache)
privkey, err := a.bookDb.Get([]byte(privKeyTag)) privkey, err := a.bookDb.Get([]byte(privKeyTag))
if len(privkey) == 0 || err != nil { if len(privkey) != 0 && err == nil {
a.initKey()
privkey, _ := a.GetPrivPubKey()
err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
if err != nil {
panic(err)
}
} else {
a.setKey(string(privkey), a.genPubkey(string(privkey))) a.setKey(string(privkey), a.genPubkey(string(privkey)))
} }
...@@ -393,10 +385,12 @@ func (a *AddrBook) setKey(privkey, pubkey string) { ...@@ -393,10 +385,12 @@ func (a *AddrBook) setKey(privkey, pubkey string) {
//ResetPeerkey reset priv,pub key //ResetPeerkey reset priv,pub key
func (a *AddrBook) ResetPeerkey(privkey, pubkey string) { func (a *AddrBook) ResetPeerkey(privkey, pubkey string) {
a.keymtx.Lock()
defer a.keymtx.Unlock() if privkey == "" || pubkey == "" {
a.privkey = privkey a.initKey()
a.pubkey = pubkey privkey, pubkey = a.GetPrivPubKey()
}
a.setKey(privkey, pubkey)
err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey)) err := a.bookDb.Set([]byte(privKeyTag), []byte(privkey))
if err != nil { if err != nil {
panic(err) panic(err)
......
...@@ -34,12 +34,6 @@ const ( ...@@ -34,12 +34,6 @@ const (
maxSamIPNum = 20 maxSamIPNum = 20
) )
var (
// LocalAddr local address
LocalAddr string
//defaultPort = 13802
)
const ( const (
defalutNatPort = 23802 defalutNatPort = 23802
maxOutBoundNum = 25 maxOutBoundNum = 25
......
...@@ -147,6 +147,7 @@ func (d *DownloadJob) GetFreePeer(blockHeight int64) *Peer { ...@@ -147,6 +147,7 @@ func (d *DownloadJob) GetFreePeer(blockHeight int64) *Peer {
var jobNum int32 = 10 var jobNum int32 = 10
var bestPeer *Peer var bestPeer *Peer
for _, peer := range d.downloadPeers { for _, peer := range d.downloadPeers {
pbpeer, ok := infos[peer.Addr()] pbpeer, ok := infos[peer.Addr()]
if ok { if ok {
if len(peer.GetPeerName()) == 0 { if len(peer.GetPeerName()) == 0 {
...@@ -194,6 +195,7 @@ func (d *DownloadJob) DownloadBlock(invs []*pb.Inventory, ...@@ -194,6 +195,7 @@ func (d *DownloadJob) DownloadBlock(invs []*pb.Inventory,
REGET: REGET:
freePeer := d.GetFreePeer(inv.GetHeight()) //获取当前任务数最少的节点,相当于 下载速度最快的节点 freePeer := d.GetFreePeer(inv.GetHeight()) //获取当前任务数最少的节点,相当于 下载速度最快的节点
if freePeer == nil { if freePeer == nil {
log.Debug("no free peer")
time.Sleep(time.Millisecond * 100) time.Sleep(time.Millisecond * 100)
goto REGET goto REGET
} }
......
...@@ -123,7 +123,8 @@ func (n *Node) flushNodePort(localport, export uint16) { ...@@ -123,7 +123,8 @@ func (n *Node) flushNodePort(localport, export uint16) {
n.nodeInfo.SetExternalAddr(exaddr) n.nodeInfo.SetExternalAddr(exaddr)
n.nodeInfo.addrBook.AddOurAddress(exaddr) n.nodeInfo.addrBook.AddOurAddress(exaddr)
} }
if listenAddr, err := NewNetAddressString(fmt.Sprintf("%v:%v", LocalAddr, localport)); err == nil {
if listenAddr, err := NewNetAddressString(fmt.Sprintf("%v:%v", n.nodeInfo.GetListenAddr().IP.String(), localport)); err == nil {
n.nodeInfo.SetListenAddr(listenAddr) n.nodeInfo.SetListenAddr(listenAddr)
n.nodeInfo.addrBook.AddOurAddress(listenAddr) n.nodeInfo.addrBook.AddOurAddress(listenAddr)
} }
...@@ -354,9 +355,9 @@ func (n *Node) detectNodeAddr() { ...@@ -354,9 +355,9 @@ func (n *Node) detectNodeAddr() {
for { for {
cfg := n.nodeInfo.cfg cfg := n.nodeInfo.cfg
laddr := P2pComm.GetLocalAddr() laddr := P2pComm.GetLocalAddr()
LocalAddr = laddr //LocalAddr = laddr
log.Info("DetectNodeAddr", "addr:", laddr) log.Info("DetectNodeAddr", "addr:", laddr)
if len(LocalAddr) == 0 { if laddr == "" {
log.Error("DetectNodeAddr", "NetWork Disable p2p Disable", "Retry until Network enable") log.Error("DetectNodeAddr", "NetWork Disable p2p Disable", "Retry until Network enable")
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
continue continue
......
...@@ -34,9 +34,10 @@ type P2p struct { ...@@ -34,9 +34,10 @@ type P2p struct {
txFactory chan struct{} txFactory chan struct{}
otherFactory chan struct{} otherFactory chan struct{}
waitRestart chan struct{} waitRestart chan struct{}
closed int32
restart int32 closed int32
cfg *types.P2P restart int32
cfg *types.P2P
} }
// New produce a p2p object // New produce a p2p object
...@@ -96,15 +97,15 @@ func (network *P2p) isRestart() bool { ...@@ -96,15 +97,15 @@ func (network *P2p) isRestart() bool {
// Close network client // Close network client
func (network *P2p) Close() { func (network *P2p) Close() {
log.Info("p2p network start shutdown")
atomic.StoreInt32(&network.closed, 1) atomic.StoreInt32(&network.closed, 1)
log.Debug("close", "network", "ShowTaskCapcity done")
network.node.Close() network.node.Close()
log.Debug("close", "node", "done")
if network.client != nil { if network.client != nil {
if !network.isRestart() { if !network.isRestart() {
network.client.Close() network.client.Close()
} }
} }
network.node.pubsub.Shutdown() network.node.pubsub.Shutdown()
...@@ -126,25 +127,74 @@ func (network *P2p) SetQueueClient(cli queue.Client) { ...@@ -126,25 +127,74 @@ func (network *P2p) SetQueueClient(cli queue.Client) {
go func(p2p *P2p) { go func(p2p *P2p) {
p2p.node.Start()
if p2p.isRestart() { if p2p.isRestart() {
//reset p2p.node.Start()
atomic.StoreInt32(&p2p.closed, 0) atomic.StoreInt32(&p2p.closed, 0)
atomic.StoreInt32(&p2p.restart, 0) atomic.StoreInt32(&p2p.restart, 0)
network.waitRestart <- struct{}{} network.waitRestart <- struct{}{}
return
}
p2p.subP2pMsg()
key, pub := p2p.node.nodeInfo.addrBook.GetPrivPubKey()
log.Debug("key pub:", pub, "")
if key == "" {
if p2p.cfg.WaitPid { //key为空,则为初始钱包,阻塞模式,一直等到钱包导入助记词,解锁
if p2p.genAirDropKeyFromWallet() != nil {
return
}
} else {
//创建随机Pid,会同时出现node award ,airdropaddr
p2p.node.nodeInfo.addrBook.ResetPeerkey(key, pub)
go p2p.genAirDropKeyFromWallet()
}
} else { } else {
p2p.subP2pMsg() //key 有两种可能,老版本的随机key,也有可能是seed的key, 非阻塞模式
go p2p.loadP2PPrivKeyToWallet()
go p2p.genAirDropKeyFromWallet() go p2p.genAirDropKeyFromWallet()
} }
p2p.node.Start()
log.Debug("SetQueueClient gorountine ret") log.Debug("SetQueueClient gorountine ret")
}(network) }(network)
} }
func (network *P2p) loadP2PPrivKeyToWallet() error {
var parm types.ReqWalletImportPrivkey
parm.Privkey, _ = network.node.nodeInfo.addrBook.GetPrivPubKey()
parm.Label = "node award"
ReTry:
msg := network.client.NewMessage("wallet", types.EventWalletImportPrivkey, &parm)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("ImportPrivkey", "Error", err.Error())
return err
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
if err == types.ErrPrivkeyExist {
return nil
}
if err == types.ErrLabelHasUsed {
//切换随机lable
parm.Label = fmt.Sprintf("node award %v", P2pComm.RandStr(3))
time.Sleep(time.Second)
goto ReTry
}
log.Error("loadP2PPrivKeyToWallet", "err", err.Error())
return err
}
log.Debug("loadP2PPrivKeyToWallet", "resp", resp.GetData())
return nil
}
func (network *P2p) showTaskCapcity() { func (network *P2p) showTaskCapcity() {
ticker := time.NewTicker(time.Second * 5) ticker := time.NewTicker(time.Second * 5)
log.Info("ShowTaskCapcity", "Capcity", atomic.LoadInt32(&network.txCapcity)) log.Info("ShowTaskCapcity", "Capcity", atomic.LoadInt32(&network.txCapcity))
...@@ -160,10 +210,11 @@ func (network *P2p) showTaskCapcity() { ...@@ -160,10 +210,11 @@ func (network *P2p) showTaskCapcity() {
} }
func (network *P2p) genAirDropKeyFromWallet() error { func (network *P2p) genAirDropKeyFromWallet() error {
_, savePub := network.node.nodeInfo.addrBook.GetPrivPubKey()
for { for {
if network.isClose() { if network.isClose() {
return nil log.Error("genAirDropKeyFromWallet", "p2p closed", "")
return fmt.Errorf("p2p closed")
} }
msg := network.client.NewMessage("wallet", types.EventGetWalletStatus, nil) msg := network.client.NewMessage("wallet", types.EventGetWalletStatus, nil)
err := network.client.SendTimeout(msg, true, time.Minute) err := network.client.SendTimeout(msg, true, time.Minute)
...@@ -179,12 +230,20 @@ func (network *P2p) genAirDropKeyFromWallet() error { ...@@ -179,12 +230,20 @@ func (network *P2p) genAirDropKeyFromWallet() error {
continue continue
} }
if resp.GetData().(*types.WalletStatus).GetIsWalletLock() { //上锁 if resp.GetData().(*types.WalletStatus).GetIsWalletLock() { //上锁
if savePub == "" {
log.Warn("P2P Stuck ! Wallet must be unlock and save with mnemonics")
}
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
if !resp.GetData().(*types.WalletStatus).GetIsHasSeed() { //无种子 if !resp.GetData().(*types.WalletStatus).GetIsHasSeed() { //无种子
time.Sleep(time.Second) if savePub == "" {
log.Warn("P2P Stuck ! Wallet must be imported with mnemonics")
}
time.Sleep(time.Second * 5)
continue continue
} }
...@@ -208,7 +267,6 @@ func (network *P2p) genAirDropKeyFromWallet() error { ...@@ -208,7 +267,6 @@ func (network *P2p) genAirDropKeyFromWallet() error {
} else { } else {
hexPrivkey = reply.GetData() hexPrivkey = reply.GetData()
} }
log.Info("genAirDropKeyFromWallet", "hexprivkey", hexPrivkey)
if hexPrivkey[:2] == "0x" { if hexPrivkey[:2] == "0x" {
hexPrivkey = hexPrivkey[2:] hexPrivkey = hexPrivkey[2:]
} }
...@@ -221,19 +279,30 @@ func (network *P2p) genAirDropKeyFromWallet() error { ...@@ -221,19 +279,30 @@ func (network *P2p) genAirDropKeyFromWallet() error {
log.Info("genAirDropKeyFromWallet", "pubkey", hexPubkey) log.Info("genAirDropKeyFromWallet", "pubkey", hexPubkey)
_, pub := network.node.nodeInfo.addrBook.GetPrivPubKey() if savePub == hexPubkey {
if pub == hexPubkey { return nil
}
if savePub != "" {
//priv,pub是随机公私钥对,兼容老版本,先对其进行导入钱包处理
err = network.loadP2PPrivKeyToWallet()
if err != nil {
log.Error("genAirDropKeyFromWallet", "loadP2PPrivKeyToWallet error", err)
panic(err)
}
network.node.nodeInfo.addrBook.ResetPeerkey(hexPrivkey, hexPubkey)
//重启p2p模块
log.Info("genAirDropKeyFromWallet", "p2p will Restart....")
network.ReStart()
return nil return nil
} }
//覆盖addrbook 中的公私钥对 //覆盖addrbook 中的公私钥对
network.node.nodeInfo.addrBook.ResetPeerkey(hexPrivkey, hexPubkey) network.node.nodeInfo.addrBook.ResetPeerkey(hexPrivkey, hexPubkey)
//重启p2p模块
log.Info("genAirDropKeyFromWallet", "p2p will Restart....")
network.ReStart()
return nil return nil
} }
// ReStart p2p //ReStart p2p
func (network *P2p) ReStart() { func (network *P2p) ReStart() {
atomic.StoreInt32(&network.restart, 1) atomic.StoreInt32(&network.restart, 1)
network.Close() network.Close()
...@@ -246,67 +315,6 @@ func (network *P2p) ReStart() { ...@@ -246,67 +315,6 @@ func (network *P2p) ReStart() {
network.SetQueueClient(network.client) network.SetQueueClient(network.client)
} }
func (network *P2p) loadP2PPrivKeyToWallet() error {
for {
if network.isClose() {
return nil
}
msg := network.client.NewMessage("wallet", types.EventGetWalletStatus, nil)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("GetWalletStatus", "Error", err.Error())
time.Sleep(time.Second)
continue
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
time.Sleep(time.Second)
continue
}
if resp.GetData().(*types.WalletStatus).GetIsWalletLock() { //上锁
time.Sleep(time.Second)
continue
}
if !resp.GetData().(*types.WalletStatus).GetIsHasSeed() { //无种子
time.Sleep(time.Second)
continue
}
break
}
var parm types.ReqWalletImportPrivkey
parm.Privkey, _ = network.node.nodeInfo.addrBook.GetPrivPubKey()
parm.Label = "node award"
ReTry:
msg := network.client.NewMessage("wallet", types.EventWalletImportPrivkey, &parm)
err := network.client.SendTimeout(msg, true, time.Minute)
if err != nil {
log.Error("ImportPrivkey", "Error", err.Error())
return err
}
resp, err := network.client.WaitTimeout(msg, time.Minute)
if err != nil {
if err == types.ErrPrivkeyExist {
return nil
}
if err == types.ErrLabelHasUsed {
//切换随机lable
parm.Label = fmt.Sprintf("node award %v", P2pComm.RandStr(3))
time.Sleep(time.Second)
goto ReTry
}
log.Error("loadP2PPrivKeyToWallet", "err", err.Error())
return err
}
log.Debug("loadP2PPrivKeyToWallet", "resp", resp.GetData())
return nil
}
func (network *P2p) subP2pMsg() { func (network *P2p) subP2pMsg() {
if network.client == nil { if network.client == nil {
......
...@@ -2,6 +2,7 @@ package p2p ...@@ -2,6 +2,7 @@ package p2p
import ( import (
"encoding/hex" "encoding/hex"
//"fmt"
"net" "net"
"os" "os"
"sort" "sort"
...@@ -31,8 +32,6 @@ func init() { ...@@ -31,8 +32,6 @@ func init() {
q = queue.New("channel") q = queue.New("channel")
go q.Start() go q.Start()
p2pModule = initP2p(33802, dataDir)
p2pModule.Wait()
go func() { go func() {
cfg, sub := types.InitCfg("../cmd/chain33/chain33.test.toml") cfg, sub := types.InitCfg("../cmd/chain33/chain33.test.toml")
...@@ -115,6 +114,9 @@ func init() { ...@@ -115,6 +114,9 @@ func init() {
} }
} }
}() }()
time.Sleep(time.Second)
p2pModule = initP2p(53802, dataDir)
p2pModule.Wait()
} }
...@@ -128,9 +130,14 @@ func initP2p(port int32, dbpath string) *P2p { ...@@ -128,9 +130,14 @@ func initP2p(port int32, dbpath string) *P2p {
cfg.Version = 119 cfg.Version = 119
cfg.ServerStart = true cfg.ServerStart = true
cfg.Driver = "leveldb" cfg.Driver = "leveldb"
p2pcli := New(cfg) p2pcli := New(cfg)
p2pcli.SetQueueClient(q.Client()) p2pcli.node.nodeInfo.addrBook.initKey()
privkey, _ := p2pcli.node.nodeInfo.addrBook.GetPrivPubKey()
p2pcli.node.nodeInfo.addrBook.bookDb.Set([]byte(privKeyTag), []byte(privkey))
p2pcli.node.nodeInfo.SetServiceTy(7) p2pcli.node.nodeInfo.SetServiceTy(7)
p2pcli.SetQueueClient(q.Client())
return p2pcli return p2pcli
} }
...@@ -162,17 +169,19 @@ func TestNetInfo(t *testing.T) { ...@@ -162,17 +169,19 @@ func TestNetInfo(t *testing.T) {
p2pModule.node.nodeInfo.SetNatDone() p2pModule.node.nodeInfo.SetNatDone()
p2pModule.node.nodeInfo.Get() p2pModule.node.nodeInfo.Get()
p2pModule.node.nodeInfo.Set(p2pModule.node.nodeInfo) p2pModule.node.nodeInfo.Set(p2pModule.node.nodeInfo)
assert.NotNil(t, p2pModule.node.nodeInfo.GetListenAddr())
assert.NotNil(t, p2pModule.node.nodeInfo.GetExternalAddr())
} }
//测试Peer //测试Peer
func TestPeer(t *testing.T) { func TestPeer(t *testing.T) {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(), conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err) assert.Nil(t, err)
defer conn.Close() defer conn.Close()
remote, err := NewNetAddressString("127.0.0.1:33802") remote, err := NewNetAddressString("127.0.0.1:53802")
assert.Nil(t, err) assert.Nil(t, err)
localP2P := initP2p(43802, "testdata2") localP2P := initP2p(43802, "testdata2")
...@@ -219,7 +228,7 @@ func TestPeer(t *testing.T) { ...@@ -219,7 +228,7 @@ func TestPeer(t *testing.T) {
_, err = p2pcli.SendVersion(peer, localP2P.node.nodeInfo) _, err = p2pcli.SendVersion(peer, localP2P.node.nodeInfo)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(p2pcli.CheckPeerNatOk("localhost:33802")) t.Log(p2pcli.CheckPeerNatOk("localhost:53802"))
t.Log("checkself:", p2pcli.CheckSelf("loadhost:43803", localP2P.node.nodeInfo)) t.Log("checkself:", p2pcli.CheckSelf("loadhost:43803", localP2P.node.nodeInfo))
_, err = p2pcli.GetAddr(peer) _, err = p2pcli.GetAddr(peer)
assert.Nil(t, err) assert.Nil(t, err)
...@@ -230,7 +239,7 @@ func TestPeer(t *testing.T) { ...@@ -230,7 +239,7 @@ func TestPeer(t *testing.T) {
height, err := p2pcli.GetBlockHeight(localP2P.node.nodeInfo) height, err := p2pcli.GetBlockHeight(localP2P.node.nodeInfo)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, int(height), 2019) assert.Equal(t, int(height), 2019)
assert.Equal(t, false, p2pcli.CheckSelf("localhost:33802", localP2P.node.nodeInfo)) assert.Equal(t, false, p2pcli.CheckSelf("localhost:53802", localP2P.node.nodeInfo))
//测试下载 //测试下载
job := NewDownloadJob(NewP2PCli(localP2P).(*Cli), []*Peer{peer}) job := NewDownloadJob(NewP2PCli(localP2P).(*Cli), []*Peer{peer})
...@@ -271,7 +280,7 @@ func TestGrpcConns(t *testing.T) { ...@@ -271,7 +280,7 @@ func TestGrpcConns(t *testing.T) {
var conns []*grpc.ClientConn var conns []*grpc.ClientConn
for i := 0; i < maxSamIPNum; i++ { for i := 0; i < maxSamIPNum; i++ {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(), conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err) assert.Nil(t, err)
...@@ -282,7 +291,7 @@ func TestGrpcConns(t *testing.T) { ...@@ -282,7 +291,7 @@ func TestGrpcConns(t *testing.T) {
conns = append(conns, conn) conns = append(conns, conn)
} }
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(), conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err) assert.Nil(t, err)
cli := types.NewP2PgserviceClient(conn) cli := types.NewP2PgserviceClient(conn)
...@@ -300,7 +309,7 @@ func TestGrpcConns(t *testing.T) { ...@@ -300,7 +309,7 @@ func TestGrpcConns(t *testing.T) {
//测试grpc 流多连接 //测试grpc 流多连接
func TestGrpcStreamConns(t *testing.T) { func TestGrpcStreamConns(t *testing.T) {
conn, err := grpc.Dial("localhost:33802", grpc.WithInsecure(), conn, err := grpc.Dial("localhost:53802", grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
assert.Nil(t, err) assert.Nil(t, err)
cli := types.NewP2PgserviceClient(conn) cli := types.NewP2PgserviceClient(conn)
...@@ -329,7 +338,7 @@ func TestGrpcStreamConns(t *testing.T) { ...@@ -329,7 +338,7 @@ func TestGrpcStreamConns(t *testing.T) {
func TestP2pComm(t *testing.T) { func TestP2pComm(t *testing.T) {
addrs := P2pComm.AddrRouteble([]string{"localhost:33802"}) addrs := P2pComm.AddrRouteble([]string{"localhost:53802"})
t.Log(addrs) t.Log(addrs)
i32 := P2pComm.BytesToInt32([]byte{0xff}) i32 := P2pComm.BytesToInt32([]byte{0xff})
...@@ -398,7 +407,13 @@ func TestAddrBook(t *testing.T) { ...@@ -398,7 +407,13 @@ func TestAddrBook(t *testing.T) {
assert.Equal(t, addrBook.genPubkey(hex.EncodeToString(prv)), pubstr) assert.Equal(t, addrBook.genPubkey(hex.EncodeToString(prv)), pubstr)
addrBook.Save() addrBook.Save()
addrBook.GetAddrs() addrBook.GetAddrs()
addrBook.ResetPeerkey("", "")
privkey, _ := addrBook.GetPrivPubKey()
assert.NotEmpty(t, privkey)
addrBook.ResetPeerkey(hex.EncodeToString(prv), pubstr) addrBook.ResetPeerkey(hex.EncodeToString(prv), pubstr)
resetkey, _ := addrBook.GetPrivPubKey()
assert.NotEqual(t, resetkey, privkey)
} }
func TestBytesToInt32(t *testing.T) { func TestBytesToInt32(t *testing.T) {
......
...@@ -630,8 +630,8 @@ func (m *Cli) getLocalPeerInfo() (*pb.P2PPeerInfo, error) { ...@@ -630,8 +630,8 @@ func (m *Cli) getLocalPeerInfo() (*pb.P2PPeerInfo, error) {
localpeerinfo.Name = pub localpeerinfo.Name = pub
localpeerinfo.MempoolSize = int32(meminfo.GetSize()) localpeerinfo.MempoolSize = int32(meminfo.GetSize())
if m.network.node.nodeInfo.GetExternalAddr().IP == nil { if m.network.node.nodeInfo.GetExternalAddr().IP == nil {
localpeerinfo.Addr = LocalAddr localpeerinfo.Addr = m.network.node.nodeInfo.GetListenAddr().IP.String()
localpeerinfo.Port = int32(m.network.node.listenPort) localpeerinfo.Port = int32(m.network.node.nodeInfo.GetListenAddr().Port)
} else { } else {
localpeerinfo.Addr = m.network.node.nodeInfo.GetExternalAddr().IP.String() localpeerinfo.Addr = m.network.node.nodeInfo.GetExternalAddr().IP.String()
localpeerinfo.Port = int32(m.network.node.nodeInfo.GetExternalAddr().Port) localpeerinfo.Port = int32(m.network.node.nodeInfo.GetExternalAddr().Port)
......
...@@ -574,7 +574,7 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe ...@@ -574,7 +574,7 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe
if s.node.Size() > 0 { if s.node.Size() > 0 {
if remoteIP != LocalAddr && remoteIP != s.node.nodeInfo.GetExternalAddr().IP.String() { if remoteIP != s.node.nodeInfo.GetListenAddr().IP.String() && remoteIP != s.node.nodeInfo.GetExternalAddr().IP.String() {
s.node.nodeInfo.SetServiceTy(Service) s.node.nodeInfo.SetServiceTy(Service)
} }
} }
......
...@@ -281,6 +281,35 @@ func (mem *Mempool) RemoveTxsOfBlock(block *types.Block) bool { ...@@ -281,6 +281,35 @@ func (mem *Mempool) RemoveTxsOfBlock(block *types.Block) bool {
return true return true
} }
// GetProperFeeRate 获取合适的手续费率
func (mem *Mempool) GetProperFeeRate() int64 {
baseFeeRate := mem.cache.GetProperFee()
if mem.cfg.IsLevelFee {
return mem.getLevelFeeRate(baseFeeRate)
}
return baseFeeRate
}
// getLevelFeeRate 获取合适的阶梯手续费率
func (mem *Mempool) getLevelFeeRate(baseFeeRate int64) int64 {
var feeRate int64
sumByte := mem.cache.TotalByte()
maxTxNumber := types.GetP(mem.Height()).MaxTxNumber
switch {
case (sumByte > int64(types.MaxBlockSize/100) && sumByte < int64(types.MaxBlockSize/20)) ||
(int64(mem.Size()) >= maxTxNumber/10 && int64(mem.Size()) < maxTxNumber/2):
feeRate = 10 * baseFeeRate
case sumByte >= int64(types.MaxBlockSize/20) || int64(mem.Size()) >= maxTxNumber/2:
feeRate = 100 * baseFeeRate
default:
return baseFeeRate
}
if feeRate > 10000000 {
feeRate = 10000000
}
return feeRate
}
// Mempool.DelBlock将回退的区块内的交易重新加入mempool中 // Mempool.DelBlock将回退的区块内的交易重新加入mempool中
func (mem *Mempool) delBlock(block *types.Block) { func (mem *Mempool) delBlock(block *types.Block) {
if len(block.Txs) <= 0 { if len(block.Txs) <= 0 {
......
...@@ -6,6 +6,7 @@ package mempool ...@@ -6,6 +6,7 @@ package mempool
import ( import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
) )
//QueueCache 排队交易处理 //QueueCache 排队交易处理
...@@ -30,7 +31,9 @@ type Item struct { ...@@ -30,7 +31,9 @@ type Item struct {
type txCache struct { type txCache struct {
*AccountTxIndex *AccountTxIndex
*LastTxCache *LastTxCache
qcache QueueCache qcache QueueCache
totalFee int64
totalByte int64
} }
//NewTxCache init accountIndex and last cache //NewTxCache init accountIndex and last cache
...@@ -59,6 +62,8 @@ func (cache *txCache) Remove(hash string) { ...@@ -59,6 +62,8 @@ func (cache *txCache) Remove(hash string) {
} }
cache.AccountTxIndex.Remove(tx) cache.AccountTxIndex.Remove(tx)
cache.LastTxCache.Remove(tx) cache.LastTxCache.Remove(tx)
cache.totalFee -= tx.Fee
cache.totalByte -= int64(proto.Size(tx))
} }
//Exist 是否存在 //Exist 是否存在
...@@ -69,6 +74,14 @@ func (cache *txCache) Exist(hash string) bool { ...@@ -69,6 +74,14 @@ func (cache *txCache) Exist(hash string) bool {
return cache.qcache.Exist(hash) return cache.qcache.Exist(hash)
} }
//GetProperFee 获取合适手续费
func (cache *txCache) GetProperFee() int64 {
if cache.qcache == nil {
return 0
}
return cache.qcache.GetProperFee()
}
//Size cache tx num //Size cache tx num
func (cache *txCache) Size() int { func (cache *txCache) Size() int {
if cache.qcache == nil { if cache.qcache == nil {
...@@ -77,6 +90,16 @@ func (cache *txCache) Size() int { ...@@ -77,6 +90,16 @@ func (cache *txCache) Size() int {
return cache.qcache.Size() return cache.qcache.Size()
} }
//TotalFee 手续费总和
func (cache *txCache) TotalFee() int64 {
return cache.totalFee
}
//TotalByte 交易字节数总和
func (cache *txCache) TotalByte() int64 {
return cache.totalByte
}
//Walk iter all txs //Walk iter all txs
func (cache *txCache) Walk(count int, cb func(tx *Item) bool) { func (cache *txCache) Walk(count int, cb func(tx *Item) bool) {
if cache.qcache == nil { if cache.qcache == nil {
...@@ -107,6 +130,8 @@ func (cache *txCache) Push(tx *types.Transaction) error { ...@@ -107,6 +130,8 @@ func (cache *txCache) Push(tx *types.Transaction) error {
return err return err
} }
cache.LastTxCache.Push(tx) cache.LastTxCache.Push(tx)
cache.totalFee += tx.Fee
cache.totalByte += int64(proto.Size(tx))
return nil return nil
} }
......
...@@ -92,6 +92,13 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message { ...@@ -92,6 +92,13 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message {
msg.Data = err msg.Data = err
return msg return msg
} }
if mem.cfg.IsLevelFee {
err = mem.checkLevelFee(tx)
if err != nil {
msg.Data = err
return msg
}
}
//检查txgroup 中的每个交易 //检查txgroup 中的每个交易
txs, err := tx.GetTxGroup() txs, err := tx.GetTxGroup()
if err != nil { if err != nil {
...@@ -114,7 +121,21 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message { ...@@ -114,7 +121,21 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message {
return msg return msg
} }
//checkTxList 检查账户余额是否足够,并加入到Mempool,成功则传入goodChan,若加入Mempool失败则传入badChan // checkLevelFee 检查阶梯手续费
func (mem *Mempool) checkLevelFee(tx *types.TransactionCache) error {
//获取mempool里所有交易手续费总和
feeRate := mem.GetProperFeeRate()
totalfee, err := tx.GetTotalFee(feeRate)
if err != nil {
return err
}
if tx.Fee < totalfee {
return types.ErrTxFeeTooLow
}
return nil
}
//checkTxRemote 检查账户余额是否足够,并加入到Mempool,成功则传入goodChan,若加入Mempool失败则传入badChan
func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message {
tx := msg.GetData().(types.TxGroup) tx := msg.GetData().(types.TxGroup)
lastheader := mem.GetHeader() lastheader := mem.GetHeader()
......
...@@ -189,9 +189,9 @@ func (mem *Mempool) eventGetAddrTxs(msg *queue.Message) { ...@@ -189,9 +189,9 @@ func (mem *Mempool) eventGetAddrTxs(msg *queue.Message) {
msg.Reply(mem.client.NewMessage("", types.EventReplyAddrTxs, txlist)) msg.Reply(mem.client.NewMessage("", types.EventReplyAddrTxs, txlist))
} }
// eventGetProperFee 获取排队策略中合适的手续费 // eventGetProperFee 获取排队策略中合适的手续费
func (mem *Mempool) eventGetProperFee(msg *queue.Message) { func (mem *Mempool) eventGetProperFee(msg *queue.Message) {
properFee := mem.cache.qcache.GetProperFee() properFee := mem.GetProperFeeRate()
msg.Reply(mem.client.NewMessage("rpc", types.EventReplyProperFee, msg.Reply(mem.client.NewMessage("rpc", types.EventReplyProperFee,
&types.ReplyProperFee{ProperFee: properFee})) &types.ReplyProperFee{ProperFee: properFee}))
} }
......
...@@ -58,6 +58,10 @@ func (cache *SimpleQueue) Push(tx *Item) error { ...@@ -58,6 +58,10 @@ func (cache *SimpleQueue) Push(tx *Item) error {
// Remove 删除数据 // Remove 删除数据
func (cache *SimpleQueue) Remove(hash string) error { func (cache *SimpleQueue) Remove(hash string) error {
_, err := cache.GetItem(hash)
if err != nil {
return err
}
cache.txList.Remove(hash) cache.txList.Remove(hash)
return nil return nil
} }
......
...@@ -68,6 +68,7 @@ type Mempool struct { ...@@ -68,6 +68,7 @@ type Mempool struct {
// 每个账户在mempool中得最大交易数量,默认100 // 每个账户在mempool中得最大交易数量,默认100
MaxTxNumPerAccount int64 `protobuf:"varint,5,opt,name=maxTxNumPerAccount" json:"maxTxNumPerAccount,omitempty"` MaxTxNumPerAccount int64 `protobuf:"varint,5,opt,name=maxTxNumPerAccount" json:"maxTxNumPerAccount,omitempty"`
MaxTxLast int64 `protobuf:"varint,6,opt,name=maxTxLast" json:"maxTxLast,omitempty"` MaxTxLast int64 `protobuf:"varint,6,opt,name=maxTxLast" json:"maxTxLast,omitempty"`
IsLevelFee bool `protobuf:"varint,7,opt,name=isLevelFee" json:"isLevelFee,omitempty"`
} }
// Consensus 配置 // Consensus 配置
...@@ -176,6 +177,8 @@ type P2P struct { ...@@ -176,6 +177,8 @@ type P2P struct {
InnerBounds int32 `protobuf:"varint,15,opt,name=innerBounds" json:"innerBounds,omitempty"` InnerBounds int32 `protobuf:"varint,15,opt,name=innerBounds" json:"innerBounds,omitempty"`
// 是否使用Github获取种子节点 // 是否使用Github获取种子节点
UseGithub bool `protobuf:"varint,16,opt,name=useGithub" json:"useGithub,omitempty"` UseGithub bool `protobuf:"varint,16,opt,name=useGithub" json:"useGithub,omitempty"`
//是否等待Pid
WaitPid bool `protobuf:"varint,17,opt,name=waitPid" json:"waitPid,omitempty"`
} }
// RPC 配置 // RPC 配置
......
...@@ -286,6 +286,12 @@ func Init(t string, cfg *Config) { ...@@ -286,6 +286,12 @@ func Init(t string, cfg *Config) {
panic("config CoinSymbol must without '-'") panic("config CoinSymbol must without '-'")
} }
coinSymbol = cfg.CoinSymbol coinSymbol = cfg.CoinSymbol
} else {
if isPara() {
panic("must config CoinSymbol in para chain")
} else {
coinSymbol = DefaultCoinsSymbol
}
} }
} }
//local 只用于单元测试 //local 只用于单元测试
......
...@@ -33,6 +33,11 @@ const ( ...@@ -33,6 +33,11 @@ const (
NoneX = "none" NoneX = "none"
) )
//DefaultCoinsSymbol 默认的主币名称
const (
DefaultCoinsSymbol = "bty"
)
//UserKeyX 用户自定义执行器前缀byte类型 //UserKeyX 用户自定义执行器前缀byte类型
var ( var (
UserKey = []byte(UserKeyX) UserKey = []byte(UserKeyX)
......
...@@ -2,6 +2,7 @@ Title="user.p.guodun." ...@@ -2,6 +2,7 @@ Title="user.p.guodun."
TestNet=false TestNet=false
FixTime=false FixTime=false
EnableParaFork=true EnableParaFork=true
CoinSymbol="gd"
[log] [log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
...@@ -2,6 +2,7 @@ Title="user.p.guodun2." ...@@ -2,6 +2,7 @@ Title="user.p.guodun2."
TestNet=false TestNet=false
FixTime=false FixTime=false
EnableParaFork=false EnableParaFork=false
CoinSymbol="gd2"
[log] [log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
......
...@@ -348,6 +348,28 @@ func (tx *TransactionCache) Check(height, minfee, maxFee int64) error { ...@@ -348,6 +348,28 @@ func (tx *TransactionCache) Check(height, minfee, maxFee int64) error {
return tx.checkok return tx.checkok
} }
//GetTotalFee 获取交易真实费用
func (tx *TransactionCache) GetTotalFee(minFee int64) (int64, error) {
txgroup, err := tx.GetTxGroup()
if err != nil {
tx.checkok = err
return 0, err
}
var totalfee int64
if txgroup == nil {
return tx.GetRealFee(minFee)
}
txs := txgroup.Txs
for i := 0; i < len(txs); i++ {
fee, err := txs[i].GetRealFee(minFee)
if err != nil {
return 0, err
}
totalfee += fee
}
return totalfee, nil
}
//GetTxGroup 获取交易组 //GetTxGroup 获取交易组
func (tx *TransactionCache) GetTxGroup() (*Transactions, error) { func (tx *TransactionCache) GetTxGroup() (*Transactions, error) {
var err error var err error
......
...@@ -49,6 +49,7 @@ var ( ...@@ -49,6 +49,7 @@ var (
datadir = flag.String("datadir", "", "data dir of chain33, include logs and datas") datadir = flag.String("datadir", "", "data dir of chain33, include logs and datas")
versionCmd = flag.Bool("v", false, "version") versionCmd = flag.Bool("v", false, "version")
fixtime = flag.Bool("fixtime", false, "fix time") fixtime = flag.Bool("fixtime", false, "fix time")
waitPid = flag.Bool("waitpid", false, "p2p stuck until seed save info wallet & wallet unlock")
) )
//RunChain33 : run Chain33 //RunChain33 : run Chain33
...@@ -91,6 +92,9 @@ func RunChain33(name string) { ...@@ -91,6 +92,9 @@ func RunChain33(name string) {
if *fixtime { if *fixtime {
cfg.FixTime = *fixtime cfg.FixTime = *fixtime
} }
if *waitPid {
cfg.P2P.WaitPid = *waitPid
}
//set test net flag //set test net flag
types.Init(cfg.Title, cfg) types.Init(cfg.Title, cfg)
if cfg.FixTime { if cfg.FixTime {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment