Skip to content

Commit

Permalink
add feessupport account
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiquan911 committed Apr 28, 2019
1 parent 60896ba commit 7730b03
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 29 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/astaxie/beego v1.11.1
github.com/blocktree/go-owcdrivers v1.0.4
github.com/blocktree/go-owcrypt v1.0.1
github.com/blocktree/openwallet v1.2.1
github.com/blocktree/openwallet v1.4.1
github.com/bndr/gotabulate v1.1.2
github.com/btcsuite/btcutil v0.0.0-20190316010144-3ac1210f4b38
github.com/golang/protobuf v1.3.1
Expand All @@ -20,4 +20,4 @@ require (
google.golang.org/grpc v1.19.1
)

replace github.com/blocktree/openwallet => ../../openwallet
//replace github.com/blocktree/openwallet => ../../openwallet
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ github.com/blocktree/go-owcrypt v1.0.1 h1:hTqRN7mH2L0mVzHcL9jE0YM7B4oUFiDvksLEpa
github.com/blocktree/go-owcrypt v1.0.1/go.mod h1:5FCinL/4XVEqbmAFTOUgfMJVNJEw6WzVy624qsxzZC8=
github.com/blocktree/openwallet v1.2.1 h1:t+AsfEZvBGxkhUYZWcOsuAoeFdNxSMJ9I1VOPqplPGM=
github.com/blocktree/openwallet v1.2.1/go.mod h1:7IxhXsLl0WOg4cz8EP/HCU6LBkal2jN1vdH4dNzHOzw=
github.com/blocktree/openwallet v1.4.1 h1:Erju/SLK3qjU9OZ4JEsrUBD6wfvC0PBC+28rhy+BLM4=
github.com/blocktree/openwallet v1.4.1/go.mod h1:jStJigV8cNTOmvzvWJ4bdjXhiRvtQtSh++uJxSZRcb0=
github.com/bndr/gotabulate v1.1.2 h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c=
github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1LbPAb3U=
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
Expand Down
8 changes: 4 additions & 4 deletions openwtester/transcation_assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func TestTransfer_TRX(t *testing.T) {

testGetAssetsAccountBalance(tm, walletID, accountID)

rawTx, err := testCreateTransactionStep(tm, walletID, accountID, to, "0.001", "", nil)
rawTx, err := testCreateTransactionStep(tm, walletID, accountID, to, "0.3", "", nil)
if err != nil {
return
}
Expand Down Expand Up @@ -244,7 +244,7 @@ func TestSummary(t *testing.T) {
testGetAssetsAccountBalance(tm, walletID, accountID)

rawTxArray, err := testCreateSummaryTransactionStep(tm, walletID, accountID,
summaryAddress, "", "", "",
summaryAddress, "0.01", "0.01", "",
0, 100, nil, nil)
if err != nil {
log.Errorf("CreateSummaryTransaction failed, unexpected error: %v", err)
Expand Down Expand Up @@ -345,8 +345,8 @@ func TestSummary_TRC20(t *testing.T) {

feesSupport := openwallet.FeesSupportAccount{
AccountID: "5Tm3sqFap329wj3Du4DVXMkjAe85FVH3MaB6HSV8joj1",
FixSupportAmount: "1",
//FeesSupportScale: "1.3",
//FixSupportAmount: "1",
FeesSupportScale: "1.3",
}

contract := openwallet.SmartContract{
Expand Down
4 changes: 3 additions & 1 deletion tron/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ type WalletConfig struct {
CoinDecimal decimal.Decimal
//后台数据源类型
RPCServerType int
//FeeLimit
//FeeLimit 智能合约最大能量消耗限制,1 Energy = 10 SUN
FeeLimit int64
//FeeMini 智能合约最小能量消耗起,1 Energy = 10 SUN
FeeMini int64
}

//NewConfig Create config instance
Expand Down
2 changes: 2 additions & 0 deletions tron/config_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (wm *WalletManager) LoadConfig() error {
wm.Config.RPCPassword = c.String("rpcPassword")
wm.Config.NodeInstallPath = c.String("nodeInstallPath")
wm.Config.FeeLimit, _ = c.Int64("feeLimit")
wm.Config.FeeMini, _ = c.Int64("feeMini")
wm.Config.IsTestNet, _ = c.Bool("isTestNet")
if wm.Config.IsTestNet {
wm.Config.WalletDataPath = c.String("testNetDataPath")
Expand Down Expand Up @@ -78,6 +79,7 @@ func (wm *WalletManager) LoadAssetsConfig(c config.Configer) error {
//wm.Config.NodeInstallPath = c.String("nodeInstallPath")
wm.Config.IsTestNet, _ = c.Bool("isTestNet")
wm.Config.FeeLimit, _ = c.Int64("feeLimit")
wm.Config.FeeMini, _ = c.Int64("feeMini")
//if wm.Config.IsTestNet {
// wm.Config.WalletDataPath = c.String("testNetDataPath")
//} else {
Expand Down
15 changes: 15 additions & 0 deletions tron/manager_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ func (wm *WalletManager) GetAccountNet(address string) (accountNet *AccountNet,
return accountNet, nil
}

// GetAccountResource
func (wm *WalletManager) GetAccountResource(address string) (*AccountResource, error) {

address = convertAddrToHex(address)

params := req.Param{"address": address}
r, err := wm.WalletClient.Call("/wallet/getaccountresource", params)
if err != nil {
return nil, err
}
res := NewAccountResource(r)
return res, nil
}


//deprecated
// GetAccount Done!
// Function:Query bandwidth information.
Expand Down
14 changes: 13 additions & 1 deletion tron/manager_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
func TestGetAccountNet(t *testing.T) {

var addr string
addr = "TFHtQPM6SJ2GTebArYkhvZKk4rc3WAmdgE"
addr = "TRJJ9Mq4aMjdmKWpTDJAgbYNoY2P9Facg5"
accountNet, err := tw.GetAccountNet(addr)
if err != nil {
t.Errorf("GetAccountNet failed: %v\n", err)
Expand All @@ -32,6 +32,18 @@ func TestGetAccountNet(t *testing.T) {
log.Infof("accountNet: %+v", accountNet)
}

func TestGetAccountResource(t *testing.T) {

var addr string
addr = "TRJJ9Mq4aMjdmKWpTDJAgbYNoY2P9Facg5"
account, err := tw.GetAccountResource(addr)
if err != nil {
t.Errorf("GetAccountResource failed: %v\n", err)
return
}
log.Infof("GetAccountResource: %+v", account)
}

func TestGetAccount(t *testing.T) {

var addr string
Expand Down
21 changes: 21 additions & 0 deletions tron/manager_txRef.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,3 +704,24 @@ func (wm *WalletManager) GetTransactionFeeEstimated(from string, data string) (*
*/
return feeInfo, nil
}


//IsEnoughEnergyToTransferTRC20 是否足够能量转账TRC20
func (wm *WalletManager) IsEnoughEnergyToTransferTRC20(address string, trxBalance *big.Int) (flag bool, energyRest int64, feeMini int64) {
feeMini = wm.Config.FeeMini
res, err := wm.GetAccountResource(address)
if err != nil {
return false, 0, feeMini
}

energyRest = res.EnergyLimit - res.EnergyUsed
//1 Energy = 10 SUN
trxEnergy := trxBalance.Div(trxBalance, big.NewInt(10)).Int64()
energyRest = energyRest + trxEnergy
//能量少于下限
if energyRest < feeMini {
return false, energyRest, feeMini
}

return true, energyRest, feeMini
}
24 changes: 24 additions & 0 deletions tron/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,30 @@ func NewAccountNet(json *gjson.Result) *AccountNet {
return obj
}

type AccountResource struct {
FreeNetUsed int64
FreeNetLimit int64
NetUsed int64
NetLimit int64
EnergyUsed int64
EnergyLimit int64
StorageUsed int64
StorageLimit int64
}

func NewAccountResource(json *gjson.Result) *AccountResource {
obj := &AccountResource{}
obj.FreeNetUsed = json.Get("freeNetUsed").Int()
obj.FreeNetLimit = json.Get("freeNetLimit").Int()
obj.NetUsed = json.Get("NetUsed").Int()
obj.NetLimit = json.Get("NetLimit").Int()
obj.EnergyUsed = json.Get("EnergyUsed").Int()
obj.EnergyLimit = json.Get("EnergyLimit").Int()
obj.StorageUsed = json.Get("StorageUsed").Int()
obj.StorageLimit = json.Get("StorageLimit").Int()
return obj
}

type txFeeInfo struct {
GasUsed int64
GasPrice decimal.Decimal
Expand Down
78 changes: 57 additions & 21 deletions tron/tx_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/golang/protobuf/proto"
"math/big"
"sort"
"strings"
"time"

"github.com/blocktree/openwallet/openwallet"
Expand Down Expand Up @@ -190,6 +191,7 @@ func (decoder *TransactionDecoder) CreateTokenTransaction(wrapper openwallet.Wal
)

tokenDecimals := rawTx.Coin.Contract.Decimals
tokenProtocol := rawTx.Coin.Contract.Protocol

//获取wallet
addresses, err := wrapper.GetAddressList(0, -1, "AccountID", accountID) //wrapper.GetWallet().GetAddressesByAccount(rawTx.Account.AccountID)
Expand Down Expand Up @@ -266,6 +268,15 @@ func (decoder *TransactionDecoder) CreateTokenTransaction(wrapper openwallet.Wal
continue
}

//TRC20,需要检查能量是否足够调用合约
if strings.EqualFold(tokenProtocol, TRC20) {
//判断账户资源是否足够
isEnoughEnegry, energyRest, feeMini := decoder.wm.IsEnoughEnergyToTransferTRC20(addrBalance.Balance.Address, trxBalance)
if !isEnoughEnegry {
return openwallet.Errorf(openwallet.ErrInsufficientFees, "address[%s] available energy: %d is less than feeMini: %d", addrBalance.Balance.Address, energyRest, feeMini)
}
}

//只要找到一个合适使用的地址余额就停止遍历
findAddrBalance = &AddrBalance{
Address: addrBalance.Balance.Address,
Expand Down Expand Up @@ -580,10 +591,10 @@ func (decoder *TransactionDecoder) CreateSimpleSummaryRawTransaction(wrapper ope
func (decoder *TransactionDecoder) CreateTokenSummaryRawTransaction(wrapper openwallet.WalletDAI, sumRawTx *openwallet.SummaryRawTransaction) ([]*openwallet.RawTransactionWithError, error) {

var (
rawTxArray = make([]*openwallet.RawTransactionWithError, 0)
accountID = sumRawTx.Account.AccountID
minTransfer = common.StringNumToBigIntWithExp(sumRawTx.MinTransfer, Decimals)
retainedBalance = common.StringNumToBigIntWithExp(sumRawTx.RetainedBalance, Decimals)
rawTxArray = make([]*openwallet.RawTransactionWithError, 0)
accountID = sumRawTx.Account.AccountID
minTransfer = common.StringNumToBigIntWithExp(sumRawTx.MinTransfer, Decimals)
retainedBalance = common.StringNumToBigIntWithExp(sumRawTx.RetainedBalance, Decimals)
feesSupportAccount *openwallet.AssetsAccount
)

Expand All @@ -598,6 +609,7 @@ func (decoder *TransactionDecoder) CreateTokenSummaryRawTransaction(wrapper open
}

tokenDecimals := int32(sumRawTx.Coin.Contract.Decimals)
tokenProtocol := sumRawTx.Coin.Contract.Protocol

if minTransfer.Cmp(retainedBalance) < 0 {
return nil, fmt.Errorf("mini transfer amount must be greater than address retained balance")
Expand Down Expand Up @@ -627,7 +639,6 @@ func (decoder *TransactionDecoder) CreateTokenSummaryRawTransaction(wrapper open
for _, addrBalance := range addrBalanceArray {

trxBalance := big.NewInt(0)
trxBalanceDec := decimal.Zero

//检查余额是否超过最低转账
addrBalance_BI := common.StringNumToBigIntWithExp(addrBalance.Balance.Balance, tokenDecimals)
Expand Down Expand Up @@ -668,28 +679,51 @@ func (decoder *TransactionDecoder) CreateTokenSummaryRawTransaction(wrapper open
}
if len(addrTRXBalanceArray) > 0 {
trxBalance = common.StringNumToBigIntWithExp(addrTRXBalanceArray[0].Balance, decoder.wm.Decimal())
trxBalanceDec, _ = decimal.NewFromString(addrTRXBalanceArray[0].Balance)
}

//有手续费账户支持
if feesSupportAccount != nil {

//通过手续费账户创建交易单
supportAddress := addrBalance.Balance.Address
supportAmount := decimal.Zero
//feesSupportScale, _ := decimal.NewFromString(sumRawTx.FeesSupportAccount.FeesSupportScale)
fixSupportAmount, _ := decimal.NewFromString(sumRawTx.FeesSupportAccount.FixSupportAmount)

//目前TRON的手续费计算,官方没有API方法,只能采用固定数量支持
supportAmount = fixSupportAmount
half := decimal.New(2, 0)
//TRC20,需要检查能量是否足够调用合约
if strings.EqualFold(tokenProtocol, TRC20) {
//判断账户资源是否足够
isEnoughEnegry, energyRest, feeMini := decoder.wm.IsEnoughEnergyToTransferTRC20(addrBalance.Balance.Address, trxBalance)
if !isEnoughEnegry {
decoder.wm.Log.Debugf("address[%s] available energy: %d is less than feeMini: %d", addrBalance.Balance.Address, energyRest, feeMini)
//没有手续费账户支持,记录该交易单失败
if feesSupportAccount == nil {
rawTxWithErr := &openwallet.RawTransactionWithError{
RawTx: nil,
Error: openwallet.Errorf(openwallet.ErrInsufficientFees, "address[%s] available energy: %d is less than feeMini: %d", addrBalance.Balance.Address, energyRest, feeMini),
}
//添加到队列
rawTxArray = append(rawTxArray, rawTxWithErr)
continue
}

//如果余额低于固定数量/2,就需要手续费转账支持
if trxBalanceDec.LessThan(supportAmount.Div(half)) {
decoder.wm.Log.Debugf("use fees support account: %s to recharge energy", feesSupportAccount.AccountID)

//通过手续费账户创建交易单
supportAddress := addrBalance.Balance.Address
supportAmount := decimal.Zero
feesSupportScale, _ := decimal.NewFromString(sumRawTx.FeesSupportAccount.FeesSupportScale)
fixSupportAmount, _ := decimal.NewFromString(sumRawTx.FeesSupportAccount.FixSupportAmount)
//1 Energy = 10 SUN, 1 trx = 1000000 SUN, fees(trx) = Energy * 100000
fees := decimal.New(feeMini, 1-decoder.wm.Decimal())

//优先采用固定支持数量
if fixSupportAmount.GreaterThan(decimal.Zero) {
supportAmount = fixSupportAmount
} else {
//没有固定支持数量,有手续费倍率,计算支持数量
if feesSupportScale.GreaterThan(decimal.Zero) {
supportAmount = feesSupportScale.Mul(fees)
} else {
//默认支持数量为手续费
supportAmount = fees
}
}

decoder.wm.Log.Debugf("create transaction for fees support account")
decoder.wm.Log.Debugf("fees account: %s", feesSupportAccount.AccountID)
//decoder.wm.Log.Debugf("mini support amount: %s", fees.String())
decoder.wm.Log.Debugf("mini support amount: %s", fees.String())
decoder.wm.Log.Debugf("allow support amount: %s", supportAmount.String())
decoder.wm.Log.Debugf("support address: %s", supportAddress)

Expand Down Expand Up @@ -719,7 +753,9 @@ func (decoder *TransactionDecoder) CreateTokenSummaryRawTransaction(wrapper open

//汇总下一个
continue

}

}

decoder.wm.Log.Debugf("balance: %v", addrBalance.Balance.Balance)
Expand Down

0 comments on commit 7730b03

Please sign in to comment.