mirror of
https://github.com/alexgo-io/libbrc20-indexer.git
synced 2026-04-29 04:05:13 +08:00
744 lines
22 KiB
Go
744 lines
22 KiB
Go
package indexer
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/unisat-wallet/libbrc20-indexer/conf"
|
|
"github.com/unisat-wallet/libbrc20-indexer/constant"
|
|
"github.com/unisat-wallet/libbrc20-indexer/decimal"
|
|
"github.com/unisat-wallet/libbrc20-indexer/model"
|
|
"github.com/unisat-wallet/libbrc20-indexer/utils"
|
|
)
|
|
|
|
var GResultsExternal []*model.SwapFunctionResultCheckState
|
|
|
|
func InitResultDataFromFile(fname string) (err error) {
|
|
// Open our jsonFile
|
|
jsonFile, err := os.Open(fname)
|
|
// if we os.Open returns an error then handle it
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
// defer the closing of our jsonFile so that we can parse it later on
|
|
defer jsonFile.Close()
|
|
|
|
byteValue, err := ioutil.ReadAll(jsonFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = json.Unmarshal([]byte(byteValue), &GResultsExternal)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (g *BRC20ModuleIndexer) BRC20ModulePrepareSwapCommitContent(
|
|
commitsStr []string,
|
|
commitsObj []*model.InscriptionBRC20ModuleSwapCommitContent) {
|
|
|
|
total := len(commitsStr)
|
|
if total < 2 {
|
|
return
|
|
}
|
|
|
|
for idx, commitStr := range commitsStr[:total-1] {
|
|
nextCommitObj := commitsObj[idx+1]
|
|
|
|
if _, ok := g.InscriptionsValidCommitMapById[nextCommitObj.Parent]; ok {
|
|
continue
|
|
}
|
|
|
|
data := &model.InscriptionBRC20Data{
|
|
InscriptionId: nextCommitObj.Parent,
|
|
ContentBody: []byte(commitStr),
|
|
}
|
|
g.InscriptionsValidCommitMapById[nextCommitObj.Parent] = data
|
|
}
|
|
}
|
|
|
|
func (g *BRC20ModuleIndexer) BRC20ModuleVerifySwapCommitContent(
|
|
commitStr string,
|
|
commitObj *model.InscriptionBRC20ModuleSwapCommitContent,
|
|
results []*model.SwapFunctionResultCheckState) (idx int, critical bool, err error) {
|
|
|
|
if len(commitObj.Data) != len(results) {
|
|
return -1, false, errors.New("commit verify, function results different size")
|
|
}
|
|
|
|
idx, err = g.ProcessInscribeCommitPreVerify(commitObj)
|
|
if err != nil {
|
|
log.Printf("commit verify failed: inscribe pre function[%d] %s", idx, err)
|
|
return idx, true, err
|
|
}
|
|
|
|
// Verifying commit that was not moved in the middle
|
|
// check module exist
|
|
moduleInfo, ok := g.ModulesInfoMap[commitObj.Module]
|
|
if !ok {
|
|
return -1, true, errors.New("commit, module not exist")
|
|
}
|
|
|
|
parentId := commitObj.Parent
|
|
// invalid if parent commit not exist
|
|
commitIdsToCheck := []string{}
|
|
for parentId != "" {
|
|
if _, ok := moduleInfo.CommitIdMap[parentId]; ok {
|
|
break
|
|
}
|
|
commitIdsToCheck = append([]string{parentId}, commitIdsToCheck...)
|
|
|
|
parentCommitData, ok := g.InscriptionsValidCommitMapById[parentId]
|
|
if !ok {
|
|
return -1, false, errors.New("commit, parent body missing")
|
|
}
|
|
|
|
parentId, err = GetCommitParentFromData(parentCommitData)
|
|
if err != nil {
|
|
return -1, true, errors.New("commit, parent json invalid")
|
|
}
|
|
}
|
|
|
|
for _, parentId := range commitIdsToCheck {
|
|
parentCommitData, ok := g.InscriptionsValidCommitMapById[parentId]
|
|
if !ok {
|
|
return -1, false, errors.New("commit, parent body not ready")
|
|
}
|
|
|
|
if idx, err := g.ProcessCommitCheck(parentCommitData); err != nil {
|
|
return idx, true, err
|
|
}
|
|
}
|
|
|
|
// verify current commit
|
|
eachFuntionSize, err := GetEachItemLengthOfCommitJsonData([]byte(commitStr))
|
|
if err != nil {
|
|
return -1, true, errors.New("commit, get function size failed")
|
|
}
|
|
idx, critical, err = g.ProcessCommitVerify("", commitObj, eachFuntionSize, results)
|
|
if err != nil {
|
|
log.Printf("commit verify failed, send function[%d] invalid", idx)
|
|
return idx, critical, err
|
|
}
|
|
return 0, false, nil
|
|
}
|
|
|
|
func (g *BRC20ModuleIndexer) BRC20ResultsPreVerify(moduleInfo *model.BRC20ModuleSwapInfo, result *model.SwapFunctionResultCheckState) (err error) {
|
|
// check user amt format
|
|
for idxUser, user := range result.Users {
|
|
userPkScript := constant.ZERO_ADDRESS_PKSCRIPT
|
|
// format check
|
|
if user.Address != "0" {
|
|
if pk, err := utils.GetPkScriptByAddress(user.Address, conf.GlobalNetParams); err != nil {
|
|
return errors.New(fmt.Sprintf("result users[%d] addr(%s) invalid", idxUser, user.Address))
|
|
} else {
|
|
userPkScript = string(pk)
|
|
}
|
|
}
|
|
if len(user.Tick) == 4 {
|
|
tokenAmt, ok := g.CheckTickVerify(user.Tick, user.Balance)
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result users[%d] balance invalid", idxUser))
|
|
}
|
|
|
|
// balance check
|
|
tokenBalance := moduleInfo.GetUserTokenBalance(user.Tick, userPkScript)
|
|
if tokenBalance.SwapAccountBalance.Cmp(tokenAmt) != 0 {
|
|
return errors.New(fmt.Sprintf("result users[%d] %s amount not match (%s != %s)",
|
|
idxUser, user.Tick,
|
|
tokenAmt.String(),
|
|
tokenBalance.SwapAccountBalance.String(),
|
|
))
|
|
}
|
|
|
|
} else {
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(user.Tick)
|
|
if err != nil {
|
|
return errors.New(fmt.Sprintf("result users[%d] tick invalid", idxUser))
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(token0, ""); !ok {
|
|
return errors.New(fmt.Sprintf("result users[%d] tick/0 invalid", idxUser))
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(token1, ""); !ok {
|
|
return errors.New(fmt.Sprintf("result users[%d] tick/1 invalid", idxUser))
|
|
}
|
|
lpAmt, ok := CheckAmountVerify(user.Balance, 18)
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result users[%d] Lp Amount invalid", idxUser))
|
|
}
|
|
|
|
// balance check
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
usersLpBalanceInPool, ok := moduleInfo.LPTokenUsersBalanceMap[poolPair]
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result users[%d] Pair invalid", idxUser))
|
|
}
|
|
lpBalance := usersLpBalanceInPool[userPkScript]
|
|
if lpBalance.Cmp(lpAmt) != 0 {
|
|
return errors.New(fmt.Sprintf("result users[%d] %s lp balance not match", idxUser, poolPair))
|
|
}
|
|
}
|
|
}
|
|
|
|
// check pool amt format
|
|
for idxPool, poolResult := range result.Pools {
|
|
// format check
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(poolResult.Pair)
|
|
if err != nil {
|
|
return errors.New(fmt.Sprintf("result pools[%d] Pair invalid", idxPool))
|
|
}
|
|
token0Amt, ok := g.CheckTickVerify(token0, poolResult.ReserveAmount0)
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result pools[%d] Amount0 invalid", idxPool))
|
|
}
|
|
|
|
token1Amt, ok := g.CheckTickVerify(token1, poolResult.ReserveAmount1)
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result pools[%d] Amount1 invalid", idxPool))
|
|
}
|
|
|
|
lpAmt, ok := CheckAmountVerify(poolResult.LPAmount, 18)
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result pools[%d] Lp Amount invalid", idxPool))
|
|
}
|
|
|
|
// balance check
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pool, ok := moduleInfo.SwapPoolTotalBalanceDataMap[poolPair]
|
|
if !ok {
|
|
return errors.New(fmt.Sprintf("result pools[%d] missing pair[%s]", idxPool, poolPair))
|
|
}
|
|
// Determine the token order id of the pool
|
|
var token0Idx, token1Idx int
|
|
if token0 == pool.Tick[0] {
|
|
token0Idx = 0
|
|
token1Idx = 1
|
|
} else {
|
|
token0Idx = 1
|
|
token1Idx = 0
|
|
}
|
|
|
|
if token0Amt.Cmp(pool.TickBalance[token0Idx]) != 0 {
|
|
return errors.New(fmt.Sprintf("result pool[%d] %s balance not match", idxPool, pool.Tick[token0Idx]))
|
|
}
|
|
|
|
if token1Amt.Cmp(pool.TickBalance[token1Idx]) != 0 {
|
|
return errors.New(fmt.Sprintf("result pool[%d] %s balance not match", idxPool, pool.Tick[token1Idx]))
|
|
}
|
|
|
|
lpAmt.Precition = 18
|
|
if lpAmt.Cmp(pool.LpBalance) != 0 {
|
|
return errors.New(fmt.Sprintf("result pool[%d] %s lpbalance not match", idxPool, poolPair))
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProcessInscribeCommit Created a commit, but it has not yet taken effect.
|
|
func (g *BRC20ModuleIndexer) ProcessInscribeCommitPreVerify(body *model.InscriptionBRC20ModuleSwapCommitContent) (index int, err error) {
|
|
if body.Module != strings.ToLower(body.Module) {
|
|
return -1, errors.New("module id invalid")
|
|
}
|
|
|
|
// check module exist
|
|
moduleInfo, ok := g.ModulesInfoMap[body.Module]
|
|
if !ok {
|
|
return -1, errors.New("module invalid")
|
|
}
|
|
|
|
// check gasPrice
|
|
if _, ok := g.CheckTickVerify(moduleInfo.GasTick, body.GasPrice); !ok {
|
|
log.Printf("ProcessInscribeCommit commit gas err: %s", body.GasPrice)
|
|
return -1, errors.New("gas price invalid")
|
|
}
|
|
|
|
// common content
|
|
content := fmt.Sprintf("module: %s\n", moduleInfo.ID)
|
|
if body.Parent != "" {
|
|
content += fmt.Sprintf("parent: %s\n", body.Parent)
|
|
}
|
|
if body.GasPrice != "" {
|
|
content += fmt.Sprintf("gas_price: %s\n", body.GasPrice)
|
|
}
|
|
|
|
// for previous id
|
|
functionsByAddressMap := make(map[string][]string)
|
|
for idx, f := range body.Data {
|
|
if pkScript, err := utils.GetPkScriptByAddress(f.Address, conf.GlobalNetParams); err != nil {
|
|
return idx, errors.New("addr invalid")
|
|
} else {
|
|
f.PkScript = string(pkScript)
|
|
}
|
|
|
|
// log.Printf("ProcessInscribeCommitPreVerify func[%d] %s(%s)", idx, f.Function, strings.Join(f.Params, ", "))
|
|
|
|
// get prevouse function id by user
|
|
previous := functionsByAddressMap[f.Address]
|
|
if id, ok := CheckFunctionSigVerify(content, f, previous); !ok {
|
|
return idx, errors.New(fmt.Sprintf("function[%d]%s sig invalid", idx, id))
|
|
} else {
|
|
// update previous id list
|
|
previous = append(previous, id)
|
|
functionsByAddressMap[f.Address] = previous
|
|
}
|
|
|
|
// function process
|
|
if f.Function == constant.BRC20_SWAP_FUNCTION_DEPLOY_POOL {
|
|
if len(f.Params) != 2 {
|
|
return idx, errors.New("func: deploy params invalid")
|
|
}
|
|
token0 := f.Params[0]
|
|
token1 := f.Params[1]
|
|
if token0 == token1 {
|
|
return idx, errors.New("func: deploy same tokens")
|
|
}
|
|
if _, ok := g.InscriptionsTickerInfoMap[strings.ToLower(token0)]; !ok {
|
|
return idx, errors.New("func: deploy tick0 invalid")
|
|
}
|
|
if _, ok := g.InscriptionsTickerInfoMap[strings.ToLower(token1)]; !ok {
|
|
return idx, errors.New("func: deploy tick1 invalid")
|
|
}
|
|
|
|
// Check for duplicate pairs when the Commit inscription effect is applied.
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_ADD_LIQ {
|
|
if len(f.Params) != 5 {
|
|
return idx, errors.New("func: addLiq params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: addLiq poolPair invalid")
|
|
}
|
|
|
|
token0AmtStr := f.Params[1]
|
|
token1AmtStr := f.Params[2]
|
|
tokenLpAmtStr := f.Params[3]
|
|
slippage := f.Params[4]
|
|
|
|
if _, ok := g.CheckTickVerify(token0, token0AmtStr); !ok {
|
|
return idx, errors.New("func: addLiq amt0 invalid")
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(token1, token1AmtStr); !ok {
|
|
return idx, errors.New("func: addLiq amt1 invalid")
|
|
}
|
|
|
|
if _, ok := CheckAmountVerify(tokenLpAmtStr, 18); !ok {
|
|
return idx, errors.New("func: addLiq amtLp invalid")
|
|
}
|
|
|
|
if _, ok := CheckAmountVerify(slippage, 3); !ok {
|
|
return idx, errors.New("func: addLiq slippage invalid")
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_REMOVE_LIQ {
|
|
if len(f.Params) != 5 {
|
|
return idx, errors.New("func: removeLiq params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: removeLiq poolPair invalid")
|
|
}
|
|
|
|
tokenLpAmtStr := f.Params[1]
|
|
token0AmtStr := f.Params[2]
|
|
token1AmtStr := f.Params[3]
|
|
slippage := f.Params[4]
|
|
|
|
if _, ok := CheckAmountVerify(tokenLpAmtStr, 18); !ok {
|
|
return idx, errors.New(fmt.Sprintf("func: removeLiq amtLp invalid, %s", f.Params[1]))
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(token0, token0AmtStr); !ok {
|
|
return idx, errors.New("func: removeLiq amt0 invalid")
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(token1, token1AmtStr); !ok {
|
|
return idx, errors.New("func: removeLiq amt1 invalid")
|
|
}
|
|
|
|
if _, ok := CheckAmountVerify(slippage, 3); !ok {
|
|
return idx, errors.New("func: removeLiq slippage invalid")
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SWAP {
|
|
if len(f.Params) != 6 {
|
|
return idx, errors.New("func: swap params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: swap poolPair invalid")
|
|
}
|
|
|
|
// Check that the first parameter must be one of the token pairs.
|
|
if token := f.Params[1]; token != token0 && token != token1 {
|
|
return idx, errors.New("func: swap token invalid")
|
|
}
|
|
|
|
derection := f.Params[3]
|
|
if derection != "exactIn" && derection != "exactOut" {
|
|
return idx, errors.New("func: swap derection invalid")
|
|
}
|
|
|
|
var tokenIn, tokenInAmtStr, tokenOut, tokenOutAmtStr string
|
|
if derection == "exactIn" {
|
|
tokenIn = f.Params[1]
|
|
tokenInAmtStr = f.Params[2]
|
|
|
|
if tokenIn == token0 {
|
|
tokenOut = token1
|
|
} else {
|
|
tokenOut = token0
|
|
}
|
|
tokenOutAmtStr = f.Params[4]
|
|
} else if derection == "exactOut" {
|
|
tokenOut = f.Params[1]
|
|
tokenOutAmtStr = f.Params[2]
|
|
|
|
if tokenOut == token0 {
|
|
tokenIn = token1
|
|
} else {
|
|
tokenIn = token0
|
|
}
|
|
tokenInAmtStr = f.Params[4]
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(tokenIn, tokenInAmtStr); !ok {
|
|
return idx, errors.New("func: swap token amount invalid")
|
|
}
|
|
|
|
if _, ok := g.CheckTickVerify(tokenOut, tokenOutAmtStr); !ok {
|
|
return idx, errors.New("func: swap amt1 invalid")
|
|
}
|
|
|
|
slippage := f.Params[5]
|
|
if _, ok := CheckAmountVerify(slippage, 3); !ok {
|
|
return idx, errors.New("func: swap slippage invalid")
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_DECREASE_APPROVAL {
|
|
if len(f.Params) != 2 {
|
|
return idx, errors.New("func: decrease approval params invalid")
|
|
}
|
|
|
|
token := f.Params[0]
|
|
tokenAmtStr := f.Params[1]
|
|
|
|
if _, ok := g.CheckTickVerify(token, tokenAmtStr); !ok {
|
|
return idx, errors.New("func: decrease approval amt invalid")
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SEND {
|
|
if len(f.Params) != 3 {
|
|
return idx, errors.New("func: send params invalid")
|
|
}
|
|
|
|
addressTo := f.Params[0]
|
|
if _, err := utils.GetPkScriptByAddress(addressTo, conf.GlobalNetParams); err != nil {
|
|
return idx, errors.New("send addr invalid")
|
|
}
|
|
|
|
tokenOrPair := f.Params[1]
|
|
tokenAmtStr := f.Params[2]
|
|
if len(tokenOrPair) == 4 {
|
|
if _, ok := g.CheckTickVerify(tokenOrPair, tokenAmtStr); !ok {
|
|
return idx, errors.New("func: send amt invalid")
|
|
}
|
|
} else {
|
|
if _, _, err := utils.DecodeTokensFromSwapPair(tokenOrPair); err != nil {
|
|
return idx, errors.New("func: send lp invalid")
|
|
}
|
|
if _, ok := CheckAmountVerify(tokenAmtStr, 18); !ok {
|
|
return idx, errors.New(fmt.Sprintf("func: send amtLp invalid, %s", tokenAmtStr))
|
|
}
|
|
}
|
|
|
|
} else {
|
|
log.Printf("ProcessInscribeCommit commit[%d] invalid function: %s. id: %s", idx, f.Function, f.ID)
|
|
return idx, errors.New("func invalid")
|
|
}
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
func (g *BRC20ModuleIndexer) ProcessCommitVerify(commitId string, body *model.InscriptionBRC20ModuleSwapCommitContent,
|
|
eachFuntionSize []uint64, results []*model.SwapFunctionResultCheckState) (index int, critical bool, err error) {
|
|
|
|
// check module exist
|
|
moduleInfo, ok := g.ModulesInfoMap[body.Module]
|
|
if !ok {
|
|
return -1, true, errors.New("commit, module not exist")
|
|
}
|
|
|
|
// check empty parent
|
|
if body.Parent == "" {
|
|
if len(moduleInfo.CommitIdMap) > 0 {
|
|
return -1, true, errors.New("commit, missing parent")
|
|
}
|
|
} else {
|
|
// invalid if reusing 'parent'
|
|
if _, ok := moduleInfo.CommitIdChainMap[body.Parent]; ok {
|
|
return -1, true, errors.New("commit, parent already sattled")
|
|
}
|
|
|
|
// invalid if parent commit not exist
|
|
if _, ok := moduleInfo.CommitIdMap[body.Parent]; !ok {
|
|
return -1, true, errors.New("commit, parent invalid")
|
|
}
|
|
}
|
|
|
|
gasPriceAmt, _ := g.CheckTickVerify(moduleInfo.GasTick, body.GasPrice)
|
|
|
|
if len(body.Data) != len(eachFuntionSize) {
|
|
return -1, true, errors.New("commit, function size not match data")
|
|
}
|
|
for idx, f := range body.Data {
|
|
if pkScript, err := utils.GetPkScriptByAddress(f.Address, conf.GlobalNetParams); err != nil {
|
|
return idx, true, errors.New("commit, addr invalid")
|
|
} else {
|
|
f.PkScript = string(pkScript)
|
|
}
|
|
|
|
// gas fee
|
|
if gasPriceAmt.Sign() > 0 {
|
|
size := eachFuntionSize[idx]
|
|
gasAmt := gasPriceAmt.Mul(decimal.NewDecimal(size, 3))
|
|
// log.Printf("process commit[%d] size: %d, gas fee: %s, module[%s]", idx, size, gasAmt.String(), body.Module)
|
|
if err := g.ProcessCommitFunctionGasFee(moduleInfo, f.PkScript, gasAmt); err != nil { // has update
|
|
log.Printf("process commit[%d] gas failed: %s", idx, err)
|
|
return idx, true, err
|
|
}
|
|
}
|
|
|
|
// functions
|
|
if f.Function == constant.BRC20_SWAP_FUNCTION_DEPLOY_POOL {
|
|
if err := g.ProcessCommitFunctionDeployPool(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] deploy pool failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_ADD_LIQ {
|
|
if err := g.ProcessCommitFunctionAddLiquidity(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] add liq failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_REMOVE_LIQ {
|
|
if err := g.ProcessCommitFunctionRemoveLiquidity(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] remove liq failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SWAP {
|
|
if err := g.ProcessCommitFunctionSwap(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] swap failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_DECREASE_APPROVAL {
|
|
if err := g.ProcessCommitFunctionDecreaseApproval(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] decrease approval failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SEND {
|
|
if err := g.ProcessCommitFunctionSend(moduleInfo, f); err != nil {
|
|
log.Printf("process commit[%d] send failed: %s, module[%s]", idx, err, body.Module)
|
|
return idx, true, err
|
|
}
|
|
}
|
|
|
|
// instant verify
|
|
if len(results) == len(body.Data) {
|
|
if err = g.BRC20ResultsPreVerify(moduleInfo, results[idx]); err != nil {
|
|
log.Printf("commit verify failed: result[%d] %s", idx, err)
|
|
return idx, false, err
|
|
}
|
|
}
|
|
|
|
// verify test result
|
|
if GResultsExternal == nil {
|
|
continue
|
|
}
|
|
for _, result := range GResultsExternal {
|
|
if result.CommitId != commitId {
|
|
continue
|
|
}
|
|
|
|
if result.FunctionIdx != idx {
|
|
continue
|
|
}
|
|
|
|
if err = g.BRC20ResultsPreVerify(moduleInfo, result); err != nil {
|
|
log.Printf("commit verify failed: result[%d] %s", idx, err)
|
|
return idx, false, err
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0, false, nil
|
|
}
|
|
|
|
func (g *BRC20ModuleIndexer) InitCherryPickFilter(body *model.InscriptionBRC20ModuleSwapCommitContent, pickUsersPkScript, pickTokensTick, pickPoolsPair map[string]bool) (index int, err error) {
|
|
// check module exist
|
|
moduleInfo, ok := g.ModulesInfoMap[body.Module]
|
|
if !ok {
|
|
return -1, errors.New("module invalid")
|
|
}
|
|
|
|
pickUsersPkScript[string(moduleInfo.GasToPkScript)] = true
|
|
pickUsersPkScript[string(moduleInfo.LpFeePkScript)] = true
|
|
pickUsersPkScript[string(moduleInfo.SequencerPkScript)] = true
|
|
pickUsersPkScript[string(moduleInfo.DeployerPkScript)] = true
|
|
|
|
pickTokensTick[moduleInfo.GasTick] = true
|
|
|
|
for idx, f := range body.Data {
|
|
if pkScript, err := utils.GetPkScriptByAddress(f.Address, conf.GlobalNetParams); err != nil {
|
|
return idx, errors.New("addr invalid")
|
|
} else {
|
|
pickUsersPkScript[string(pkScript)] = true
|
|
}
|
|
|
|
// function process
|
|
if f.Function == constant.BRC20_SWAP_FUNCTION_DEPLOY_POOL {
|
|
if len(f.Params) != 2 {
|
|
return idx, errors.New("func: deploy params invalid")
|
|
}
|
|
token0 := f.Params[0]
|
|
token1 := f.Params[1]
|
|
|
|
// pair
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pickPoolsPair[poolPair] = true
|
|
|
|
// tick
|
|
token0 = strings.ToLower(token0)
|
|
token1 = strings.ToLower(token1)
|
|
pickTokensTick[token0] = true
|
|
pickTokensTick[token1] = true
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_ADD_LIQ {
|
|
if len(f.Params) != 5 {
|
|
return idx, errors.New("func: addLiq params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: addLiq poolPair invalid")
|
|
}
|
|
|
|
// pair
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pickPoolsPair[poolPair] = true
|
|
|
|
// tick
|
|
token0 = strings.ToLower(token0)
|
|
token1 = strings.ToLower(token1)
|
|
pickTokensTick[token0] = true
|
|
pickTokensTick[token1] = true
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_REMOVE_LIQ {
|
|
if len(f.Params) != 5 {
|
|
return idx, errors.New("func: removeLiq params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: removeLiq poolPair invalid")
|
|
}
|
|
|
|
// pair
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pickPoolsPair[poolPair] = true
|
|
|
|
// tick
|
|
token0 = strings.ToLower(token0)
|
|
token1 = strings.ToLower(token1)
|
|
pickTokensTick[token0] = true
|
|
pickTokensTick[token1] = true
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SWAP {
|
|
if len(f.Params) != 6 {
|
|
return idx, errors.New("func: swap params invalid")
|
|
}
|
|
|
|
token0, token1, err := utils.DecodeTokensFromSwapPair(f.Params[0])
|
|
if err != nil {
|
|
return idx, errors.New("func: swap poolPair invalid")
|
|
}
|
|
|
|
// pair
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pickPoolsPair[poolPair] = true
|
|
|
|
// tick
|
|
token0 = strings.ToLower(token0)
|
|
token1 = strings.ToLower(token1)
|
|
pickTokensTick[token0] = true
|
|
pickTokensTick[token1] = true
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_DECREASE_APPROVAL {
|
|
if len(f.Params) != 2 {
|
|
return idx, errors.New("func: decrease approval params invalid")
|
|
}
|
|
|
|
token0 := f.Params[0]
|
|
token0 = strings.ToLower(token0)
|
|
pickTokensTick[token0] = true
|
|
|
|
} else if f.Function == constant.BRC20_SWAP_FUNCTION_SEND {
|
|
if len(f.Params) != 3 {
|
|
return idx, errors.New("func: send params invalid")
|
|
}
|
|
|
|
addressTo := f.Params[0]
|
|
if pk, err := utils.GetPkScriptByAddress(addressTo, conf.GlobalNetParams); err != nil {
|
|
return idx, errors.New("send addr invalid")
|
|
} else {
|
|
pickUsersPkScript[string(pk)] = true
|
|
}
|
|
|
|
tokenOrPair := f.Params[1]
|
|
if len(tokenOrPair) == 4 {
|
|
token0 := strings.ToLower(tokenOrPair)
|
|
pickTokensTick[token0] = true
|
|
|
|
} else {
|
|
if token0, token1, err := utils.DecodeTokensFromSwapPair(tokenOrPair); err != nil {
|
|
return idx, errors.New("func: send lp invalid")
|
|
} else {
|
|
poolPair := GetLowerInnerPairNameByToken(token0, token1)
|
|
pickPoolsPair[poolPair] = true
|
|
|
|
// tick
|
|
token0 = strings.ToLower(token0)
|
|
token1 = strings.ToLower(token1)
|
|
pickTokensTick[token0] = true
|
|
pickTokensTick[token1] = true
|
|
}
|
|
}
|
|
|
|
} else {
|
|
log.Printf("ProcessInscribeCommit commit[%d] invalid function: %s. id: %s", idx, f.Function, f.ID)
|
|
return idx, errors.New("func invalid")
|
|
}
|
|
}
|
|
|
|
return 0, nil
|
|
}
|