aozhiwei 26be80a811 1
2024-09-24 16:58:35 +08:00

234 lines
6.1 KiB
Go

package service
import (
"q5"
"f5"
"sync"
"strings"
"main/constant"
"math/big"
)
type vip struct {
lock sync.Mutex
}
type vesterDepositWithdrawPo struct {
idx int64
eventName string
chainTimestamp int32
accountAddress string
depositAmount string
withdrawClamiedAmount string
withdrawBalance string
}
func (this *vip) init() () {
}
func (this *vip) Add(accountAddress string, val string, idx int64, valField string, idxField string) bool {
this.lock.Lock()
defer this.lock.Unlock()
extKv := [][]string{}
accountAddress = strings.ToLower(accountAddress)
err, ds := f5.GetGoStyleDb().NewOrmSelect(
constant.BCNFT_DB,
"t_vip_user",
[][]string {
{"account_address", accountAddress},
})
if err != nil {
return false
}
nowTime := f5.GetApp().GetRealSeconds()
updateKv := [][]string {
{idxField, q5.ToString(idx)},
{"modifytime", q5.ToString(nowTime)},
}
insertKv := [][]string {
{"account_address", accountAddress},
{valField, val},
{idxField, q5.ToString(idx)},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
}
updateKv = append(updateKv, extKv...)
insertKv = append(insertKv, extKv...)
if ds.Next() {
if q5.ToInt64(ds.GetByName(idxField)) >= idx {
return true
}
bnOldVal, _ := new(big.Int).SetString(ds.GetByName(valField), 10)
bnVal, _ := new(big.Int).SetString(val, 10)
bnNewVal := bnOldVal.Add(bnOldVal, bnVal)
updateKv = append(updateKv, [][]string{{valField, bnNewVal.String()}}...)
err1, _, _ := f5.GetGoStyleDb().NewUpdate(
constant.BCNFT_DB,
"t_vip_user",
[][]string {
{"account_address", accountAddress},
},
updateKv)
if err1 != nil {
return false
}
} else {
err1, _, _ := f5.GetGoStyleDb().NewInsert(
constant.BCNFT_DB,
"t_vip_user",
insertKv)
if err1 != nil {
return false
}
}
return true
}
func (this *vip) Replace(accountAddress string, val string, idx int64, valField string, idxField string,
extKv [][]string) bool {
this.lock.Lock()
defer this.lock.Unlock()
accountAddress = strings.ToLower(accountAddress)
err, ds := f5.GetGoStyleDb().NewOrmSelect(
constant.BCNFT_DB,
"t_vip_user",
[][]string {
{"account_address", accountAddress},
})
if err != nil {
return false
}
nowTime := f5.GetApp().GetRealSeconds()
updateKv := [][]string {
{valField, val},
{idxField, q5.ToString(idx)},
{"modifytime", q5.ToString(nowTime)},
}
insertKv := [][]string {
{"account_address", accountAddress},
{valField, val},
{idxField, q5.ToString(idx)},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
}
updateKv = append(updateKv, extKv...)
insertKv = append(insertKv, extKv...)
if ds.Next() {
if q5.ToInt64(ds.GetByName(idxField)) >= idx {
return true
}
err1, _, _ := f5.GetGoStyleDb().NewUpdate(
constant.BCNFT_DB,
"t_vip_user",
[][]string {
{"account_address", accountAddress},
},
updateKv)
if err1 != nil {
return false
}
} else {
err1, _, _ := f5.GetGoStyleDb().NewInsert(
constant.BCNFT_DB,
"t_vip_user",
insertKv)
if err1 != nil {
return false
}
}
return true
}
/*
Deposit amount his_amount 衰减,最后的存覆盖之前的
Withdraw 所有
按时间排序处理事件的先后顺序
通过Vester.sol的remainingEsToken方法获取, 如果要本地计算的话, 那就取每次Deposit事件的时间和amount, 加上先前的转换的余额, 再按total * (now - deposit_time) / (365 * 24 * 2600)
*/
func (this *vip) RecalcEsCecConvert(accountAddress string) error {
accountAddress = strings.ToLower(accountAddress)
err , ds := f5.GetGoStyleDb().NewOrmSelect(
constant.BCEVENT_DB,
"t_vester_deposit_withdraw",
[][]string {
{"account_address", accountAddress},
})
if err != nil {
return err
}
matchDeposits := []*vesterDepositWithdrawPo{}
var lastWithdraw *vesterDepositWithdrawPo
{
allDeposits := []*vesterDepositWithdrawPo{}
for ds.Next() {
p := new(vesterDepositWithdrawPo)
p.idx = q5.ToInt64(ds.GetByName("idx"))
p.eventName = ds.GetByName("event_name")
p.chainTimestamp = q5.ToInt32(ds.GetByName("chain_timestamp"))
p.accountAddress = ds.GetByName("account_address")
p.depositAmount = ds.GetByName("deposit_amount")
p.withdrawClamiedAmount = ds.GetByName("withdraw_clamied_amount")
p.withdrawBalance = ds.GetByName("withdraw_balance")
if p.eventName == constant.VESTER_DEPOSIT_EVENT_NAME {
q5.AppendSlice(&allDeposits, p)
} else if p.eventName == constant.VESTER_WITHDRAW_EVENT_NAME {
if lastWithdraw == nil || lastWithdraw.chainTimestamp < p.chainTimestamp {
lastWithdraw = p
}
}
}
for _, val := range allDeposits {
if lastWithdraw == nil || val.chainTimestamp > lastWithdraw.chainTimestamp {
q5.AppendSlice(&matchDeposits, val)
}
}
}
q5.Sort(matchDeposits, func (a *vesterDepositWithdrawPo, b *vesterDepositWithdrawPo) bool {
return a.chainTimestamp < b.chainTimestamp
})
var lastDeposit *vesterDepositWithdrawPo
nowTime := q5.ToInt32(f5.GetApp().GetRealSeconds())
bnTotal := new(big.Int)
for _, val := range matchDeposits {
if lastDeposit != nil {
if nowTime > lastDeposit.chainTimestamp {
bnPassTime := new(big.Int).SetInt64(int64(nowTime - lastDeposit.chainTimestamp))
bnTotalTime := new(big.Int).SetInt64(int64(365 * 24 * 2600))
bnTmp := bnTotal.Mul(bnTotal, bnPassTime)
bnInterest := bnTmp.Div(bnTmp, bnTotalTime)
bnTotal = bnTotal.Sub(bnTotal, bnInterest)
}
}
bnAmount, _ := new(big.Int).SetString(val.depositAmount, 10)
bnTotal = bnAmount.Add(bnAmount, bnTotal)
lastDeposit = val
}
var maxIdx int64
if lastDeposit != nil &&
lastDeposit.idx > maxIdx {
maxIdx = lastDeposit.idx
}
if lastWithdraw != nil &&
lastWithdraw.idx > maxIdx {
maxIdx = lastWithdraw.idx
}
if lastDeposit != nil {
this.Replace(accountAddress, bnTotal.String(), maxIdx, "escec_convert", "deposit_withdraw_last_src_idx",
[][]string {
{"last_convert_time", q5.ToString(lastDeposit.chainTimestamp)},
})
} else if lastWithdraw != nil {
this.Replace(accountAddress, "0", maxIdx, "escec_convert", "deposit_withdraw_last_src_idx",
[][]string {
{"last_convert_time", q5.ToString(lastWithdraw.chainTimestamp)},
})
}
return nil
}