Commit 991f1f38 authored by heyubin's avatar heyubin

Merge branch 'master' into multisig

parents 04d2dd7b 6e169f63
...@@ -212,12 +212,12 @@ func (client *Client) setTicket(tlist *ty.ReplyTicketList, privmap map[string]cr ...@@ -212,12 +212,12 @@ func (client *Client) setTicket(tlist *ty.ReplyTicketList, privmap map[string]cr
func (client *Client) flushTicket() error { func (client *Client) flushTicket() error {
//list accounts //list accounts
tickets, privs, err := client.getTickets() tickets, privs, err := client.getTickets()
if err == types.ErrMinerNotStared { if err == types.ErrWalletIsLocked {
tlog.Error("flushTicket error", "err", "wallet miner not start") tlog.Error("flushTicket error", "err", "wallet is locked")
client.setTicket(nil, nil) client.setTicket(nil, nil)
return nil return nil
} }
if err != nil && err != types.ErrMinerNotStared { if err != nil {
tlog.Error("flushTicket error", "err", err) tlog.Error("flushTicket error", "err", err)
return err return err
} }
......
...@@ -131,15 +131,19 @@ func (mdb *MemoryStateDB) GetBalance(addr string) uint64 { ...@@ -131,15 +131,19 @@ func (mdb *MemoryStateDB) GetBalance(addr string) uint64 {
isExec := mdb.Exist(addr) isExec := mdb.Exist(addr)
var ac *types.Account var ac *types.Account
if isExec { if isExec {
contract := mdb.GetAccount(addr) if types.IsDappFork(mdb.GetBlockHeight(), "evm", evmtypes.ForkEVMFrozen) {
if contract == nil { ac = mdb.CoinsAccount.LoadExecAccount(addr, addr)
return 0 } else {
} contract := mdb.GetAccount(addr)
creator := contract.GetCreator() if contract == nil {
if len(creator) == 0 { return 0
return 0 }
creator := contract.GetCreator()
if len(creator) == 0 {
return 0
}
ac = mdb.CoinsAccount.LoadExecAccount(creator, addr)
} }
ac = mdb.CoinsAccount.LoadExecAccount(creator, addr)
} else { } else {
ac = mdb.CoinsAccount.LoadAccount(addr) ac = mdb.CoinsAccount.LoadAccount(addr)
} }
...@@ -439,6 +443,7 @@ func (mdb *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) b ...@@ -439,6 +443,7 @@ func (mdb *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) b
case NoNeed: case NoNeed:
return true return true
case ToExec: case ToExec:
// 无论其它账户还是创建者向合约地址转账,都需要检查其当前合约账户活动余额是否充足
accFrom := mdb.CoinsAccount.LoadExecAccount(sender, recipient) accFrom := mdb.CoinsAccount.LoadExecAccount(sender, recipient)
b := accFrom.GetBalance() - value b := accFrom.GetBalance() - value
if b < 0 { if b < 0 {
...@@ -452,8 +457,7 @@ func (mdb *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) b ...@@ -452,8 +457,7 @@ func (mdb *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) b
return false return false
} }
} }
func (mdb *MemoryStateDB) checkExecAccount(execAddr string, value int64) bool {
func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
var err error var err error
defer func() { defer func() {
if err != nil { if err != nil {
...@@ -465,7 +469,7 @@ func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool { ...@@ -465,7 +469,7 @@ func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
err = types.ErrAmount err = types.ErrAmount
return false return false
} }
contract := mdb.GetAccount(addr) contract := mdb.GetAccount(execAddr)
if contract == nil { if contract == nil {
err = model.ErrAddrNotExists err = model.ErrAddrNotExists
return false return false
...@@ -476,9 +480,16 @@ func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool { ...@@ -476,9 +480,16 @@ func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
return false return false
} }
accFrom := mdb.CoinsAccount.LoadExecAccount(contract.GetCreator(), addr) var accFrom *types.Account
b := accFrom.GetBalance() - value if types.IsDappFork(mdb.GetBlockHeight(), "evm", evmtypes.ForkEVMFrozen) {
if b < 0 { // 分叉后,需要检查合约地址下的金额是否足够
accFrom = mdb.CoinsAccount.LoadExecAccount(execAddr, execAddr)
} else {
accFrom = mdb.CoinsAccount.LoadExecAccount(creator, execAddr)
}
balance := accFrom.GetBalance()
remain := balance - value
if remain < 0 {
err = types.ErrNoBalance err = types.ErrNoBalance
return false return false
} }
...@@ -600,17 +611,28 @@ func (mdb *MemoryStateDB) transfer2Contract(sender, recipient string, amount int ...@@ -600,17 +611,28 @@ func (mdb *MemoryStateDB) transfer2Contract(sender, recipient string, amount int
} }
execAddr := recipient execAddr := recipient
// 从自己的合约账户到创建者的合约账户
// 有可能是外部账户调用自己创建的合约,这种情况下这一步可以省略
ret = &types.Receipt{} ret = &types.Receipt{}
if strings.Compare(sender, creator) != 0 {
rs, err := mdb.CoinsAccount.ExecTransfer(sender, creator, execAddr, amount) if types.IsDappFork(mdb.GetBlockHeight(), "evm", evmtypes.ForkEVMFrozen) {
// 用户向合约转账时,将钱转到合约地址下execAddr:execAddr
rs, err := mdb.CoinsAccount.ExecTransfer(sender, execAddr, execAddr, amount)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret.KV = append(ret.KV, rs.KV...) ret.KV = append(ret.KV, rs.KV...)
ret.Logs = append(ret.Logs, rs.Logs...) ret.Logs = append(ret.Logs, rs.Logs...)
} else {
if strings.Compare(sender, creator) != 0 {
// 用户向合约转账时,首先将钱转到创建者合约地址下
rs, err := mdb.CoinsAccount.ExecTransfer(sender, creator, execAddr, amount)
if err != nil {
return nil, err
}
ret.KV = append(ret.KV, rs.KV...)
ret.Logs = append(ret.Logs, rs.Logs...)
}
} }
return ret, nil return ret, nil
...@@ -631,24 +653,22 @@ func (mdb *MemoryStateDB) transfer2External(sender, recipient string, amount int ...@@ -631,24 +653,22 @@ func (mdb *MemoryStateDB) transfer2External(sender, recipient string, amount int
execAddr := sender execAddr := sender
// 第一步先从创建者的合约账户到接受者的合约账户 if types.IsDappFork(mdb.GetBlockHeight(), "evm", evmtypes.ForkEVMFrozen) {
// 如果是自己调用自己创建的合约,这一步也可以省略 // 合约向用户地址转账时,从合约地址下的钱中转出到用户合约地址
if strings.Compare(creator, recipient) != 0 { ret, err = mdb.CoinsAccount.ExecTransfer(execAddr, recipient, execAddr, amount)
ret, err = mdb.CoinsAccount.ExecTransfer(creator, recipient, execAddr, amount)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else {
// 第一步先从创建者的合约账户到接受者的合约账户
// 如果是自己调用自己创建的合约,这一步也可以省略
if strings.Compare(creator, recipient) != 0 {
ret, err = mdb.CoinsAccount.ExecTransfer(creator, recipient, execAddr, amount)
if err != nil {
return nil, err
}
}
} }
// 第二步再从接收者的合约账户取款到接受者账户
// 本操作不允许,需要外部操作coins账户
//rs, err := mdb.CoinsAccount.TransferWithdraw(recipient.String(), sender.String(), amount)
//if err != nil {
// return nil, err
//}
//
//ret = mdb.mergeResult(ret, rs)
return ret, nil return ret, nil
} }
......
...@@ -38,6 +38,8 @@ func init() { ...@@ -38,6 +38,8 @@ func init() {
types.RegisterDappFork(ExecutorName, ForkEVMKVHash, 1000000) types.RegisterDappFork(ExecutorName, ForkEVMKVHash, 1000000)
// EVM合约支持ABI绑定和调用 // EVM合约支持ABI绑定和调用
types.RegisterDappFork(ExecutorName, ForkEVMABI, 1250000) types.RegisterDappFork(ExecutorName, ForkEVMABI, 1250000)
// EEVM合约用户金额冻结
types.RegisterDappFork(ExecutorName, ForkEVMFrozen, 1300000)
} }
// EvmType EVM类型定义 // EvmType EVM类型定义
......
...@@ -38,6 +38,8 @@ const ( ...@@ -38,6 +38,8 @@ const (
ForkEVMKVHash = "ForkEVMKVHash" ForkEVMKVHash = "ForkEVMKVHash"
// ForkEVMABI EVM合约支持ABI绑定和调用 // ForkEVMABI EVM合约支持ABI绑定和调用
ForkEVMABI = "ForkEVMABI" ForkEVMABI = "ForkEVMABI"
// ForkEVMFrozen EVM合约用户金额冻结
ForkEVMFrozen = "ForkEVMFrozen"
) )
var ( var (
......
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
ty "github.com/33cn/plugin/plugin/dapp/ticket/types" ty "github.com/33cn/plugin/plugin/dapp/ticket/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
context "golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
...@@ -127,6 +127,8 @@ func TestJrpc_GetTicketCount(t *testing.T) { ...@@ -127,6 +127,8 @@ func TestJrpc_GetTicketCount(t *testing.T) {
func TestRPC_CallTestNode(t *testing.T) { func TestRPC_CallTestNode(t *testing.T) {
api := new(mocks.QueueProtocolAPI) api := new(mocks.QueueProtocolAPI)
cfg, sub := testnode.GetDefaultConfig() cfg, sub := testnode.GetDefaultConfig()
// 测试环境下,默认配置的共识为solo,需要修改
cfg.Consensus.Name = "ticket"
mock33 := testnode.NewWithConfig(cfg, sub, api) mock33 := testnode.NewWithConfig(cfg, sub, api)
defer func() { defer func() {
mock33.Close() mock33.Close()
......
...@@ -7,6 +7,7 @@ package wallet ...@@ -7,6 +7,7 @@ package wallet
import ( import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
...@@ -221,6 +222,7 @@ func (policy *ticketPolicy) SignTransaction(key crypto.PrivKey, req *types.ReqSi ...@@ -221,6 +222,7 @@ func (policy *ticketPolicy) SignTransaction(key crypto.PrivKey, req *types.ReqSi
func (policy *ticketPolicy) OnWalletLocked() { func (policy *ticketPolicy) OnWalletLocked() {
// 钱包锁住时,不允许挖矿 // 钱包锁住时,不允许挖矿
atomic.CompareAndSwapInt32(&policy.isTicketLocked, 0, 1) atomic.CompareAndSwapInt32(&policy.isTicketLocked, 0, 1)
FlushTicket(policy.getAPI())
} }
//解锁超时处理,需要区分整个钱包的解锁或者只挖矿的解锁 //解锁超时处理,需要区分整个钱包的解锁或者只挖矿的解锁
...@@ -768,6 +770,17 @@ func (policy *ticketPolicy) autoMining() { ...@@ -768,6 +770,17 @@ func (policy *ticketPolicy) autoMining() {
defer bizlog.Info("End auto mining") defer bizlog.Info("End auto mining")
operater := policy.getWalletOperate() operater := policy.getWalletOperate()
defer operater.GetWaitGroup().Done() defer operater.GetWaitGroup().Done()
// 只有ticket共识下ticket相关的操作才有效
q := types.Conf("config.consensus")
if q != nil {
cons := q.GStr("name")
if strings.Compare(strings.TrimSpace(cons), ty.TicketX) != 0 {
bizlog.Info("consensus is not ticket, exit mining")
return
}
}
lastHeight := int64(0) lastHeight := int64(0)
miningTicketTicker := policy.getMingTicketTicker() miningTicketTicker := policy.getMingTicketTicker()
for { for {
......
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