feat_: recovery retracking pending transsactions
Add ReTrackOwnerTokenDeploymentTransaction function which will runs community tokens transactions listening. Add deployment transaction hash to community_tokens table. Issue #14699
This commit is contained in:
parent
edc65e4611
commit
ad9032d036
|
@ -1241,7 +1241,7 @@ func (p *Persistence) GetCommunityChatIDs(communityID types.HexBytes) ([]string,
|
|||
func (p *Persistence) GetAllCommunityTokens() ([]*token.CommunityToken, error) {
|
||||
rows, err := p.db.Query(`SELECT community_id, address, type, name, symbol, description, supply_str,
|
||||
infinite_supply, transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals,
|
||||
deployer, privileges_level FROM community_tokens`)
|
||||
deployer, privileges_level, tx_hash FROM community_tokens`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1253,7 +1253,7 @@ func (p *Persistence) GetAllCommunityTokens() ([]*token.CommunityToken, error) {
|
|||
func (p *Persistence) GetCommunityTokens(communityID string) ([]*token.CommunityToken, error) {
|
||||
rows, err := p.db.Query(`SELECT community_id, address, type, name, symbol, description, supply_str,
|
||||
infinite_supply, transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals,
|
||||
deployer, privileges_level
|
||||
deployer, privileges_level, tx_hash
|
||||
FROM community_tokens WHERE community_id = ?`, communityID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1267,11 +1267,11 @@ func (p *Persistence) GetCommunityToken(communityID string, chainID int, address
|
|||
token := token.CommunityToken{}
|
||||
var supplyStr string
|
||||
err := p.db.QueryRow(`SELECT community_id, address, type, name, symbol, description, supply_str, infinite_supply,
|
||||
transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level
|
||||
transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level, tx_hash
|
||||
FROM community_tokens WHERE community_id = ? AND chain_id = ? AND address = ?`, communityID, chainID, address).Scan(&token.CommunityID, &token.Address, &token.TokenType, &token.Name,
|
||||
&token.Symbol, &token.Description, &supplyStr, &token.InfiniteSupply, &token.Transferable,
|
||||
&token.RemoteSelfDestruct, &token.ChainID, &token.DeployState, &token.Base64Image, &token.Decimals,
|
||||
&token.Deployer, &token.PrivilegesLevel)
|
||||
&token.Deployer, &token.PrivilegesLevel, &token.TransactionHash)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
|
@ -1290,11 +1290,11 @@ func (p *Persistence) GetCommunityTokenByChainAndAddress(chainID int, address st
|
|||
token := token.CommunityToken{}
|
||||
var supplyStr string
|
||||
err := p.db.QueryRow(`SELECT community_id, address, type, name, symbol, description, supply_str, infinite_supply,
|
||||
transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level
|
||||
transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level, tx_hash
|
||||
FROM community_tokens WHERE chain_id = ? AND address = ?`, chainID, address).Scan(&token.CommunityID, &token.Address, &token.TokenType, &token.Name,
|
||||
&token.Symbol, &token.Description, &supplyStr, &token.InfiniteSupply, &token.Transferable,
|
||||
&token.RemoteSelfDestruct, &token.ChainID, &token.DeployState, &token.Base64Image, &token.Decimals,
|
||||
&token.Deployer, &token.PrivilegesLevel)
|
||||
&token.Deployer, &token.PrivilegesLevel, &token.TransactionHash)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
|
@ -1318,7 +1318,7 @@ func (p *Persistence) getCommunityTokensInternal(rows *sql.Rows) ([]*token.Commu
|
|||
err := rows.Scan(&token.CommunityID, &token.Address, &token.TokenType, &token.Name,
|
||||
&token.Symbol, &token.Description, &supplyStr, &token.InfiniteSupply, &token.Transferable,
|
||||
&token.RemoteSelfDestruct, &token.ChainID, &token.DeployState, &token.Base64Image, &token.Decimals,
|
||||
&token.Deployer, &token.PrivilegesLevel)
|
||||
&token.Deployer, &token.PrivilegesLevel, &token.TransactionHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1345,10 +1345,10 @@ func (p *Persistence) HasCommunityToken(communityID string, address string, chai
|
|||
|
||||
func (p *Persistence) AddCommunityToken(token *token.CommunityToken) error {
|
||||
_, err := p.db.Exec(`INSERT INTO community_tokens (community_id, address, type, name, symbol, description, supply_str,
|
||||
infinite_supply, transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, token.CommunityID, token.Address, token.TokenType, token.Name,
|
||||
infinite_supply, transferable, remote_self_destruct, chain_id, deploy_state, image_base64, decimals, deployer, privileges_level, tx_hash)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, token.CommunityID, token.Address, token.TokenType, token.Name,
|
||||
token.Symbol, token.Description, token.Supply.String(), token.InfiniteSupply, token.Transferable, token.RemoteSelfDestruct,
|
||||
token.ChainID, token.DeployState, token.Base64Image, token.Decimals, token.Deployer, token.PrivilegesLevel)
|
||||
token.ChainID, token.DeployState, token.Base64Image, token.Decimals, token.Deployer, token.PrivilegesLevel, token.TransactionHash)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -395,6 +395,7 @@ func (s *PersistenceSuite) TestGetCommunityToken() {
|
|||
ChainID: 1,
|
||||
DeployState: token.InProgress,
|
||||
Base64Image: "ABCD",
|
||||
TransactionHash: "0x1234",
|
||||
}
|
||||
|
||||
err = s.db.AddCommunityToken(&tokenERC721)
|
||||
|
@ -426,6 +427,7 @@ func (s *PersistenceSuite) TestGetCommunityTokens() {
|
|||
Base64Image: "ABCD",
|
||||
Deployer: "0xDep1",
|
||||
PrivilegesLevel: token.OwnerLevel,
|
||||
TransactionHash: "0x1234",
|
||||
}
|
||||
|
||||
tokenERC20 := token.CommunityToken{
|
||||
|
@ -445,6 +447,7 @@ func (s *PersistenceSuite) TestGetCommunityTokens() {
|
|||
Decimals: 21,
|
||||
Deployer: "0xDep2",
|
||||
PrivilegesLevel: token.CommunityLevel,
|
||||
TransactionHash: "0x123456",
|
||||
}
|
||||
|
||||
err = s.db.AddCommunityToken(&tokenERC721)
|
||||
|
|
|
@ -38,4 +38,5 @@ type CommunityToken struct {
|
|||
Decimals int `json:"decimals"`
|
||||
Deployer string `json:"deployer"`
|
||||
PrivilegesLevel PrivilegesLevel `json:"privilegesLevel"`
|
||||
TransactionHash string `json:"transactionHash"`
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@
|
|||
// 1715163152_remove_status_community.up.sql (354B)
|
||||
// 1715163262_rename_peersyncing_group_id_field.up.sql (212B)
|
||||
// 1716413241_remove_social_links.up.sql (38B)
|
||||
// 1716891408_add_community_token_transaction_hash.up.sql (65B)
|
||||
// README.md (554B)
|
||||
// doc.go (870B)
|
||||
|
||||
|
@ -2988,6 +2989,26 @@ func _1716413241_remove_social_linksUpSql() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1716891408_add_community_token_transaction_hashUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\xf4\x09\x71\x0d\x52\x08\x71\x74\xf2\x71\x55\x48\xce\xcf\xcd\x2d\xcd\xcb\x2c\xa9\x8c\x2f\xc9\xcf\x4e\xcd\x2b\x56\x70\x74\x71\x51\x70\xf6\xf7\x09\xf5\xf5\x53\x28\xa9\x88\xcf\x48\x2c\xce\x50\x08\x71\x8d\x08\x51\x70\x71\x75\x73\x0c\xf5\x09\x51\x50\x52\xb2\xe6\x02\x04\x00\x00\xff\xff\xb6\x77\x1a\x00\x41\x00\x00\x00")
|
||||
|
||||
func _1716891408_add_community_token_transaction_hashUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__1716891408_add_community_token_transaction_hashUpSql,
|
||||
"1716891408_add_community_token_transaction_hash.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _1716891408_add_community_token_transaction_hashUpSql() (*asset, error) {
|
||||
bytes, err := _1716891408_add_community_token_transaction_hashUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1716891408_add_community_token_transaction_hash.up.sql", size: 65, mode: os.FileMode(0644), modTime: time.Unix(1700000000, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7b, 0x3, 0x3d, 0x99, 0x3b, 0x47, 0xae, 0xa4, 0x94, 0x48, 0x3f, 0x40, 0xfb, 0x75, 0x8f, 0x1e, 0x38, 0x1c, 0x66, 0x13, 0x32, 0x2c, 0xb4, 0xbe, 0xce, 0x91, 0x55, 0xd5, 0x34, 0xe4, 0xb3, 0xda}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00")
|
||||
|
||||
func readmeMdBytes() ([]byte, error) {
|
||||
|
@ -3258,8 +3279,9 @@ var _bindata = map[string]func() (*asset, error){
|
|||
"1715163152_remove_status_community.up.sql": _1715163152_remove_status_communityUpSql,
|
||||
"1715163262_rename_peersyncing_group_id_field.up.sql": _1715163262_rename_peersyncing_group_id_fieldUpSql,
|
||||
"1716413241_remove_social_links.up.sql": _1716413241_remove_social_linksUpSql,
|
||||
"README.md": readmeMd,
|
||||
"doc.go": docGo,
|
||||
"1716891408_add_community_token_transaction_hash.up.sql": _1716891408_add_community_token_transaction_hashUpSql,
|
||||
"README.md": readmeMd,
|
||||
"doc.go": docGo,
|
||||
}
|
||||
|
||||
// AssetDebug is true if the assets were built with the debug flag enabled.
|
||||
|
@ -3447,8 +3469,9 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
|||
"1715163152_remove_status_community.up.sql": {_1715163152_remove_status_communityUpSql, map[string]*bintree{}},
|
||||
"1715163262_rename_peersyncing_group_id_field.up.sql": {_1715163262_rename_peersyncing_group_id_fieldUpSql, map[string]*bintree{}},
|
||||
"1716413241_remove_social_links.up.sql": {_1716413241_remove_social_linksUpSql, map[string]*bintree{}},
|
||||
"README.md": {readmeMd, map[string]*bintree{}},
|
||||
"doc.go": {docGo, map[string]*bintree{}},
|
||||
"1716891408_add_community_token_transaction_hash.up.sql": {_1716891408_add_community_token_transaction_hashUpSql, map[string]*bintree{}},
|
||||
"README.md": {readmeMd, map[string]*bintree{}},
|
||||
"doc.go": {docGo, map[string]*bintree{}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE community_tokens ADD COLUMN tx_hash TEXT DEFAULT "";
|
|
@ -137,7 +137,7 @@ func (api *API) DeployCollectibles(ctx context.Context, chainID uint64, deployme
|
|||
}
|
||||
|
||||
savedCommunityToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), deploymentParameters, txArgs.From.Hex(), address.Hex(),
|
||||
protobuf.CommunityTokenType_ERC721, token.CommunityLevel)
|
||||
protobuf.CommunityTokenType_ERC721, token.CommunityLevel, tx.Hash().Hex())
|
||||
if err != nil {
|
||||
return DeploymentDetails{}, err
|
||||
}
|
||||
|
@ -249,12 +249,12 @@ func (api *API) DeployOwnerToken(ctx context.Context, chainID uint64,
|
|||
}
|
||||
|
||||
savedOwnerToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), ownerTokenParameters, txArgs.From.Hex(),
|
||||
api.s.TemporaryOwnerContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.OwnerLevel)
|
||||
api.s.TemporaryOwnerContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.OwnerLevel, tx.Hash().Hex())
|
||||
if err != nil {
|
||||
return DeploymentDetails{}, err
|
||||
}
|
||||
savedMasterToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), masterTokenParameters, txArgs.From.Hex(),
|
||||
api.s.TemporaryMasterContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.MasterLevel)
|
||||
api.s.TemporaryMasterContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.MasterLevel, tx.Hash().Hex())
|
||||
if err != nil {
|
||||
return DeploymentDetails{}, err
|
||||
}
|
||||
|
@ -266,6 +266,11 @@ func (api *API) DeployOwnerToken(ctx context.Context, chainID uint64,
|
|||
MasterToken: savedMasterToken}, nil
|
||||
}
|
||||
|
||||
// recovery function which starts transaction tracking again
|
||||
func (api *API) ReTrackOwnerTokenDeploymentTransaction(ctx context.Context, chainID uint64, contractAddress string) error {
|
||||
return api.s.ReTrackOwnerTokenDeploymentTransaction(ctx, chainID, contractAddress)
|
||||
}
|
||||
|
||||
func (api *API) DeployAssets(ctx context.Context, chainID uint64, deploymentParameters DeploymentParameters, txArgs transactions.SendTxArgs, password string) (DeploymentDetails, error) {
|
||||
|
||||
err := deploymentParameters.Validate(true)
|
||||
|
@ -307,7 +312,7 @@ func (api *API) DeployAssets(ctx context.Context, chainID uint64, deploymentPara
|
|||
}
|
||||
|
||||
savedCommunityToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), deploymentParameters, txArgs.From.Hex(), address.Hex(),
|
||||
protobuf.CommunityTokenType_ERC20, token.CommunityLevel)
|
||||
protobuf.CommunityTokenType_ERC20, token.CommunityLevel, tx.Hash().Hex())
|
||||
if err != nil {
|
||||
return DeploymentDetails{}, err
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
|
@ -512,7 +513,7 @@ func (s *Service) maxSupply(ctx context.Context, chainID uint64, contractAddress
|
|||
}
|
||||
|
||||
func (s *Service) CreateCommunityTokenAndSave(chainID int, deploymentParameters DeploymentParameters,
|
||||
deployerAddress string, contractAddress string, tokenType protobuf.CommunityTokenType, privilegesLevel token.PrivilegesLevel) (*token.CommunityToken, error) {
|
||||
deployerAddress string, contractAddress string, tokenType protobuf.CommunityTokenType, privilegesLevel token.PrivilegesLevel, transactionHash string) (*token.CommunityToken, error) {
|
||||
|
||||
tokenToSave := &token.CommunityToken{
|
||||
TokenType: tokenType,
|
||||
|
@ -531,17 +532,32 @@ func (s *Service) CreateCommunityTokenAndSave(chainID int, deploymentParameters
|
|||
Deployer: deployerAddress,
|
||||
PrivilegesLevel: privilegesLevel,
|
||||
Base64Image: deploymentParameters.Base64Image,
|
||||
TransactionHash: transactionHash,
|
||||
}
|
||||
|
||||
return s.Messenger.SaveCommunityToken(tokenToSave, deploymentParameters.CroppedImage)
|
||||
}
|
||||
|
||||
const (
|
||||
MasterSuffix = "-master"
|
||||
OwnerSuffix = "-owner"
|
||||
)
|
||||
|
||||
func (s *Service) TemporaryMasterContractAddress(hash string) string {
|
||||
return hash + "-master"
|
||||
return hash + MasterSuffix
|
||||
}
|
||||
|
||||
func (s *Service) TemporaryOwnerContractAddress(hash string) string {
|
||||
return hash + "-owner"
|
||||
return hash + OwnerSuffix
|
||||
}
|
||||
|
||||
func (s *Service) HashFromTemporaryContractAddress(address string) string {
|
||||
if strings.HasSuffix(address, OwnerSuffix) {
|
||||
return strings.TrimSuffix(address, OwnerSuffix)
|
||||
} else if strings.HasSuffix(address, MasterSuffix) {
|
||||
return strings.TrimSuffix(address, MasterSuffix)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *Service) GetMasterTokenContractAddressFromHash(ctx context.Context, chainID uint64, txHash string) (string, error) {
|
||||
|
@ -605,3 +621,48 @@ func (s *Service) GetOwnerTokenContractAddressFromHash(ctx context.Context, chai
|
|||
}
|
||||
return "", fmt.Errorf("can't find owner token address in transaction: %v", txHash)
|
||||
}
|
||||
|
||||
func (s *Service) ReTrackOwnerTokenDeploymentTransaction(ctx context.Context, chainID uint64, contractAddress string) error {
|
||||
communityToken, err := s.Messenger.GetCommunityTokenByChainAndAddress(int(chainID), contractAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if communityToken == nil {
|
||||
return fmt.Errorf("can't find token with address %v on chain %v", contractAddress, chainID)
|
||||
}
|
||||
if communityToken.DeployState != token.InProgress {
|
||||
return fmt.Errorf("token with address %v on chain %v is not in progress", contractAddress, chainID)
|
||||
}
|
||||
|
||||
hashString := communityToken.TransactionHash
|
||||
if hashString == "" && (communityToken.PrivilegesLevel == token.OwnerLevel || communityToken.PrivilegesLevel == token.MasterLevel) {
|
||||
hashString = s.HashFromTemporaryContractAddress(communityToken.Address)
|
||||
}
|
||||
|
||||
if hashString == "" {
|
||||
return fmt.Errorf("can't find transaction hash for token with address %v on chain %v", contractAddress, chainID)
|
||||
}
|
||||
|
||||
transactionType := transactions.DeployCommunityToken
|
||||
if communityToken.PrivilegesLevel == token.OwnerLevel || communityToken.PrivilegesLevel == token.MasterLevel {
|
||||
transactionType = transactions.DeployOwnerToken
|
||||
}
|
||||
|
||||
_, err = s.pendingTracker.GetPendingEntry(wcommon.ChainID(chainID), common.HexToHash(hashString))
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
// start only if no pending transaction in database
|
||||
err = s.pendingTracker.TrackPendingTransaction(
|
||||
wcommon.ChainID(chainID),
|
||||
common.HexToHash(hashString),
|
||||
common.HexToAddress(communityToken.Deployer),
|
||||
common.Address{},
|
||||
transactionType,
|
||||
transactions.Keep,
|
||||
"",
|
||||
)
|
||||
log.Debug("retracking pending transaction with hashId ", hashString)
|
||||
} else {
|
||||
log.Debug("pending transaction with hashId is already tracked ", hashString)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue