Commit f221521c authored by jiangpeng's avatar jiangpeng

merge upstream master

parents 216f5050 d4de6275
......@@ -43,7 +43,7 @@ enableTxQuickIndex=true
# 升级storedb是否重新执行localdb,bityuan主链升级不需要开启,平行链升级需要开启
enableReExecLocal=true
# 使能精简localdb
enableReduceLocaldb=true
enableReduceLocaldb=false
enablePushSubscribe=false
[p2p]
......@@ -94,8 +94,13 @@ coinDevFund=12
coinBaseReward=3
#委托账户最少解绑定时间(按小时)
unBindTime=24
#支持挖矿奖励的1e8小数模式,比如18coin 需要配置成1800000000 以支持小数位后的配置
#decimalMode=true
#支持挖矿奖励的1e8小数模式,比如18coin 需要配置成1800000000 以支持小数位后的配置,如果true,意味着已经打开即coinReward=1800000000
decimalMode=false
#挖矿模式, normal:缺省挖矿,其他自定义,注册名字需要和配置名字保持一致
minerMode="normal"
#挖矿减半周期,按高度减半
halvePeriod=1000
[consensus.sub.para]
#主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“118.31.177.1:8802,39.97.2.127:8802”
......@@ -261,6 +266,8 @@ ForkLoopCheckCommitTxDone=0
#仅平行链适用,自共识分阶段开启,缺省是0,若对应主链高度7200000之前开启过自共识,需要重新配置此分叉,并为之前自共识设置selfConsensEnablePreContract配置项
ForkParaSelfConsStages=0
ForkParaAssetTransferRbk=0
#仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励
ForkParaFullMinerHeight=0
[fork.sub.evm]
Enable=0
......
......@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v1.65.1-0.20201111090506-e2d7705ea453
github.com/33cn/chain33 v1.65.1-0.20210115070259-1e4df1700e2e
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect
......@@ -41,9 +41,10 @@ require (
github.com/tjfoc/gmsm v1.3.2
github.com/valyala/fasthttp v1.5.0
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.uber.org/zap v1.16.0 // indirect
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
google.golang.org/grpc v1.28.0
google.golang.org/grpc v1.29.1
)
This diff is collapsed.
......@@ -124,7 +124,7 @@ func DposPerf() {
fmt.Println("=======start NormPut!=======")
for i := 0; i < loopCount; i++ {
NormPut()
NormPut(cfg)
time.Sleep(time.Second)
}
......@@ -462,7 +462,7 @@ func getprivkey(key string) crypto.PrivKey {
return priv
}
func prepareTxList() *types.Transaction {
func prepareTxList(cfg *types.Chain33Config) *types.Transaction {
var key string
var value string
var i int
......@@ -475,6 +475,7 @@ func prepareTxList() *types.Transaction {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
return tx
}
......@@ -489,8 +490,8 @@ func clearTestData() {
fmt.Println("test data clear successfully!")
}
func NormPut() {
tx := prepareTxList()
func NormPut(cfg *types.Chain33Config) {
tx := prepareTxList(cfg)
reply, err := c.SendTransaction(context.Background(), tx)
if err != nil {
......
......@@ -490,6 +490,10 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T
func (client *commitMsgClient) getExecName(commitHeight int64) string {
cfg := client.paraClient.GetAPI().GetConfig()
if cfg.IsDappFork(commitHeight, pt.ParaX, pt.ForkParaFullMinerHeight) {
return paracross.GetExecName(cfg)
}
if cfg.IsDappFork(commitHeight, pt.ParaX, pt.ForkParaSelfConsStages) {
return paracross.GetExecName(cfg)
}
......
......@@ -165,7 +165,7 @@ func (client *blockSyncClient) batchSyncBlocks() {
}
//没有需要同步的块,清理本地数据库中localCacheCount前的块
if err == nil && curSyncCaughtState {
_, err := client.clearLocalOldBlocks()
err := client.clearLocalOldBlocks()
if err != nil {
client.printError(err)
}
......@@ -289,6 +289,8 @@ func (client *blockSyncClient) delLocalBlocks(startHeight int64, endHeight int64
return errors.New("para sync - startHeight > endHeight,can't clear local blocks")
}
plog.Info("Para sync - clear local blocks", "startHeight:", startHeight, "endHeight:", endHeight)
index := startHeight
set := &types.LocalDBSet{}
cfg := client.paraClient.GetAPI().GetConfig()
......@@ -308,8 +310,6 @@ func (client *blockSyncClient) delLocalBlocks(startHeight int64, endHeight int64
kv := &types.KeyValue{Key: key, Value: types.Encode(&types.Int64{Data: endHeight + 1})}
set.KV = append(set.KV, kv)
client.printDebugInfo("Para sync - clear local blocks", "startHeight:", startHeight, "endHeight:", endHeight)
return client.paraClient.setLocalDb(set)
}
......@@ -356,23 +356,28 @@ func (client *blockSyncClient) getFirstLocalHeight() (int64, error) {
}
//清除指定数量(localCacheCount)以前的区块
func (client *blockSyncClient) clearLocalOldBlocks() (bool, error) {
func (client *blockSyncClient) clearLocalOldBlocks() error {
lastLocalHeight, err := client.paraClient.getLastLocalHeight()
if err != nil {
return false, err
return err
}
firstLocalHeight, err := client.getFirstLocalHeight()
if err != nil {
return false, err
return err
}
canDelCount := lastLocalHeight - firstLocalHeight - client.maxCacheCount + 1
if canDelCount <= client.maxCacheCount {
return false, nil
count := canDelCount / client.maxCacheCount
for i := int64(0); i < count; i++ {
start := firstLocalHeight + i*client.maxCacheCount
end := start + client.maxCacheCount - 1
err = client.delLocalBlocks(start, end)
if err != nil {
return err
}
}
return true, client.delLocalBlocks(firstLocalHeight, firstLocalHeight+canDelCount-1)
return nil
}
// miner tx need all para node create, but not all node has auth account, here just not sign to keep align
......
......@@ -350,13 +350,13 @@ func testCreateGenesisBlock(t *testing.T, para *client, testLoopCount int32) {
//测试清理localdb缓存数据
func testClearLocalOldBlocks(t *testing.T, para *client, testLoopCount int32) {
isCleaned, err := para.blockSyncClient.clearLocalOldBlocks()
err := para.blockSyncClient.clearLocalOldBlocks()
switch testLoopCount {
case 0:
assert.Nil(t, err)
case 1:
assert.Equal(t, true, !isCleaned && err == nil)
assert.Equal(t, true, err == nil)
default: //2
assert.Error(t, err)
}
......
......@@ -19,7 +19,6 @@ import (
"github.com/33cn/chain33/common/limits"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/executor"
"github.com/33cn/chain33/mempool"
"github.com/33cn/chain33/p2p"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/store"
......@@ -47,9 +46,8 @@ func init() {
log.SetLogLevel("info")
}
func TestPbft(t *testing.T) {
q, chain, p2pnet, s, mem, exec, cs, wallet := initEnvPbft()
q, chain, p2pnet, s, exec, cs, wallet := initEnvPbft()
defer chain.Close()
defer mem.Close()
defer p2pnet.Close()
defer exec.Close()
defer s.Close()
......@@ -62,7 +60,7 @@ func TestPbft(t *testing.T) {
clearTestData()
}
func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Module, queue.Module, *executor.Executor, queue.Module, queue.Module) {
func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Module, *executor.Executor, queue.Module, queue.Module) {
flag.Parse()
chain33Cfg := types.NewChain33Config(types.ReadFile("chain33.test.toml"))
var q = queue.New("channel")
......@@ -72,8 +70,6 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod
chain := blockchain.New(chain33Cfg)
chain.SetQueueClient(q.Client())
mem := mempool.New(chain33Cfg)
mem.SetQueueClient(q.Client())
exec := executor.New(chain33Cfg)
exec.SetQueueClient(q.Client())
chain33Cfg.SetMinFee(0)
......@@ -86,7 +82,7 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod
walletm := wallet.New(chain33Cfg)
walletm.SetQueueClient(q.Client())
return q, chain, p2pnet, s, mem, exec, cs, walletm
return q, chain, p2pnet, s, exec, cs, walletm
}
......@@ -97,13 +93,15 @@ func sendReplyList(q queue.Queue) {
for msg := range client.Recv() {
if msg.Ty == types.EventTxList {
count++
createReplyList("test" + strconv.Itoa(count))
createReplyList(client.GetConfig(), "test"+strconv.Itoa(count))
msg.Reply(client.NewMessage("consensus", types.EventReplyTxList,
&types.ReplyTxList{Txs: transactions}))
if count == 5 {
time.Sleep(5 * time.Second)
break
}
} else if msg.Ty == types.EventGetMempoolSize {
msg.Reply(client.NewMessage("", 0, &types.MempoolSize{}))
}
}
}
......@@ -124,7 +122,8 @@ func getprivkey(key string) crypto.PrivKey {
return priv
}
func createReplyList(account string) {
func createReplyList(cfg *types.Chain33Config, account string) {
var result []*types.Transaction
for j := 0; j < txSize; j++ {
//tx := &types.Transaction{}
......@@ -134,6 +133,7 @@ func createReplyList(account string) {
tx.To = "14qViLJfdGaP4EeHnDyJbEGQysnCpwn1gZ"
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
result = append(result, tx)
......
......@@ -334,6 +334,8 @@ func NormPut(privkey string, key string, value string) {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = r.Int63()
version, _ := c.Version(context.Background(), nil)
tx.ChainID = version.ChainID
tx.Sign(types.SECP256K1, getprivkey(privkey))
reply, err := c.SendTransaction(context.Background(), tx)
......
......@@ -440,6 +440,7 @@ func LoadProposer(source *tmtypes.Validator) (*ttypes.Validator, error) {
// CreateBlockInfoTx make blockInfo to the first transaction of the block and execer is valnode
func CreateBlockInfoTx(pubkey string, state *tmtypes.State, block *tmtypes.TendermintBlock) *types.Transaction {
blockSave := *block
blockSave.Data = nil
blockInfo := &tmtypes.TendermintBlockInfo{
......
......@@ -74,13 +74,13 @@ func TendermintPerf(t *testing.T) {
time.Sleep(2 * time.Second)
ConfigManager()
for i := 0; i < loopCount; i++ {
NormPut()
NormPut(q.GetConfig().GetChainID())
time.Sleep(time.Second)
}
CheckState(t, cs.(*Client))
AddNode()
for i := 0; i < loopCount*3; i++ {
NormPut()
NormPut(q.GetConfig().GetChainID())
time.Sleep(time.Second)
}
time.Sleep(2 * time.Second)
......@@ -148,7 +148,7 @@ func generateValue(i, valI int) string {
return string(value)
}
func prepareTxList() *types.Transaction {
func prepareTxList(chainid int32) *types.Transaction {
var key string
var value string
var i int
......@@ -161,6 +161,7 @@ func prepareTxList() *types.Transaction {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = r.Int63()
tx.ChainID = chainid
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
return tx
}
......@@ -173,8 +174,8 @@ func clearTestData() {
fmt.Println("test data clear successfully!")
}
func NormPut() {
tx := prepareTxList()
func NormPut(chainid int32) {
tx := prepareTxList(chainid)
reply, err := c.SendTransaction(context.Background(), tx)
if err != nil {
......@@ -199,6 +200,10 @@ func AddNode() {
tx := &types.Transaction{Execer: []byte("valnode"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("valnode")
tx.Nonce = r.Int63()
version, _ := c.Version(context.Background(), nil)
if version != nil {
tx.ChainID = version.ChainID
}
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
reply, err := c.SendTransaction(context.Background(), tx)
......@@ -221,6 +226,11 @@ func ConfigManager() {
tx := &types.Transaction{Execer: []byte("manage"), Payload: types.Encode(modify), Fee: fee}
tx.To = address.ExecAddress("manage")
tx.Nonce = r.Int63()
version, _ := c.Version(context.Background(), nil)
if version != nil {
tx.ChainID = version.ChainID
}
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
reply, err := c.SendTransaction(context.Background(), tx)
......
......@@ -238,7 +238,7 @@ func DposPerf() {
}
time.Sleep(2 * time.Second)
for i := 0; i < loopCount; i++ {
NormPut()
NormPut(q.GetConfig())
time.Sleep(time.Second)
}
time.Sleep(2 * time.Second)
......@@ -336,8 +336,8 @@ func getprivkey(key string) crypto.PrivKey {
return priv
}
func NormPut() {
tx := prepareTxList()
func NormPut(cfg *types.Chain33Config) {
tx := prepareTxList(cfg)
reply, err := c.SendTransaction(context.Background(), tx)
if err != nil {
......@@ -350,7 +350,8 @@ func NormPut() {
}
}
func prepareTxList() *types.Transaction {
func prepareTxList(cfg *types.Chain33Config) *types.Transaction {
var key string
var value string
var i int
......@@ -363,6 +364,7 @@ func prepareTxList() *types.Transaction {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
tx.Sign(types.SECP256K1, getprivkey(genesisKey))
return tx
}
......
......@@ -43,6 +43,7 @@ func createPingTx(cfg *types.Chain33Config, op string, parm *Tx) (*types.Transac
Payload: types.Encode(action),
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(cfg.ExecName(EchoX)),
ChainID: cfg.GetChainID(),
}
return tx, nil
}
......
......@@ -296,7 +296,7 @@ func createEvmTx(cfg *types.Chain33Config, action proto.Message, execer, caller,
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
txHex := types.Encode(tx)
rawTx := hex.EncodeToString(txHex)
......@@ -348,7 +348,7 @@ func createEvmTransferTx(cfg *types.Chain33Config, cmd *cobra.Command, caller, e
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
txHex := types.Encode(tx)
rawTx := hex.EncodeToString(txHex)
......
......@@ -40,7 +40,7 @@ func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreat
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
......@@ -69,7 +69,7 @@ func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
......@@ -103,7 +103,7 @@ func (c *channelClient) Transfer(ctx context.Context, in evmtypes.EvmContractTra
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
......
......@@ -361,7 +361,7 @@ func testGuessImp(t *testing.T) {
fmt.Println("=======start NormPut!=======")
for i := 0; i < loopCount; i++ {
NormPut()
NormPut(cfg)
time.Sleep(time.Second)
}
......@@ -503,7 +503,7 @@ func getprivkey(key string) crypto.PrivKey {
return priv
}
func prepareTxList() *types.Transaction {
func prepareTxList(cfg *types.Chain33Config) *types.Transaction {
var key string
var value string
var i int
......@@ -516,12 +516,13 @@ func prepareTxList() *types.Transaction {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
return tx
}
func NormPut() {
tx := prepareTxList()
func NormPut(cfg *types.Chain33Config) {
tx := prepareTxList(cfg)
reply, err := c.SendTransaction(context.Background(), tx)
if err != nil {
......
......@@ -363,7 +363,7 @@ func testGuessImp(t *testing.T) {
fmt.Println("=======start NormPut!=======")
for i := 0; i < loopCount; i++ {
NormPut()
NormPut(cfg)
time.Sleep(time.Second)
}
......@@ -721,7 +721,7 @@ func getprivkey(key string) crypto.PrivKey {
return priv
}
func prepareTxList() *types.Transaction {
func prepareTxList(cfg *types.Chain33Config) *types.Transaction {
var key string
var value string
var i int
......@@ -734,12 +734,13 @@ func prepareTxList() *types.Transaction {
tx := &types.Transaction{Execer: []byte("norm"), Payload: types.Encode(action), Fee: fee}
tx.To = address.ExecAddress("norm")
tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID()
tx.Sign(types.SECP256K1, getprivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"))
return tx
}
func NormPut() {
tx := prepareTxList()
func NormPut(cfg *types.Chain33Config) {
tx := prepareTxList(cfg)
reply, err := c.SendTransaction(context.Background(), tx)
if err != nil {
......
......@@ -842,6 +842,7 @@ func paraConfigCmd() *cobra.Command {
Short: "parachain config cmd",
}
cmd.AddCommand(paraStageConfigCmd())
cmd.AddCommand(issueCoinsCmd())
return cmd
}
......@@ -1513,3 +1514,45 @@ func GetConsensDoneInfoCmd() *cobra.Command {
addConsensDoneCmdFlags(cmd)
return cmd
}
func issueCoinsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "issue",
Short: "issue new coins by super manager",
Run: createIssueCoinsTx,
}
addIssueCoinsFlags(cmd)
return cmd
}
func addIssueCoinsFlags(cmd *cobra.Command) {
cmd.Flags().Uint64P("amount", "a", 0, "new issue amount")
cmd.MarkFlagRequired("amount")
}
func createIssueCoinsTx(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
coins, _ := cmd.Flags().GetUint64("amount")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
if coins == 0 {
fmt.Fprintln(os.Stderr, "coins should bigger than 0")
}
payload := &pt.ParacrossMinerAction{AddIssueCoins: int64(coins)}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "Miner",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
......@@ -1254,71 +1254,6 @@ func (a *action) CrossAssetTransfer(transfer *pt.CrossAssetTransfer) (*types.Rec
return receipt, nil
}
//当前miner tx不需要校验上一个区块的衔接性,因为tx就是本节点发出,高度,preHash等都在本区块里面的blockchain做了校验
func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
if miner.Status.Title != cfg.GetTitle() || miner.Status.MainBlockHash == nil {
return nil, pt.ErrParaMinerExecErr
}
var logs []*types.ReceiptLog
var receipt = &pt.ReceiptParacrossMiner{}
log := &types.ReceiptLog{}
log.Ty = pt.TyLogParacrossMiner
receipt.Status = miner.Status
log.Log = types.Encode(receipt)
logs = append(logs, log)
minerReceipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: logs}
//自共识分阶段使能,综合考虑挖矿奖励和共识分配奖励,判断是否自共识使能需要采用共识的高度,而不能采用当前区块高度a.height
//考虑自共识使能区块高度100,如果采用区块高度判断,则在100高度可能收到80~99的20条共识交易,这20条交易在100高度参与共识,则无奖励可分配,而且共识高度将是80而不是100
//采用共识高度miner.Status.Height判断,则严格执行了产生奖励和分配奖励,且共识高度从100开始
isSelfConsensOn := miner.IsSelfConsensus
if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
var err error
isSelfConsensOn, err = isSelfConsOn(a.db, miner.Status.Height)
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
clog.Error("paracross miner getConsensus ", "height", miner.Status.Height, "err", err)
return nil, err
}
}
//自共识后才挖矿
if isSelfConsensOn {
//增发coins到paracross合约中,只处理发放,不做分配
totalReward := int64(0)
coinReward := cfg.MGInt("mver.consensus.paracross.coinReward", a.height)
fundReward := cfg.MGInt("mver.consensus.paracross.coinDevFund", a.height)
if coinReward > 0 {
totalReward += coinReward
}
if fundReward > 0 {
totalReward += fundReward
}
decimalMode := cfg.MIsEnable("mver.consensus.paracross.decimalMode", a.height)
if !decimalMode {
totalReward *= types.Coin
}
if totalReward > 0 {
issueReceipt, err := a.coinsAccount.ExecIssueCoins(a.execaddr, totalReward)
if err != nil {
clog.Error("paracross miner issue err", "height", miner.Status.Height,
"execAddr", a.execaddr, "amount", totalReward)
return nil, err
}
minerReceipt = mergeReceipt(minerReceipt, issueReceipt)
}
}
return minerReceipt, nil
}
func getTitleFrom(exec []byte) ([]byte, error) {
last := bytes.LastIndex(exec, []byte("."))
if last == -1 {
......
......@@ -73,7 +73,7 @@ func (e *Paracross) Exec_CrossAssetTransfer(payload *pt.CrossAssetTransfer, tx *
//Exec_Miner miner tx exec process
func (e *Paracross) Exec_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, index int) (*types.Receipt, error) {
if index != 0 {
if index != 0 && payload.AddIssueCoins <= 0 {
return nil, pt.ErrParaMinerBaseIndex
}
cfg := e.GetAPI().GetConfig()
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/paracross/executor/minerrewards"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
)
//当前miner tx不需要校验上一个区块的衔接性,因为tx就是本节点发出,高度,preHash等都在本区块里面的blockchain做了校验
//note: 平行链的Miner从Height=1开始, 创世区块不挖矿
//因为bug原因,支持手动增发一部分coin到执行器地址,这部分coin不会对现有账户产生影响。因为转账到合约下的coin,同时会存到合约子账户下
func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
//增发coin
if miner.AddIssueCoins > 0 {
return a.addIssueCoins(miner.AddIssueCoins)
}
if miner.Status.Title != cfg.GetTitle() || miner.Status.MainBlockHash == nil {
return nil, pt.ErrParaMinerExecErr
}
var logs []*types.ReceiptLog
var receipt = &pt.ReceiptParacrossMiner{}
log := &types.ReceiptLog{}
log.Ty = pt.TyLogParacrossMiner
receipt.Status = miner.Status
log.Log = types.Encode(receipt)
logs = append(logs, log)
minerReceipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: logs}
on, err := a.isSelfConsensOn(miner)
if err != nil {
return nil, err
}
//自共识后才挖矿
if on {
r, err := a.issueCoins(miner)
if err != nil {
return nil, err
}
minerReceipt = mergeReceipt(minerReceipt, r)
}
return minerReceipt, nil
}
// 主链走None执行器,只在平行链执行,只是平行链的manager 账户允许发行,目前也只是发行到paracross执行器,不会对个人账户任何影响
func (a *action) addIssueCoins(amount int64) (*types.Receipt, error) {
cfg := a.api.GetConfig()
if !isSuperManager(cfg, a.fromaddr) {
return nil, errors.Wrapf(types.ErrNotAllow, "addr=%s,is not super manager", a.fromaddr)
}
issueReceipt, err := a.coinsAccount.ExecIssueCoins(a.execaddr, amount)
if err != nil {
clog.Error("paracross miner issue err", "execAddr", a.execaddr, "amount", amount)
return nil, errors.Wrap(err, "issueCoins")
}
return issueReceipt, nil
}
func (a *action) isSelfConsensOn(miner *pt.ParacrossMinerAction) (bool, error) {
cfg := a.api.GetConfig()
//ForkParaInitMinerHeight高度后,默认全部挖矿,产生在paracross执行器地址,如果自共识分阶段,也只是分阶段奖励,挖矿一直产生
if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaFullMinerHeight) {
return true, nil
}
isSelfConsensOn := miner.IsSelfConsensus
//自共识分阶段使能,综合考虑挖矿奖励和共识分配奖励,判断是否自共识使能需要采用共识的高度,而不能采用当前区块高度a.height
//考虑自共识使能区块高度100,如果采用区块高度判断,则在100高度可能收到80~99的20条共识交易,这20条交易在100高度参与共识,则无奖励可分配,而且共识高度将是80而不是100
//采用共识高度miner.Status.Height判断,则严格执行了产生奖励和分配奖励,且共识高度从100开始
if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaSelfConsStages) {
var err error
isSelfConsensOn, err = isSelfConsOn(a.db, miner.Status.Height)
if err != nil && errors.Cause(err) != pt.ErrKeyNotExist {
clog.Error("paracross miner getConsensus ", "height", miner.Status.Height, "err", err)
return false, err
}
}
return isSelfConsensOn, nil
}
func (a *action) issueCoins(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
mode := cfg.MGStr("mver.consensus.paracross.minerMode", a.height)
if _, ok := minerrewards.MinerRewards[mode]; !ok {
panic("getTotalReward not be set depend on consensus.paracross.minerMode")
}
coinReward, coinFundReward, _ := minerrewards.MinerRewards[mode].GetConfigReward(cfg, a.height)
totalReward := coinReward + coinFundReward
if totalReward > 0 {
issueReceipt, err := a.coinsAccount.ExecIssueCoins(a.execaddr, totalReward)
if err != nil {
clog.Error("paracross miner issue err", "height", miner.Status.Height,
"execAddr", a.execaddr, "amount", totalReward)
return nil, err
}
return issueReceipt, nil
}
return nil, nil
}
package minerrewards
import (
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
)
type normal struct{}
func init() {
register("normal", &normal{})
}
//获取配置的奖励数值
func (n *normal) GetConfigReward(cfg *types.Chain33Config, height int64) (int64, int64, int64) {
coinReward := cfg.MGInt("mver.consensus.paracross.coinReward", height)
fundReward := cfg.MGInt("mver.consensus.paracross.coinDevFund", height)
coinBaseReward := cfg.MGInt("mver.consensus.paracross.coinBaseReward", height)
if coinReward < 0 || fundReward < 0 || coinBaseReward < 0 {
panic("para config consensus.paracross.coinReward should bigger than 0")
}
//decimalMode=false,意味着精简模式,需要乘1e8
decimalMode := cfg.MIsEnable("mver.consensus.paracross.decimalMode", height)
if !decimalMode {
coinReward *= types.Coin
fundReward *= types.Coin
coinBaseReward *= types.Coin
}
//防止coinBaseReward 设置出错场景, coinBaseReward 一定要比coinReward小
if coinBaseReward >= coinReward {
coinBaseReward = coinReward / 10
}
return coinReward, fundReward, coinBaseReward
}
//奖励矿工算法
func (n *normal) RewardMiners(cfg *types.Chain33Config, coinReward int64, miners []string, height int64) ([]*pt.ParaMinerReward, int64) {
//找零
var change int64
var rewards []*pt.ParaMinerReward
//分配给矿工的平均奖励
minerUnit := coinReward / int64(len(miners))
if minerUnit > 0 {
for _, m := range miners {
r := &pt.ParaMinerReward{Addr: m, Amount: minerUnit}
rewards = append(rewards, r)
}
//如果不等分转到发展基金
change = coinReward % minerUnit
}
return rewards, change
}
package minerrewards
import (
"fmt"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
)
type RewardPolicy interface {
GetConfigReward(cfg *types.Chain33Config, height int64) (int64, int64, int64)
RewardMiners(cfg *types.Chain33Config, coinReward int64, miners []string, height int64) ([]*pt.ParaMinerReward, int64)
}
var MinerRewards = make(map[string]RewardPolicy)
func register(ty string, policy RewardPolicy) {
if _, ok := MinerRewards[ty]; ok {
panic(fmt.Sprintf("paracross minerreward ty=%s registered", ty))
}
MinerRewards[ty] = policy
}
......@@ -3,6 +3,8 @@ package executor
import (
"bytes"
"github.com/33cn/plugin/plugin/dapp/paracross/executor/minerrewards"
"github.com/pkg/errors"
dbm "github.com/33cn/chain33/common/db"
......@@ -41,27 +43,35 @@ func (a *action) getBindAddrs(nodes []string, statusHeight int64) (*pt.ParaNodeB
}
func (a *action) rewardSuperNode(coinReward int64, miners []string, statusHeight int64) (*types.Receipt, int64, error) {
//分配给矿工的单位奖励
minerUnit := coinReward / int64(len(miners))
var change int64
cfg := a.api.GetConfig()
receipt := &types.Receipt{Ty: types.ExecOk}
if minerUnit > 0 {
//如果不等分转到发展基金
change = coinReward % minerUnit
for _, addr := range miners {
rep, err := a.coinsAccount.ExecDeposit(addr, a.execaddr, minerUnit)
if err != nil {
clog.Error("paracross super node reward deposit err", "height", statusHeight,
"execAddr", a.execaddr, "minerAddr", addr, "amount", minerUnit, "err", err)
return nil, 0, err
}
receipt = mergeReceipt(receipt, rep)
}
mode := cfg.MGStr("mver.consensus.paracross.minerMode", a.height)
rewards, change := minerrewards.MinerRewards[mode].RewardMiners(cfg, coinReward, miners, statusHeight)
resp, err := a.rewardDeposit(rewards, statusHeight)
if err != nil {
return nil, 0, err
}
receipt = mergeReceipt(receipt, resp)
return receipt, change, nil
}
func (a *action) rewardDeposit(rewards []*pt.ParaMinerReward, statusHeight int64) (*types.Receipt, error) {
receipt := &types.Receipt{}
for _, v := range rewards {
rep, err := a.coinsAccount.ExecDeposit(v.Addr, a.execaddr, v.Amount)
if err != nil {
clog.Error("paracross super node reward deposit err", "height", statusHeight,
"execAddr", a.execaddr, "minerAddr", v.Addr, "amount", v.Amount, "err", err)
return nil, err
}
receipt = mergeReceipt(receipt, rep)
}
return receipt, nil
}
//奖励委托挖矿账户
func (a *action) rewardBindAddr(coinReward int64, bindList *pt.ParaNodeBindList, statusHeight int64) (*types.Receipt, int64, error) {
if coinReward <= 0 {
......@@ -107,24 +117,18 @@ func (a *action) rewardBindAddr(coinReward int64, bindList *pt.ParaNodeBindList,
func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus) (*types.Receipt, error) {
//获取挖矿相关配置,这里需注意是共识的高度,而不是交易的高度
cfg := a.api.GetConfig()
coinReward := cfg.MGInt("mver.consensus.paracross.coinReward", nodeStatus.Height)
fundReward := cfg.MGInt("mver.consensus.paracross.coinDevFund", nodeStatus.Height)
coinBaseReward := cfg.MGInt("mver.consensus.paracross.coinBaseReward", nodeStatus.Height)
decimalMode := cfg.MIsEnable("mver.consensus.paracross.decimalMode", nodeStatus.Height)
if !decimalMode {
coinReward *= types.Coin
fundReward *= types.Coin
coinBaseReward *= types.Coin
//此分叉后 0高度不产生挖矿奖励,也就是以后的新版本默认0高度不产生挖矿奖励
if nodeStatus.Height == 0 && cfg.IsDappFork(nodeStatus.Height, pt.ParaX, pt.ForkParaFullMinerHeight) {
return nil, nil
}
fundAddr := cfg.MGStr("mver.consensus.fundKeyAddr", nodeStatus.Height)
//防止coinBaseReward 设置出错场景, coinBaseReward 一定要比coinReward小
if coinBaseReward >= coinReward {
coinBaseReward = coinReward / 10
mode := cfg.MGStr("mver.consensus.paracross.minerMode", a.height)
if _, ok := minerrewards.MinerRewards[mode]; !ok {
panic("getReward not be set depend on consensus.paracross.minerMode")
}
coinReward, fundReward, coinBaseReward := minerrewards.MinerRewards[mode].GetConfigReward(cfg, nodeStatus.Height)
fundAddr := cfg.MGStr("mver.consensus.fundKeyAddr", nodeStatus.Height)
//超级节点地址
nodeAddrs := getSuperNodes(stat.Details, nodeStatus.BlockHash)
//委托地址
......
......@@ -321,6 +321,12 @@ message ParacrossCommitAction {
message ParacrossMinerAction {
ParacrossNodeStatus status = 1;
bool isSelfConsensus = 2;
int64 addIssueCoins = 3;
}
message ParaMinerReward{
string addr = 1;
int64 amount = 2;
}
message CrossAssetTransfer {
......
......@@ -97,6 +97,7 @@ targetTimePerBlock = 16
[mver.consensus.paracross]
coinReward = 18
coinDevFund = 12
minerMode="normal"
[consensus.sub.para]
......
......@@ -260,6 +260,7 @@ func CreateRawMinerTx(cfg *types.Chain33Config, value *ParacrossMinerAction) (*t
Payload: types.Encode(action),
Nonce: 0, //for consensus purpose, block hash need same, different auth node need keep totally same vote tx
To: address.ExecAddress(cfg.ExecName(ParaX)),
ChainID: cfg.GetChainID(),
}
err := tx.SetRealFee(cfg.GetMinTxFeeRate())
if err != nil {
......
This diff is collapsed.
......@@ -28,6 +28,8 @@ var (
ForkParaSelfConsStages = "ForkParaSelfConsStages"
// ForkParaAssetTransferRbk 平行链资产转移平行链失败主链回滚
ForkParaAssetTransferRbk = "ForkParaAssetTransferRbk"
// ForkParaFullMinerHeight 平行链全挖矿开启高度
ForkParaFullMinerHeight = "ForkParaFullMinerHeight"
// ParaConsSubConf sub
ParaConsSubConf = "consensus.sub.para"
......@@ -59,6 +61,7 @@ func InitFork(cfg *types.Chain33Config) {
//只在平行链启用
cfg.RegisterDappFork(ParaX, ForkParaSelfConsStages, types.MaxHeight)
cfg.RegisterDappFork(ParaX, ForkParaFullMinerHeight, types.MaxHeight)
}
//InitExecutor ...
......
......@@ -537,6 +537,7 @@ func (policy *privacyPolicy) createPublic2PrivacyTx(req *privacytypes.ReqCreateP
Payload: types.Encode(action),
Nonce: policy.getWalletOperate().Nonce(),
To: address.ExecAddress(cfg.ExecName(privacytypes.PrivacyX)),
ChainID: cfg.GetChainID(),
}
tx.SetExpire(cfg, time.Duration(req.Expire))
tx.Signature = &types.Signature{
......@@ -621,6 +622,7 @@ func (policy *privacyPolicy) createPrivacy2PrivacyTx(req *privacytypes.ReqCreate
Fee: privacytypes.PrivacyTxFee,
Nonce: policy.getWalletOperate().Nonce(),
To: address.ExecAddress(cfg.ExecName(privacytypes.PrivacyX)),
ChainID: cfg.GetChainID(),
}
tx.SetExpire(cfg, time.Duration(req.Expire))
if !isMainetCoins {
......@@ -711,6 +713,7 @@ func (policy *privacyPolicy) createPrivacy2PublicTx(req *privacytypes.ReqCreateP
Fee: privacytypes.PrivacyTxFee,
Nonce: policy.getWalletOperate().Nonce(),
To: address.ExecAddress(cfg.ExecName(privacytypes.PrivacyX)),
ChainID: cfg.GetChainID(),
}
tx.SetExpire(cfg, time.Duration(req.Expire))
if !isMainetCoins {
......
......@@ -190,6 +190,7 @@ func (mock *PrivacyMock) CreateUTXOs(sender string, pubkeypair string, amount in
}
func (mock *PrivacyMock) createPublic2PrivacyTx(req *ty.ReqCreatePrivacyTx) *types.Transaction {
cfg := mock.walletOp.GetAPI().GetConfig()
viewPubSlice, spendPubSlice, err := parseViewSpendPubKeyPair(req.GetPubkeypair())
if err != nil {
return nil
......@@ -217,8 +218,8 @@ func (mock *PrivacyMock) createPublic2PrivacyTx(req *ty.ReqCreatePrivacyTx) *typ
Payload: types.Encode(action),
Nonce: mock.walletOp.Nonce(),
To: address.ExecAddress(ty.PrivacyX),
ChainID: cfg.GetChainID(),
}
cfg := mock.walletOp.GetAPI().GetConfig()
txSize := types.Size(tx) + ty.SignatureSize
realFee := int64((txSize+1023)>>ty.Size1Kshiftlen) * cfg.GetMinTxFeeRate()
tx.Fee = realFee
......
......@@ -318,17 +318,23 @@ func (r *Relayd) syncBlockHeaders() {
}
func (r *Relayd) transaction(payload []byte) *types.Transaction {
var chainID int32
minFee := types.DefaultMinFee
//chain33的配置中获取chainID和minFee
if r.config.Chain33Cfg != nil {
chainID = r.config.Chain33Cfg.GetChainID()
minFee = r.config.Chain33Cfg.GetMinTxFeeRate()
}
tx := &types.Transaction{
Execer: []byte(ty.RelayX),
Payload: payload,
Nonce: rand.Int63(),
To: address.ExecAddress(ty.RelayX),
ChainID: chainID,
}
minFee := types.DefaultMinFee
if r.config.Chain33Cfg != nil {
minFee = r.config.Chain33Cfg.GetMinTxFeeRate()
}
fee, _ := tx.GetRealFee(minFee)
tx.Fee = fee
tx.Sign(types.SECP256K1, r.privateKey)
......
......@@ -139,6 +139,7 @@ func (s *suiteRelay) TestExec_1() {
tx.Execer = []byte(ty.RelayX)
tx.To = address.ExecAddress(ty.RelayX)
tx.Nonce = 1 //for different order id
tx.ChainID = chainTestCfg.GetChainID()
tx.Payload = types.Encode(sell)
tx.Sign(types.SECP256K1, privFrom)
......@@ -489,6 +490,8 @@ func (s *suiteBtcHeader) TestSaveBtcHead_1() {
tx.Execer = []byte(ty.RelayX)
tx.To = address.ExecAddress(ty.RelayX)
tx.Nonce = 2 //for different order id
tx.ChainID = chainTestCfg.GetChainID()
tx.Payload = types.Encode(sell)
tx.Sign(types.SECP256K1, privFrom)
......
......@@ -164,12 +164,14 @@ func TestPrecreate(t *testing.T) {
Ty: pty.TokenActionPreCreate,
Value: &pty.TokenAction_TokenPreCreate{TokenPreCreate: v},
}
version, _ := mainClient.Version(context.Background(), nil)
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(precreate),
Fee: feeForToken,
Nonce: r.Int63(),
To: address.ExecAddress(execName),
ChainID: version.GetChainID(),
}
tx.Sign(types.SECP256K1, privkey)
......@@ -205,12 +207,15 @@ func TestFinish(t *testing.T) {
Ty: pty.TokenActionFinishCreate,
Value: &pty.TokenAction_TokenFinishCreate{TokenFinishCreate: v},
}
version, _ := mainClient.Version(context.Background(), nil)
tx := &types.Transaction{
Execer: []byte(execName),
Payload: types.Encode(finish),
Fee: feeForToken,
Nonce: r.Int63(),
To: address.ExecAddress(execName),
ChainID: version.GetChainID(),
}
tx.Sign(types.SECP256K1, privkey)
......@@ -246,6 +251,9 @@ func TestTransferToken(t *testing.T) {
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
version, _ := mainClient.Version(context.Background(), nil)
tx.ChainID = version.GetChainID()
tx.Sign(types.SECP256K1, privkey)
reply, err := mainClient.SendTransaction(context.Background(), tx)
......@@ -326,6 +334,10 @@ func TestTokenMint(t *testing.T) {
tx := &types.Transaction{Execer: []byte(execName), Payload: types.Encode(transfer), Fee: fee, To: addrexec}
tx.Nonce = r.Int63()
version, _ := mainClient.Version(context.Background(), nil)
tx.ChainID = version.GetChainID()
tx.Sign(types.SECP256K1, privkey)
reply, err := mainClient.SendTransaction(context.Background(), tx)
......
......@@ -147,6 +147,7 @@ func CreateUnfreezeCreateTx(cfg *types.Chain33Config, title string, parm *Unfree
Payload: types.Encode(create),
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
ChainID: cfg.GetChainID(),
}
tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil
......@@ -176,6 +177,7 @@ func CreateUnfreezeWithdrawTx(cfg *types.Chain33Config, title string, parm *Unfr
Payload: types.Encode(withdraw),
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
ChainID: cfg.GetChainID(),
}
tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil
......@@ -205,6 +207,7 @@ func CreateUnfreezeTerminateTx(cfg *types.Chain33Config, title string, parm *Unf
Payload: types.Encode(terminate),
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
ChainID: cfg.GetChainID(),
}
tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil
......
......@@ -74,7 +74,6 @@ func (w *Wasm) Exec_Create(payload *types2.WasmCreate, tx *types.Transaction, in
}
func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index int) (*types.Receipt, error) {
log.Info("into wasm Exec_Call...")
if payload == nil {
return nil, types.ErrInvalidParam
}
......@@ -83,18 +82,26 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
}
w.stateKVC = dapp.NewKVCreator(w.GetStateDB(), calcStatePrefix(payload.Contract), nil)
code, err := w.stateKVC.GetNoPrefix(contractKey(payload.Contract))
if err != nil {
return nil, err
}
vm, err := exec.NewVirtualMachine(code, exec.VMConfig{
DefaultMemoryPages: 128,
DefaultTableSize: 128,
DisableFloatingPoint: true,
GasLimit: uint64(tx.Fee),
}, new(Resolver), &compiler.SimpleGasPolicy{GasPerInstruction: 1})
if err != nil {
return nil, err
var vm *exec.VirtualMachine
var ok bool
if vm, ok = w.VMCache[payload.Contract]; !ok {
code, err := w.stateKVC.GetNoPrefix(contractKey(payload.Contract))
if err != nil {
return nil, err
}
vm, err = exec.NewVirtualMachine(code, exec.VMConfig{
DefaultMemoryPages: 128,
DefaultTableSize: 128,
DisableFloatingPoint: true,
GasLimit: uint64(tx.Fee),
}, new(Resolver), &compiler.SimpleGasPolicy{GasPerInstruction: 1})
if err != nil {
return nil, err
}
w.VMCache[payload.Contract] = vm
} else {
vm.Config.GasLimit = uint64(tx.Fee)
vm.Gas = 0
}
// Get the function ID of the entry function to be executed.
......@@ -115,7 +122,6 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
if err != nil {
return nil, err
}
var kvs []*types.KeyValue
kvs = append(kvs, w.kvs...)
kvs = append(kvs, w.stateKVC.KVList()...)
......@@ -124,7 +130,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogWasmCall, Log: types.Encode(&types2.CallContractLog{
Contract: payload.Contract,
Method: payload.Method,
Result: ret,
Result: int32(ret),
})})
logs = append(logs, w.receiptLogs...)
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogCustom, Log: types.Encode(&types2.CustomLog{
......@@ -142,7 +148,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
KV: kvs,
Logs: logs,
}
if ret < 0 {
if int32(ret) < 0 || int16(ret) < 0 {
receipt.Ty = types.ExecPack
}
......
......@@ -6,6 +6,7 @@ import (
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
"github.com/perlin-network/life/exec"
)
var driverName = types2.WasmX
......@@ -36,10 +37,13 @@ type Wasm struct {
customLogs []string
execAddr string
contractName string
VMCache map[string]*exec.VirtualMachine
}
func newWasm() drivers.Driver {
d := &Wasm{}
d := &Wasm{
VMCache: make(map[string]*exec.VirtualMachine),
}
d.SetChild(d)
d.SetExecutorType(types.LoadExecutorType(driverName))
return d
......
package executor
import (
"encoding/hex"
"io/ioutil"
"strings"
"testing"
......@@ -41,10 +42,54 @@ func init() {
Init(types2.WasmX, cfg, nil)
}
func BenchmarkWasm_Exec_Call(b *testing.B) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
acc := initAccount(ldb)
testCreate(b, acc, kvdb)
testCall(b, acc, kvdb)
payload := types2.WasmAction{
Ty: types2.WasmActionCall,
Value: &types2.WasmAction_Call{
Call: &types2.WasmCall{
Contract: "dice",
Method: "play",
Parameters: []int64{1, 10},
},
},
}
tx := &types.Transaction{
Payload: types.Encode(&payload),
}
tx, err := types.FormatTx(cfg, types2.WasmX, tx)
require.Nil(b, err, "format tx error")
err = signTx(tx, PrivKeys[1])
require.Nil(b, err)
wasm := newWasm()
wasm.SetCoinsAccount(acc)
wasm.SetStateDB(kvdb)
api := mocks.QueueProtocolAPI{}
api.On("GetConfig").Return(cfg)
api.On("GetRandNum", mock.Anything).Return(hex.DecodeString("0x0b1f047927e1c42327bdd3222558eaf7b10b998e7a9bb8144e4b2a27ffa53df3"))
wasm.SetAPI(&api)
wasmCB = wasm.(*Wasm)
err = transferToExec(Addrs[1], wasmAddr, 1e9)
require.Nil(b, err)
wasmCB = nil
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := wasm.Exec(tx, 0)
require.Nil(b, err)
}
b.StopTimer()
}
func TestWasm_Exec(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
acc := initAccount(t, ldb)
acc := initAccount(ldb)
testCreate(t, acc, kvdb)
testCall(t, acc, kvdb)
......@@ -54,7 +99,7 @@ func TestWasm_Callback(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
wasmCB = newWasm().(*Wasm)
acc := initAccount(t, ldb)
acc := initAccount(ldb)
wasmCB.SetCoinsAccount(acc)
wasmCB.SetStateDB(kvdb)
wasmCB.SetLocalDB(kvdb)
......@@ -218,7 +263,7 @@ func TestWasm_Callback(t *testing.T) {
t.Log(random)
}
func testCreate(t *testing.T, acc *account.DB, stateDB db.KV) {
func testCreate(t testing.TB, acc *account.DB, stateDB db.KV) {
code, err := ioutil.ReadFile("../contracts/dice/dice.wasm")
require.Nil(t, err, "read wasm file error")
payload := types2.WasmAction{
......@@ -253,7 +298,7 @@ func testCreate(t *testing.T, acc *account.DB, stateDB db.KV) {
require.Nil(t, err)
}
func testCall(t *testing.T, acc *account.DB, stateDB db.KV) {
func testCall(t testing.TB, acc *account.DB, stateDB db.KV) {
payload := types2.WasmAction{
Ty: types2.WasmActionCall,
Value: &types2.WasmAction_Call{
......@@ -287,10 +332,12 @@ func testCall(t *testing.T, acc *account.DB, stateDB db.KV) {
require.Equal(t, int32(types2.TyLogWasmCall), receipt.Logs[0].Ty)
}
func initAccount(t *testing.T, db db.KV) *account.DB {
func initAccount(db db.KV) *account.DB {
wasmAddr = address.ExecAddress(cfg.ExecName(types2.WasmX))
acc, err := account.NewAccountDB(cfg, "coins", "bty", db)
require.Nil(t, err, "new account db error")
if err != nil {
panic(err)
}
acc.SaveAccount(&types.Account{
Balance: 1e10,
Addr: Addrs[0],
......
......@@ -37,7 +37,7 @@ message createContractLog {
message callContractLog {
string contract = 1;
string method = 2;
int64 result = 3;
int32 result = 3;
}
message localDataLog {
......
......@@ -339,7 +339,7 @@ func (m *CreateContractLog) GetCode() string {
type CallContractLog struct {
Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Result int64 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"`
Result int32 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -384,7 +384,7 @@ func (m *CallContractLog) GetMethod() string {
return ""
}
func (m *CallContractLog) GetResult() int64 {
func (m *CallContractLog) GetResult() int32 {
if m != nil {
return m.Result
}
......@@ -454,26 +454,26 @@ func init() {
}
var fileDescriptor_7d78909ad64e3bbb = []byte{
// 328 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x31, 0x4f, 0xc3, 0x30,
0x10, 0x85, 0x9b, 0xba, 0x0d, 0xcd, 0x51, 0x51, 0x6a, 0xa1, 0x2a, 0x62, 0x80, 0xc8, 0x12, 0x52,
0x24, 0xa4, 0x0e, 0x80, 0x58, 0x98, 0xa0, 0x0c, 0x1d, 0x98, 0xbc, 0x83, 0x64, 0x5c, 0x43, 0xab,
0x3a, 0x71, 0x71, 0x2e, 0xa0, 0xfc, 0x7b, 0x64, 0xc7, 0x45, 0x19, 0x10, 0x03, 0xdb, 0xdd, 0xf9,
0xbb, 0xf7, 0x72, 0x77, 0x01, 0xf8, 0x12, 0x55, 0x31, 0xdf, 0x59, 0x83, 0x86, 0x0e, 0xb1, 0xd9,
0xa9, 0x8a, 0x35, 0x6d, 0xf1, 0x5e, 0xe2, 0xc6, 0x94, 0xf4, 0x12, 0x62, 0x69, 0x95, 0x40, 0x95,
0x46, 0x59, 0x94, 0x1f, 0x5e, 0x4d, 0xe7, 0x9e, 0x9a, 0x3b, 0x64, 0xe1, 0x1f, 0x96, 0x3d, 0x1e,
0x10, 0x7a, 0x01, 0x03, 0x29, 0xb4, 0x4e, 0xfb, 0x1e, 0x9d, 0x74, 0x51, 0xa1, 0xf5, 0xb2, 0xc7,
0xfd, 0x33, 0x3d, 0x82, 0x3e, 0x36, 0x29, 0xc9, 0xa2, 0x7c, 0xc8, 0xfb, 0xd8, 0x3c, 0x1c, 0xc0,
0xf0, 0x53, 0xe8, 0x5a, 0xb1, 0x9b, 0xd6, 0xba, 0xd5, 0xa5, 0x14, 0x06, 0xa5, 0x28, 0x5a, 0xe3,
0x84, 0xfb, 0xd8, 0xd5, 0xa4, 0x59, 0x29, 0xef, 0x30, 0xe6, 0x3e, 0x66, 0x2f, 0x30, 0xda, 0x5b,
0xd0, 0x53, 0x18, 0x49, 0x53, 0xa2, 0x15, 0x12, 0x43, 0xdf, 0x4f, 0x4e, 0x67, 0x10, 0x17, 0x0a,
0xd7, 0x66, 0xe5, 0xbb, 0x13, 0x1e, 0x32, 0x7a, 0x06, 0xb0, 0x13, 0x56, 0x14, 0x0a, 0x95, 0xad,
0x52, 0x92, 0x91, 0x9c, 0xf0, 0x4e, 0x85, 0xe5, 0x40, 0x3f, 0x6a, 0x65, 0x9b, 0xc5, 0x5a, 0xc9,
0xed, 0x62, 0xaf, 0xf6, 0xcb, 0xd7, 0xb1, 0x73, 0x48, 0x64, 0x5d, 0xa1, 0x29, 0x9e, 0xcc, 0xbb,
0x03, 0x36, 0xe5, 0x9b, 0x49, 0xa3, 0x8c, 0x38, 0xc0, 0xc5, 0xec, 0x0e, 0xa6, 0xed, 0xaa, 0xf6,
0x32, 0x01, 0xfc, 0x73, 0xce, 0x24, 0xcc, 0xf9, 0x0c, 0x13, 0xb7, 0xbe, 0x6e, 0xeb, 0x7f, 0xc6,
0x9d, 0x41, 0x6c, 0x55, 0x55, 0x6b, 0xf4, 0x17, 0x20, 0x3c, 0x64, 0xec, 0x16, 0xc6, 0xda, 0x48,
0xa1, 0x1f, 0x05, 0x0a, 0xa7, 0x7d, 0x0c, 0x64, 0xab, 0x1a, 0x2f, 0x3b, 0xe6, 0x2e, 0xa4, 0x27,
0xe1, 0x4e, 0x61, 0xfb, 0x6d, 0xf2, 0x1a, 0xfb, 0xbf, 0xe7, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff,
0x24, 0x00, 0xa4, 0xe6, 0x4b, 0x02, 0x00, 0x00,
// 327 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x4f, 0x4b, 0xc3, 0x40,
0x10, 0xc5, 0x9b, 0xa6, 0x8d, 0xcd, 0x58, 0xac, 0x5d, 0xa4, 0x04, 0x0f, 0x1a, 0x16, 0x84, 0x80,
0xd0, 0x83, 0x8a, 0x17, 0x4f, 0x5a, 0x0f, 0x3d, 0x78, 0xda, 0xbb, 0xc2, 0xba, 0x5d, 0x6d, 0xe9,
0x26, 0x5b, 0x37, 0x13, 0x25, 0xdf, 0x5e, 0xf6, 0x4f, 0x25, 0x07, 0xf1, 0xe0, 0x6d, 0x66, 0xf6,
0x37, 0xef, 0x65, 0x66, 0x02, 0xf0, 0xc5, 0xeb, 0x72, 0xbe, 0x33, 0x1a, 0x35, 0x19, 0x62, 0xbb,
0x93, 0x35, 0x6d, 0x7d, 0xf1, 0x5e, 0xe0, 0x46, 0x57, 0xe4, 0x12, 0x12, 0x61, 0x24, 0x47, 0x99,
0x45, 0x79, 0x54, 0x1c, 0x5e, 0x4d, 0xe7, 0x8e, 0x9a, 0x5b, 0x64, 0xe1, 0x1e, 0x96, 0x3d, 0x16,
0x10, 0x72, 0x01, 0x03, 0xc1, 0x95, 0xca, 0xfa, 0x0e, 0x9d, 0x74, 0x51, 0xae, 0xd4, 0xb2, 0xc7,
0xdc, 0x33, 0x39, 0x82, 0x3e, 0xb6, 0x59, 0x9c, 0x47, 0xc5, 0x90, 0xf5, 0xb1, 0x7d, 0x38, 0x80,
0xe1, 0x27, 0x57, 0x8d, 0xa4, 0x37, 0xde, 0xda, 0xeb, 0x12, 0x02, 0x83, 0x8a, 0x97, 0xde, 0x38,
0x65, 0x2e, 0xb6, 0x35, 0xa1, 0x57, 0xd2, 0x39, 0x8c, 0x99, 0x8b, 0xe9, 0x0b, 0x8c, 0xf6, 0x16,
0xe4, 0x14, 0x46, 0x42, 0x57, 0x68, 0xb8, 0xc0, 0xd0, 0xf7, 0x93, 0x93, 0x19, 0x24, 0xa5, 0xc4,
0xb5, 0x5e, 0xb9, 0xee, 0x94, 0x85, 0x8c, 0x9c, 0x01, 0xec, 0xb8, 0xe1, 0xa5, 0x44, 0x69, 0xea,
0x2c, 0xce, 0xe3, 0x22, 0x66, 0x9d, 0x0a, 0x2d, 0x80, 0x7c, 0x34, 0xd2, 0xb4, 0x8b, 0xb5, 0x14,
0xdb, 0xc5, 0x5e, 0xed, 0x97, 0xaf, 0xa3, 0xe7, 0x90, 0x8a, 0xa6, 0x46, 0x5d, 0x3e, 0xe9, 0x77,
0x0b, 0x6c, 0xaa, 0x37, 0x9d, 0x45, 0x79, 0x6c, 0x01, 0x1b, 0xd3, 0x3b, 0x98, 0xfa, 0x55, 0xed,
0x65, 0x02, 0xf8, 0xe7, 0x9c, 0x69, 0x98, 0xf3, 0x19, 0x26, 0x76, 0x7d, 0xdd, 0xd6, 0xff, 0x8c,
0x3b, 0x83, 0xc4, 0xc8, 0xba, 0x51, 0x18, 0x2e, 0x10, 0x32, 0x7a, 0x0b, 0x63, 0xa5, 0x05, 0x57,
0x8f, 0x1c, 0xb9, 0xd5, 0x3e, 0x86, 0x78, 0x2b, 0x5b, 0x27, 0x3b, 0x66, 0x36, 0x24, 0x27, 0xe1,
0x4e, 0x61, 0xfb, 0x3e, 0x79, 0x4d, 0xdc, 0xdf, 0x73, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xc3,
0xc2, 0x9e, 0xbb, 0x4b, 0x02, 0x00, 0x00,
}
......@@ -75,6 +75,7 @@ func (x *suiteX2Ethereum) SetupSuite() {
tx.Execer = []byte(types2.X2ethereumX)
tx.To = address.ExecAddress(types2.X2ethereumX)
tx.Nonce = 1
tx.ChainID = chainTestCfg.GetChainID()
tx.Sign(types.SECP256K1, privFrom)
x.action = newAction(x2eth, tx, 0)
......
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