Skip to content

add checks on balance #1373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 75 additions & 18 deletions monitoring-bot/internal/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ type balanceReport struct {
original float64
afterSendingToChain float64
afterSendingToStellar float64
originalStellar float64
stellarAfterDeposit float64
stellarAfterWithdraw float64
}

type bridgeTX func(client.Identity, network) error
Expand All @@ -37,10 +40,24 @@ func (m *Monitor) monitorBridges() error {
}

message.WriteString(fmt.Sprintf("- %s\n", successMessage))
message.WriteString("\tAccount balance reports:\n")
message.WriteString(fmt.Sprintf("\t\t- Original balance: %f TFT\n", report.original))
message.WriteString(fmt.Sprintf("\t\t- Balance after deposit with stellar bridge: %f TFT\n", report.afterSendingToChain))
message.WriteString(fmt.Sprintf("\t\t- Balance after withdraw with stellar bridge: %f TFT\n", report.afterSendingToStellar))
message.WriteString("\tBridge Operation Results:\n")
message.WriteString("\t1. Initial State:\n")
message.WriteString(fmt.Sprintf("\t - TFChain Balance: %f TFT\n", report.original))
message.WriteString(fmt.Sprintf("\t - Stellar Balance: %f TFT\n", report.originalStellar))
message.WriteString("\t2. Deposit (Stellar → TFChain):\n")
message.WriteString(fmt.Sprintf("\t - TFChain Balance: %f TFT (+%f TFT)\n",
report.afterSendingToChain,
report.afterSendingToChain-report.original))
message.WriteString(fmt.Sprintf("\t - Stellar Balance: %f TFT (-%f TFT)\n",
report.stellarAfterDeposit,
report.originalStellar-report.stellarAfterDeposit))
message.WriteString("\t3. Withdraw (TFChain → Stellar):\n")
message.WriteString(fmt.Sprintf("\t - TFChain Balance: %f TFT (-%f TFT)\n",
report.afterSendingToStellar,
report.afterSendingToChain-report.afterSendingToStellar))
message.WriteString(fmt.Sprintf("\t - Stellar Balance: %f TFT (+%f TFT)\n",
report.stellarAfterWithdraw,
report.stellarAfterWithdraw-report.stellarAfterDeposit))
message.WriteString("\n")
}

Expand All @@ -57,44 +74,84 @@ func (m *Monitor) monitorBridge(net network) (balanceReport, error) {
return balanceReport{}, err
}

// get current balance
originalBalance, err := m.getBalance(m.managers[net], address(identity.Address()))
// get current balances
originalTFChainBalance, err := m.getBalance(m.managers[net], address(identity.Address()))
if err != nil {
return balanceReport{}, fmt.Errorf("failed to get balance for account: %w", err)
return balanceReport{}, fmt.Errorf("failed to get TFChain balance for account: %w", err)
}
originalStellarBalance, err := m.getStellarBalance(net)
if err != nil {
return balanceReport{}, fmt.Errorf("failed to get Stellar balance for account: %w", err)
}

balanceAfterChain, err := m.bridgeTXWrapper(m.sendToTfChain)(identity, net)
// Deposit: send TFT from Stellar to TFChain
tfchainAfterDeposit, stellarAfterDeposit, err := m.bridgeTXWrapper(
m.sendToTfChain,
originalTFChainBalance,
originalStellarBalance,
true,
)(identity, net)
if err != nil {
return balanceReport{}, err
}

balanceAfterStellar, err := m.bridgeTXWrapper(m.sendToStellar)(identity, net)
// Withdraw: send TFT from TFChain to Stellar
tfchainAfterWithdraw, stellarAfterWithdraw, err := m.bridgeTXWrapper(
m.sendToStellar,
tfchainAfterDeposit,
stellarAfterDeposit,
false,
)(identity, net)
if err != nil {
return balanceReport{}, err
}

return balanceReport{
original: originalBalance,
afterSendingToChain: balanceAfterChain,
afterSendingToStellar: balanceAfterStellar,
original: originalTFChainBalance,
afterSendingToChain: tfchainAfterDeposit,
afterSendingToStellar: tfchainAfterWithdraw,
originalStellar: originalStellarBalance,
stellarAfterDeposit: stellarAfterDeposit,
stellarAfterWithdraw: stellarAfterWithdraw,
}, nil
}

// bridgeTXWrapper does the bridge transaction, and get the balance after waiting a period of time
func (m *Monitor) bridgeTXWrapper(tx bridgeTX) func(identity client.Identity, net network) (float64, error) {
return func(identity client.Identity, net network) (float64, error) {
func (m *Monitor) bridgeTXWrapper(
tx bridgeTX,
initialTFChain float64,
initialStellar float64,
tfchainIncrease bool,
) func(identity client.Identity, net network) (float64, float64, error) {
return func(identity client.Identity, net network) (float64, float64, error) {
if err := tx(identity, net); err != nil {
return 0, err
return 0, 0, err
}

<-time.After(balanceWaitIntervalSeconds * time.Second)

balanceAfterChain, err := m.getBalance(m.managers[net], address(identity.Address()))
// Check TFChain balance
tfchainNew, err := m.getBalance(m.managers[net], address(identity.Address()))
if err != nil {
return 0, 0, fmt.Errorf("failed to get TFChain balance after transaction: %w", err)
}

// Check Stellar balance
stellarNew, err := m.getStellarBalance(net)
if err != nil {
return 0, fmt.Errorf("failed to get balance for account: %w", err)
return 0, 0, fmt.Errorf("failed to get Stellar balance after transaction: %w", err)
}

return balanceAfterChain, nil
if tfchainIncrease {
if tfchainNew <= initialTFChain {
return 0, 0, fmt.Errorf("TFChain balance did not increase: before=%f, after=%f", initialTFChain, tfchainNew)
}
} else {
if stellarNew <= initialStellar {
return 0, 0, fmt.Errorf("Stellar balance did not increase: before=%f, after=%f", initialStellar, stellarNew)
}
}
return tfchainNew, stellarNew, nil
}
}

Expand Down
4 changes: 2 additions & 2 deletions monitoring-bot/internal/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const (

tftIssuerStellarTest = "GA47YZA3PKFUZMPLQ3B5F2E3CJIB57TGGU7SPCQT2WAEYKN766PWIMB3"
tftIssuerStellarPublic = "GBOVQKJYHXRR3DX6NOX2RRYFRCUMSADGDESTDNBDS6CDVLGVESRTAC47"
bridgeTestTFTAmount = 2
bridgeTestTFTAmount = 3
txnTimeoutSeconds = 60
balanceWaitIntervalSeconds = 30
balanceWaitIntervalSeconds = 60

telegramBotURL = "https://api.telegram.org/bot"
)
Expand Down
29 changes: 29 additions & 0 deletions monitoring-bot/internal/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import (
"math/rand"
"net/http"
"os"
"strconv"
"strings"
"time"

"github.com/cosmos/go-bip39"
"github.com/rs/zerolog/log"
"github.com/stellar/go/clients/horizonclient"
substrate "github.com/threefoldtech/tfchain/clients/tfchain-client-go"
"github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go/peer"
)
Expand Down Expand Up @@ -238,6 +240,33 @@ func (m *Monitor) getBalance(manager substrate.Manager, address address) (float6
return float64(balance.Free.Int64()) / math.Pow(10, 7), nil
}

// getStellarBalance gets the balance in TFT for the address given
func (m *Monitor) getStellarBalance(net network) (float64, error) {
strClient := horizonclient.DefaultTestNetClient
strAddress := m.env.testStellarAddress
stellarTFTIssuerAddress := tftIssuerStellarTest
if net == mainNetwork || net == testNetwork {
strClient = horizonclient.DefaultPublicNetClient
strAddress = m.env.publicStellarAddress
stellarTFTIssuerAddress = tftIssuerStellarPublic
}

accountRequest := horizonclient.AccountRequest{AccountID: strAddress}
account, err := strClient.AccountDetail(accountRequest)
if err != nil {
errMsg := getHorizonError(err)
return 0, fmt.Errorf("failed to get stellar account: %s", errMsg)
}

for _, balance := range account.Balances {
if balance.Asset.Code == "TFT" && balance.Asset.Issuer == stellarTFTIssuerAddress {
return strconv.ParseFloat(balance.Balance, 64)
}
}

return 0, fmt.Errorf("TFT not found in stellar account balances")
}

// monitorBalance sends a message with the balance to a telegram bot
// if it is less than the tft threshold
func (m *Monitor) monitorBalance(manager substrate.Manager, wallet wallet) error {
Expand Down