Skip to content

Commit 5a08a38

Browse files
authored
Feature/mint balance check (#16)
* should check the balance of deployed asset from mtg * check the balance of deployed asset when mtg build transaction * fix interval * fix test
1 parent d7f1f44 commit 5a08a38

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

solana/node.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,33 @@ func (node *Node) Boot(ctx context.Context, version string) {
6868
}
6969
go node.bootObserver(ctx, version)
7070
go node.bootSigner(ctx)
71+
go node.mtgBalanceCheckLoop(ctx)
7172

7273
logger.Printf("node.Boot(%s, %d)", node.id, node.Index())
7374
}
7475

76+
func (node *Node) mtgBalanceCheckLoop(ctx context.Context) {
77+
for {
78+
as, err := node.store.ListDeployedAssets(ctx)
79+
if err != nil {
80+
panic(err)
81+
}
82+
for _, a := range as {
83+
node.checkMintBalance(ctx, a)
84+
time.Sleep(100 * time.Millisecond)
85+
}
86+
time.Sleep(time.Minute)
87+
}
88+
}
89+
90+
func (node *Node) checkMintBalance(ctx context.Context, a *solanaApp.DeployedAsset) {
91+
supply := node.RPCMintSupply(ctx, a.Address)
92+
balance := node.getMtgAssetBalance(ctx, a.AssetId)
93+
if balance.Cmp(supply) < 0 {
94+
panic(fmt.Errorf("invalid balance of mtg asset %s %s: %s %s", a.AssetId, a.Address, balance, supply))
95+
}
96+
}
97+
7598
func (node *Node) Index() int {
7699
index := node.findMember(string(node.id))
77100
if index < 0 {

solana/observer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ func (node *Node) checkSufficientBalanceForBurnSystemCall(ctx context.Context, c
10161016
panic(err)
10171017
}
10181018
amount := decimal.New(int64(*burn.Amount), -int32(da.Decimals))
1019-
balance := node.getAssetBalanceAt(ctx, math.MaxInt64, da.AssetId)
1019+
balance := node.getMtgAssetBalance(ctx, da.AssetId)
10201020
if balance.Cmp(amount) < 0 {
10211021
logger.Printf("insufficient balance to confirm burn system call: %s %s %s %s", call.RequestId, da.AssetId, amount.String(), balance.String())
10221022
return false
@@ -1025,8 +1025,8 @@ func (node *Node) checkSufficientBalanceForBurnSystemCall(ctx context.Context, c
10251025
return true
10261026
}
10271027

1028-
func (node *Node) getAssetBalanceAt(ctx context.Context, sequence uint64, assetId string) decimal.Decimal {
1029-
os := node.group.ListOutputsForAsset(ctx, node.conf.AppId, assetId, node.conf.MTG.Genesis.Epoch, sequence, mtg.SafeUtxoStateUnspent, 0)
1028+
func (node *Node) getMtgAssetBalance(ctx context.Context, assetId string) decimal.Decimal {
1029+
os := node.group.ListOutputsForAsset(ctx, node.conf.AppId, assetId, node.conf.MTG.Genesis.Epoch, math.MaxInt64, mtg.SafeUtxoStateUnspent, 0)
10301030
total := decimal.NewFromInt(0)
10311031
for _, o := range os {
10321032
total = total.Add(o.Amount)

solana/rpc.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/gagliardetto/solana-go"
1818
"github.com/gagliardetto/solana-go/programs/token"
1919
"github.com/gagliardetto/solana-go/rpc"
20+
"github.com/shopspring/decimal"
2021
)
2122

2223
func (node *Node) checkCreatedAtaUntilSufficient(ctx context.Context, tx *solana.Transaction) error {
@@ -253,6 +254,15 @@ func (node *Node) RPCCheckNFT(ctx context.Context, account string) (bool, error)
253254
return tm.Supply == 1 && tm.Decimals == 0, nil
254255
}
255256

257+
func (node *Node) RPCMintSupply(ctx context.Context, account string) decimal.Decimal {
258+
mint, err := node.solana.GetMint(ctx, solana.MPK(account))
259+
if err != nil || mint == nil {
260+
panic(fmt.Errorf("solana.GetMint(%s) => %v %v", account, mint, err))
261+
}
262+
supply := decimal.New(int64(mint.Supply), -int32(mint.Decimals))
263+
return supply
264+
}
265+
256266
func (node *Node) RPCGetMinimumBalanceForRentExemption(ctx context.Context, dataSize uint64) (uint64, error) {
257267
key := fmt.Sprintf("getMinimumBalanceForRentExemption:%d", dataSize)
258268
value, err := node.store.ReadCache(ctx, key)

solana/transaction.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ func (node *Node) checkTransaction(ctx context.Context, act *mtg.Action, assetId
6060
return ""
6161
}
6262

63+
if !common.CheckTestEnvironment(ctx) {
64+
da, err := node.store.ReadDeployedAsset(ctx, assetId)
65+
if err != nil {
66+
panic(err)
67+
}
68+
if da != nil {
69+
supply := node.RPCMintSupply(ctx, da.Address)
70+
balance = node.getMtgAssetBalance(ctx, da.AssetId)
71+
if balance.Sub(amt).Cmp(supply) < 0 {
72+
panic(fmt.Errorf("invalid balance of mtg asset %s %s: %s %s %s", da.AssetId, da.Address, balance, amt, supply))
73+
}
74+
}
75+
}
76+
6377
nextId := common.UniqueId(node.group.GenesisId(), traceId)
6478
logger.Printf("node.checkTransaction(%s) => %s", traceId, nextId)
6579
return nextId

0 commit comments

Comments
 (0)