-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathfeemodule.go
128 lines (115 loc) · 3.01 KB
/
feemodule.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package photon
import (
"math/big"
"sync"
"errors"
"fmt"
"github.com/SmartMeshFoundation/Photon/log"
"github.com/SmartMeshFoundation/Photon/models"
"github.com/SmartMeshFoundation/Photon/pfsproxy"
"github.com/SmartMeshFoundation/Photon/utils"
"github.com/ethereum/go-ethereum/common"
)
//NoFeePolicy charge no fee
type NoFeePolicy struct {
}
//GetNodeChargeFee always return 0
func (n *NoFeePolicy) GetNodeChargeFee(nodeAddress, tokenAddress common.Address, amount *big.Int) *big.Int {
return utils.BigInt0
}
// FeeModule :
type FeeModule struct {
dao models.Dao
pfsProxy pfsproxy.PfsProxy
feePolicy *models.FeePolicy
lock sync.Mutex
}
// NewFeeModule :
func NewFeeModule(dao models.Dao, pfsProxy pfsproxy.PfsProxy) (fm *FeeModule, err error) {
if dao == nil {
panic("need init dao first")
}
fm = &FeeModule{
dao: dao,
pfsProxy: pfsProxy,
feePolicy: dao.GetFeePolicy(),
}
if fm.pfsProxy != nil {
log.Info("init fee module with pfs success")
} else {
log.Info("init fee module without pfs success")
}
return
}
// SetFeePolicy :
func (fm *FeeModule) SetFeePolicy(fp *models.FeePolicy) (err error) {
if fp == nil {
return errors.New("can not set nil fee policy")
}
if fp.AccountFee == nil {
return errors.New("AccountFee can not be nil")
}
if fp.TokenFeeMap == nil {
return errors.New("TokenFeeMap can not be nil")
}
if fp.ChannelFeeMap == nil {
return errors.New("ChannelFeeMap can not be nil")
}
fm.lock.Lock()
defer fm.lock.Unlock()
// set fee policy to pfs
if fm.pfsProxy != nil {
err = fm.pfsProxy.SetFeePolicy(fp)
if err != nil {
log.Error(fmt.Sprintf("commit fee policy to pfs failed, err = %s", err.Error()))
return
}
}
// set fee policy to dao
err = fm.dao.SaveFeePolicy(fp)
if err != nil {
if fm.pfsProxy != nil {
log.Error("save fee policy to dao err,may cause different fee policy between photon and pfs")
}
return
}
fm.feePolicy = fp
return
}
//SubmitFeePolicyToPFS :
func (fm *FeeModule) SubmitFeePolicyToPFS() (err error) {
if fm.pfsProxy != nil {
err = fm.pfsProxy.SetFeePolicy(fm.feePolicy)
}
return
}
//GetNodeChargeFee : impl of FeeCharge
func (fm *FeeModule) GetNodeChargeFee(nodeAddress, tokenAddress common.Address, amount *big.Int) *big.Int {
var feeSetting *models.FeeSetting
var ok bool
// 优先channel
c, err := fm.dao.GetChannel(tokenAddress, nodeAddress)
if c != nil && err == nil {
feeSetting, ok = fm.feePolicy.ChannelFeeMap[c.ChannelIdentifier.ChannelIdentifier]
if ok {
return calculateFee(feeSetting, amount)
}
}
// 其次token
feeSetting, ok = fm.feePolicy.TokenFeeMap[tokenAddress]
if ok {
return calculateFee(feeSetting, amount)
}
// 最后account
return calculateFee(fm.feePolicy.AccountFee, amount)
}
func calculateFee(feeSetting *models.FeeSetting, amount *big.Int) *big.Int {
fee := big.NewInt(0)
if feeSetting.FeePercent > 0 {
fee = fee.Div(amount, big.NewInt(feeSetting.FeePercent))
}
if feeSetting.FeeConstant.Cmp(big.NewInt(0)) > 0 {
fee = fee.Add(fee, feeSetting.FeeConstant)
}
return fee
}