From c6a166396db6caebe0fee2cda89cef2bdd6873c6 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 13:25:00 +0300 Subject: [PATCH 01/11] update: config for EVM network broadcaster; add: separate config for airdrop parameters --- config.yaml | 11 ++- go.mod | 1 + go.sum | 6 +- internal/config/airdrop.go | 49 +++++++++++ internal/config/broadcaster.go | 150 ++++++++++++++++++--------------- internal/config/main.go | 2 + 6 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 internal/config/airdrop.go diff --git a/config.yaml b/config.yaml index 301f91c..bf92fb5 100644 --- a/config.yaml +++ b/config.yaml @@ -3,14 +3,17 @@ log: disable_sentry: true db: - url: postgres://airdrop:airdrop@localhost:5432/airdrop?sslmode=disable + url: db_url listener: - addr: localhost:8000 + addr: :8000 + +airdrop: + amount: amount + token_address: erc20_token_address broadcaster: - airdrop_amount: 100stake - cosmos_rpc: rpc_url + rpc: evm_rpc_url chain_id: chain_id sender_private_key: priv_key query_limit: 10 diff --git a/go.mod b/go.mod index 576498c..442db4c 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/rarimo/zkverifier-kit v0.2.1 github.com/rubenv/sql-migrate v1.6.1 gitlab.com/distributed_lab/ape v1.7.1 + gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c gitlab.com/distributed_lab/figure/v3 v3.1.4 gitlab.com/distributed_lab/kit v1.11.3 gitlab.com/distributed_lab/logan v3.8.1+incompatible diff --git a/go.sum b/go.sum index b7b08cc..e6ea617 100644 --- a/go.sum +++ b/go.sum @@ -2106,10 +2106,6 @@ github.com/rarimo/cosmos-sdk v0.46.7 h1:jU2PiWzc+19SF02cXM0O0puKPeH1C6Q6t2lzJ9s1 github.com/rarimo/cosmos-sdk v0.46.7/go.mod h1:fqKqz39U5IlEFb4nbQ72951myztsDzFKKDtffYJ63nk= github.com/rarimo/rarimo-core v0.0.0-20231004143803-6b209428ecbf h1:NvYhOErW0d7ohn2YzGxQYKssrgVrKOvjrKL1OBQgCB4= github.com/rarimo/rarimo-core v0.0.0-20231004143803-6b209428ecbf/go.mod h1:Onkd0EJP94hw4dT/2KH7QXRwDG4eIGeaMffSjA1i6/s= -github.com/rarimo/zkverifier-kit v0.2.1-rc.4 h1:ZpCY2toKFroHK6lpttrkZ0wvb27JbZU5L15N8KSfblc= -github.com/rarimo/zkverifier-kit v0.2.1-rc.4/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= -github.com/rarimo/zkverifier-kit v0.2.1-rc.5 h1:NN7iW40q3p6EIfAd7bxF0XdisV8AyrMQJ3g28FUstZw= -github.com/rarimo/zkverifier-kit v0.2.1-rc.5/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rarimo/zkverifier-kit v0.2.1 h1:t/5L27RIKQEtXmocPcNeta3XV5oxz891g8NFCLeIsao= github.com/rarimo/zkverifier-kit v0.2.1/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -2317,6 +2313,8 @@ github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= gitlab.com/distributed_lab/ape v1.7.1 h1:LpTmZgG7Lvx6ulopQbH2aWI3s8ey9FsKVjbic3ZQIy4= gitlab.com/distributed_lab/ape v1.7.1/go.mod h1:Qy9Y2arL0hmZIpVpctGEFhdrVsjWtyVJ5G+bZWcFT4s= +gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c h1:cqPwdAw7oJpNeN0F80bg5vNI5t3oJoSCPSnC6oj+Zyw= +gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c/go.mod h1:NT4H8lLoIqJxFa9AM88+6uUZ38BmxnFU8VOm/LJYUF4= gitlab.com/distributed_lab/figure v2.1.2+incompatible h1:xO1KCYPK9KFx6OUBOaJ62d8vYd1R3aNgidHlC/ZtVBA= gitlab.com/distributed_lab/figure v2.1.2+incompatible/go.mod h1:tk+aPBohT49MGPLy5+eVbE1HpD/CaC5drBHfVpRI8eE= gitlab.com/distributed_lab/figure/v3 v3.1.4 h1:Wa9FtWkDcgzL53JmiZl3j17L2ugJ4o1u/5C2wiXCJgw= diff --git a/internal/config/airdrop.go b/internal/config/airdrop.go new file mode 100644 index 0000000..72a34f8 --- /dev/null +++ b/internal/config/airdrop.go @@ -0,0 +1,49 @@ +package config + +import ( + "gitlab.com/distributed_lab/figure/v3" + "gitlab.com/distributed_lab/kit/comfig" + "gitlab.com/distributed_lab/kit/kv" + "gitlab.com/distributed_lab/logan/v3" + "gitlab.com/distributed_lab/logan/v3/errors" +) + +const airdropYamlKey = "airdrop" + +type AirdropConfiger interface { + AridropConfig() *AirdropConfig +} + +type AirdropConfig struct { + Amount int64 `fig:"amount,required"` + TokenAddress string `fig:"token_address,required"` +} + +type airdrop struct { + once comfig.Once + getter kv.Getter +} + +func NewAirdropConfiger(getter kv.Getter) AirdropConfiger { + return &airdrop{ + getter: getter, + } +} + +func (v *airdrop) AridropConfig() *AirdropConfig { + return v.once.Do(func() interface{} { + var result AirdropConfig + + err := figure. + Out(&result). + From(kv.MustGetStringMap(v.getter, airdropYamlKey)). + Please() + if err != nil { + panic(errors.Wrap(err, "failed to figure out config", logan.F{ + "yaml_key": airdropYamlKey, + })) + } + + return &result + }).(*AirdropConfig) +} diff --git a/internal/config/broadcaster.go b/internal/config/broadcaster.go index f518dcf..4c88321 100644 --- a/internal/config/broadcaster.go +++ b/internal/config/broadcaster.go @@ -1,40 +1,32 @@ package config import ( + "context" + "crypto/ecdsa" "fmt" - "time" - - sdkclient "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/bech32" - txclient "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/ethereum/go-ethereum/common/hexutil" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "gitlab.com/distributed_lab/dig" "gitlab.com/distributed_lab/figure/v3" "gitlab.com/distributed_lab/kit/comfig" "gitlab.com/distributed_lab/kit/kv" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/keepalive" ) -const accountPrefix = "rarimo" +const broadcasterYamlKey = "broadcaster" type Broadcaster struct { - AirdropCoins types.Coins - Sender cryptotypes.PrivKey - SenderAddress string - ChainID string - TxConfig sdkclient.TxConfig - TxClient txclient.ServiceClient - Auth authtypes.QueryClient - QueryLimit uint64 + RPC *ethclient.Client + ChainID *big.Int + PrivateKey *ecdsa.PrivateKey + Address common.Address + QueryLimit uint64 + + nonce uint64 + mut *sync.Mutex } type Broadcasterer interface { @@ -55,44 +47,23 @@ func NewBroadcaster(getter kv.Getter) Broadcasterer { func (b *broadcasterer) Broadcaster() Broadcaster { return b.once.Do(func() interface{} { var cfg struct { - AirdropAmount string `fig:"airdrop_amount,required"` - CosmosRPC string `fig:"cosmos_rpc,required"` - ChainID string `fig:"chain_id,required"` - SenderPrivateKey string `fig:"sender_private_key,required"` - QueryLimit uint64 `fig:"query_limit"` + RPC *ethclient.Client `fig:"rpc,required"` + ChainID *big.Int `fig:"chain_id,required"` + QueryLimit uint64 `fig:"query_limit"` + SenderPrivateKey *ecdsa.PrivateKey `fig:"sender_private_key"` } - err := figure.Out(&cfg).From(kv.MustGetStringMap(b.getter, "broadcaster")).Please() + err := figure. + Out(&cfg). + With(figure.BaseHooks, figure.EthereumHooks). + From(kv.MustGetStringMap(b.getter, broadcasterYamlKey)). + Please() if err != nil { panic(fmt.Errorf("failed to figure out broadcaster: %w", err)) } - amount, err := types.ParseCoinsNormalized(cfg.AirdropAmount) - if err != nil { - panic(fmt.Errorf("broadcaster: invalid airdrop amount: %w", err)) - } - - cosmosRPC, err := grpc.Dial( - cfg.CosmosRPC, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithKeepaliveParams(keepalive.ClientParameters{ - Time: 10 * time.Second, // wait time before ping if no activity - Timeout: 20 * time.Second, // ping timeout - }), - ) - if err != nil { - panic(fmt.Errorf("broadcaster: failed to dial cosmos core rpc: %w", err)) - } - - privateKey, err := hexutil.Decode(cfg.SenderPrivateKey) - if err != nil { - panic(fmt.Errorf("broadcaster: sender private key is not a hex string: %w", err)) - } - - sender := &secp256k1.PrivKey{Key: privateKey} - address, err := bech32.ConvertAndEncode(accountPrefix, sender.PubKey().Address().Bytes()) - if err != nil { - panic(fmt.Errorf("failed to convert and encode sender address: %w", err)) + if cfg.SenderPrivateKey == nil { + cfg.SenderPrivateKey = extractPubKey() } queryLimit := uint64(100) @@ -100,18 +71,59 @@ func (b *broadcasterer) Broadcaster() Broadcaster { queryLimit = cfg.QueryLimit } + address := crypto.PubkeyToAddress(cfg.SenderPrivateKey.PublicKey) + nonce, err := cfg.RPC.NonceAt(context.Background(), address, nil) + if err != nil { + panic(fmt.Errorf("failed to get nonce %w", err)) + } + return Broadcaster{ - Sender: sender, - SenderAddress: address, - ChainID: cfg.ChainID, - TxConfig: authtx.NewTxConfig( - codec.NewProtoCodec(codectypes.NewInterfaceRegistry()), - []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}, - ), - TxClient: txclient.NewServiceClient(cosmosRPC), - Auth: authtypes.NewQueryClient(cosmosRPC), - AirdropCoins: amount, - QueryLimit: queryLimit, + PrivateKey: cfg.SenderPrivateKey, + Address: address, + ChainID: cfg.ChainID, + QueryLimit: queryLimit, + + nonce: nonce, + mut: &sync.Mutex{}, } }).(Broadcaster) } + +func extractPubKey() *ecdsa.PrivateKey { + var envPK struct { + PrivateKey *ecdsa.PrivateKey `dig:"PRIVATE_KEY,clear"` + } + + if err := dig.Out(&envPK).With(figure.EthereumHooks).Now(); err != nil { + panic(fmt.Errorf("failed to figure out private key from ENV: %w", err)) + } + + return envPK.PrivateKey +} + +func (n *Broadcaster) LockNonce() { + n.mut.Lock() +} + +func (n *Broadcaster) UnlockNonce() { + n.mut.Unlock() +} + +func (n *Broadcaster) Nonce() uint64 { + return n.nonce +} + +func (n *Broadcaster) IncrementNonce() { + n.nonce++ +} + +// ResetNonce sets nonce to the value received from a node +func (n *Broadcaster) ResetNonce(client *ethclient.Client) error { + nonce, err := client.NonceAt(context.Background(), n.Address, nil) + if err != nil { + return fmt.Errorf("failed to get nonce, %w", err) + } + + n.nonce = nonce + return nil +} diff --git a/internal/config/main.go b/internal/config/main.go index a1f317a..27a65f9 100644 --- a/internal/config/main.go +++ b/internal/config/main.go @@ -13,6 +13,7 @@ type Config struct { comfig.Listenerer identity.VerifierProvider Broadcasterer + AirdropConfiger airdrop comfig.Once verifier comfig.Once @@ -27,5 +28,6 @@ func New(getter kv.Getter) *Config { Logger: comfig.NewLogger(getter, comfig.LoggerOpts{}), VerifierProvider: identity.NewVerifierProvider(getter), Broadcasterer: NewBroadcaster(getter), + AirdropConfiger: NewAirdropConfiger(getter), } } From f9a10b7ad535a4f118efa0adb8421c8e84b2a1ff Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 13:32:12 +0300 Subject: [PATCH 02/11] fix: use address type for ERC20 token --- internal/config/airdrop.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/config/airdrop.go b/internal/config/airdrop.go index 72a34f8..3f1674a 100644 --- a/internal/config/airdrop.go +++ b/internal/config/airdrop.go @@ -1,6 +1,7 @@ package config import ( + "github.com/ethereum/go-ethereum/common" "gitlab.com/distributed_lab/figure/v3" "gitlab.com/distributed_lab/kit/comfig" "gitlab.com/distributed_lab/kit/kv" @@ -15,8 +16,8 @@ type AirdropConfiger interface { } type AirdropConfig struct { - Amount int64 `fig:"amount,required"` - TokenAddress string `fig:"token_address,required"` + Amount int64 `fig:"amount,required"` + TokenAddress common.Address `fig:"token_address,required"` } type airdrop struct { @@ -36,6 +37,7 @@ func (v *airdrop) AridropConfig() *AirdropConfig { err := figure. Out(&result). + With(figure.BaseHooks, figure.EthereumHooks). From(kv.MustGetStringMap(v.getter, airdropYamlKey)). Please() if err != nil { From aa965175257c55e21f57e0e55dea4652fffe16dd Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 15:08:46 +0300 Subject: [PATCH 03/11] update: airdrop cfg amount type, broadcaster to be compatible with EVM ERC20 token transfer txs; remove: comments for broadcaster pkg --- internal/broadcaster/broadcaster.go | 203 ++++++++++++---------------- internal/config/airdrop.go | 10 +- 2 files changed, 92 insertions(+), 121 deletions(-) diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index f398e55..279648b 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -1,37 +1,34 @@ -// Package broadcaster provides the functionality to broadcast transactions to -// the blockchain. It is similar to https://github.com/rarimo/broadcaster-svc, -// but is integrated into evm-airdrop-svc purposely. The mentioned broadcaster does -// not allow you to track even successful transaction submission. -// -// The reason of broadcasting implementation is the same: account sequence -// (nonce) must be strictly incrementing in Cosmos. package broadcaster import ( "context" "fmt" + "math/big" "time" - clienttx "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/types" - client "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - bank "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/rarimo/evm-airdrop-svc/internal/config" "github.com/rarimo/evm-airdrop-svc/internal/data" - ethermint "github.com/rarimo/rarimo-core/ethermint/types" "gitlab.com/distributed_lab/logan/v3" + "gitlab.com/distributed_lab/logan/v3/errors" "gitlab.com/distributed_lab/running" ) -const txCodeSuccess = 0 +const ( + byteSize = 32 + transferFnSignature = "transfer(address,uint256)" +) type Runner struct { log *logan.Entry q *data.AirdropsQ config.Broadcaster + config.AirdropConfig } func Run(ctx context.Context, cfg *config.Config) { @@ -39,9 +36,10 @@ func Run(ctx context.Context, cfg *config.Config) { log.Info("Starting service") r := &Runner{ - log: log, - q: data.NewAirdropsQ(cfg.DB().Clone()), - Broadcaster: cfg.Broadcaster(), + log: log, + q: data.NewAirdropsQ(cfg.DB().Clone()), + Broadcaster: cfg.Broadcaster(), + AirdropConfig: cfg.AridropConfig(), } running.WithBackOff(ctx, r.log, "builtin-broadcaster", r.run, 5*time.Second, 5*time.Second, 5*time.Second) @@ -77,120 +75,70 @@ func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err e } }() - tx, err := r.createAirdropTx(ctx, airdrop) + tx, err := r.genTx(ctx, airdrop) if err != nil { - return fmt.Errorf("create airdrop tx: %w", err) + return fmt.Errorf("failed to generate tx: %w", err) } - txHash, err = r.broadcastTx(ctx, tx) - if err != nil { - return fmt.Errorf("broadcast tx: %w", err) + if err = r.broadcastTx(ctx, tx, airdrop); err != nil { + return fmt.Errorf("failed to broadcast tx: %w", err) } - r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusCompleted) return nil } -func (r *Runner) createAirdropTx(ctx context.Context, airdrop data.Airdrop) ([]byte, error) { - tx, err := r.genTx(ctx, 0, airdrop) - if err != nil { - return nil, fmt.Errorf("failed to generate tx: %w", err) - } +func (r *Runner) genTx(ctx context.Context, airdrop data.Airdrop) (*types.Transaction, error) { + receiver := common.HexToAddress(airdrop.Address) + txData := r.buildTransferTx(airdrop) - gasUsed, err := r.simulateTx(ctx, tx) + gasPrice, gasLimit, err := r.getGasCosts(ctx, receiver, txData) if err != nil { - return nil, fmt.Errorf("failed to simulate tx: %w", err) - } - - tx, err = r.genTx(ctx, gasUsed*3, airdrop) + return nil, fmt.Errorf("failed to get gas costs: %w", err) + } + + tx, err := types.SignNewTx( + r.PrivateKey, + types.NewCancunSigner(r.ChainID), + &types.LegacyTx{ + Nonce: r.Nonce(), + Gas: gasLimit, + GasPrice: gasPrice, + To: &receiver, + Data: txData, + }, + ) if err != nil { - return nil, fmt.Errorf("failed to generate tx after simulation: %w", err) + return nil, fmt.Errorf("failed to sign new tx: %w", err) } return tx, nil } -func (r *Runner) genTx(ctx context.Context, gasLimit uint64, airdrop data.Airdrop) ([]byte, error) { - tx, err := r.buildTransferTx(airdrop) - if err != nil { - return nil, fmt.Errorf("build transfer tx: %w", err) - } - - builder, err := r.TxConfig.WrapTxBuilder(tx) - if err != nil { - return nil, fmt.Errorf("wrap tx with builder: %w", err) - } - builder.SetGasLimit(gasLimit) - // there are no fees on the mainnet now, and applying fees requires a lot of work - builder.SetFeeAmount(types.Coins{types.NewInt64Coin("urmo", 0)}) - - resp, err := r.Auth.Account(ctx, &authtypes.QueryAccountRequest{Address: r.SenderAddress}) - if err != nil { - return nil, fmt.Errorf("get sender account: %w", err) - } - - var account ethermint.EthAccount - if err = account.Unmarshal(resp.Account.Value); err != nil { - return nil, fmt.Errorf("unmarshal sender account: %w", err) - } - - err = builder.SetSignatures(signing.SignatureV2{ - PubKey: r.Sender.PubKey(), - Data: &signing.SingleSignatureData{ - SignMode: r.TxConfig.SignModeHandler().DefaultMode(), - Signature: nil, - }, - Sequence: account.Sequence, - }) - if err != nil { - return nil, fmt.Errorf("set signatures to tx: %w", err) - } - - signerData := xauthsigning.SignerData{ - ChainID: r.ChainID, - AccountNumber: account.AccountNumber, - Sequence: account.Sequence, - } - sigV2, err := clienttx.SignWithPrivKey( - r.TxConfig.SignModeHandler().DefaultMode(), signerData, - builder, r.Sender, r.TxConfig, account.Sequence, - ) - if err != nil { - return nil, fmt.Errorf("sign with private key: %w", err) +func (r *Runner) broadcastTx(ctx context.Context, tx *types.Transaction, airdrop data.Airdrop) error { + if err := r.RPC.SendTransaction(ctx, tx); err != nil { + return fmt.Errorf("failed to send tx: %w", err) } - if err = builder.SetSignatures(sigV2); err != nil { - return nil, fmt.Errorf("set signatures V2: %w", err) - } + r.waitForTransactionMined(ctx, tx, airdrop) - return r.TxConfig.TxEncoder()(builder.GetTx()) + return nil } -func (r *Runner) simulateTx(ctx context.Context, tx []byte) (gasUsed uint64, err error) { - sim, err := r.TxClient.Simulate(ctx, &client.SimulateRequest{TxBytes: tx}) - if err != nil { - return 0, fmt.Errorf("simulate tx: %w", err) - } +func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types.Transaction, airdrop data.Airdrop) { + log := r.log.WithField("tx", transaction.Hash().Hex()) - r.log.Debugf("Gas wanted: %d; gas used in simulation: %d", sim.GasInfo.GasWanted, sim.GasInfo.GasUsed) - return sim.GasInfo.GasUsed, nil -} + go func() { + log.Debugf("waiting to mine") -func (r *Runner) broadcastTx(ctx context.Context, tx []byte) (string, error) { - grpcRes, err := r.TxClient.BroadcastTx(ctx, &client.BroadcastTxRequest{ - Mode: client.BroadcastMode_BROADCAST_MODE_BLOCK, - TxBytes: tx, - }) - if err != nil { - return "", fmt.Errorf("send tx: %w", err) - } - r.log.Debugf("Submitted transaction to the core: %s", grpcRes.TxResponse.TxHash) + _, err := bind.WaitMined(ctx, r.RPC, transaction) + if err != nil { + panic(errors.Wrap(err, "failed to mine transaction")) + } - if grpcRes.TxResponse.Code != txCodeSuccess { - return grpcRes.TxResponse.TxHash, fmt.Errorf("got error code: %d, info: %s, log: %s", grpcRes.TxResponse.Code, grpcRes.TxResponse.Info, grpcRes.TxResponse.RawLog) - } + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted) - return grpcRes.TxResponse.TxHash, nil + log.Debugf("was mined") + }() } // If we don't update tx status from pending, having the successful funds @@ -214,17 +162,38 @@ func (r *Runner) updateAirdropStatus(ctx context.Context, id, txHash, status str }, 2*time.Second, 10*time.Second) } -func (r *Runner) buildTransferTx(airdrop data.Airdrop) (types.Tx, error) { - tx := &bank.MsgSend{ - FromAddress: r.SenderAddress, - ToAddress: airdrop.Address, - Amount: r.AirdropCoins, +func (r *Runner) buildTransferTx(airdrop data.Airdrop) []byte { + methodID := hexutil.Encode(crypto.Keccak256([]byte(transferFnSignature))[:4]) + paddedAddress := common.LeftPadBytes(common.HexToAddress(airdrop.Address).Bytes(), byteSize) + paddedAmount := common.LeftPadBytes(r.Amount.Bytes(), byteSize) + + var txData []byte + txData = append(txData, methodID...) + txData = append(txData, paddedAddress...) + txData = append(txData, paddedAmount...) + + return txData +} + +func (r *Runner) getGasCosts( + ctx context.Context, + receiver common.Address, + txData []byte, +) (gasPrice *big.Int, gasLimit uint64, err error) { + gasPrice, err = r.RPC.SuggestGasPrice(ctx) + if err != nil { + return nil, 0, errors.Wrap(err, "failed to suggest gas price") } - builder := r.TxConfig.NewTxBuilder() - if err := builder.SetMsgs(tx); err != nil { - return nil, fmt.Errorf("set messages: %w", err) + gasLimit, err = r.RPC.EstimateGas(ctx, ethereum.CallMsg{ + From: r.Address, + To: &receiver, + GasPrice: gasPrice, + Data: txData, + }) + if err != nil { + return nil, 0, errors.Wrap(err, "failed to estimate gas limit") } - return builder.GetTx(), nil + return } diff --git a/internal/config/airdrop.go b/internal/config/airdrop.go index 3f1674a..bd3833e 100644 --- a/internal/config/airdrop.go +++ b/internal/config/airdrop.go @@ -1,6 +1,8 @@ package config import ( + "math/big" + "github.com/ethereum/go-ethereum/common" "gitlab.com/distributed_lab/figure/v3" "gitlab.com/distributed_lab/kit/comfig" @@ -12,11 +14,11 @@ import ( const airdropYamlKey = "airdrop" type AirdropConfiger interface { - AridropConfig() *AirdropConfig + AridropConfig() AirdropConfig } type AirdropConfig struct { - Amount int64 `fig:"amount,required"` + Amount *big.Int `fig:"amount,required"` TokenAddress common.Address `fig:"token_address,required"` } @@ -31,7 +33,7 @@ func NewAirdropConfiger(getter kv.Getter) AirdropConfiger { } } -func (v *airdrop) AridropConfig() *AirdropConfig { +func (v *airdrop) AridropConfig() AirdropConfig { return v.once.Do(func() interface{} { var result AirdropConfig @@ -47,5 +49,5 @@ func (v *airdrop) AridropConfig() *AirdropConfig { } return &result - }).(*AirdropConfig) + }).(AirdropConfig) } From 6570709b6e44576c1bb87fd6751f8d010e88d7b5 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 16:04:31 +0300 Subject: [PATCH 04/11] add: nonce locking, with eth addr option for verifier, --- go.mod | 33 +++----------- go.sum | 48 +-------------------- internal/broadcaster/broadcaster.go | 3 ++ internal/service/handlers/create_airdrop.go | 2 +- internal/service/handlers/get_airdrop.go | 2 +- 5 files changed, 12 insertions(+), 76 deletions(-) diff --git a/go.mod b/go.mod index 442db4c..4d74043 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/iden3/go-rapidsnark/types v0.0.3 - github.com/rarimo/rarimo-core v0.0.0-20231004143803-6b209428ecbf - github.com/rarimo/zkverifier-kit v0.2.1 + github.com/rarimo/zkverifier-kit v0.2.2-rc.1 github.com/rubenv/sql-migrate v1.6.1 gitlab.com/distributed_lab/ape v1.7.1 gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c @@ -19,24 +18,18 @@ require ( gitlab.com/distributed_lab/kit v1.11.3 gitlab.com/distributed_lab/logan v3.8.1+incompatible gitlab.com/distributed_lab/running v1.6.0 - google.golang.org/grpc v1.59.0 ) require ( cosmossdk.io/errors v1.0.0-beta.7 // indirect cosmossdk.io/math v1.0.1 // indirect - filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.1 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect - github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd v0.23.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -48,7 +41,6 @@ require ( github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect github.com/cosmos/iavl v0.19.5 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect @@ -63,6 +55,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/felixge/httpsnoop v1.0.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/getsentry/raven-go v0.2.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect @@ -71,7 +64,6 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/protobuf v1.3.3 // indirect github.com/golang/glog v1.1.2 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -80,15 +72,9 @@ require ( github.com/google/jsonapi v1.0.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect - github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/iden3/go-iden3-crypto v0.0.15 // indirect github.com/iden3/go-rapidsnark/verifier v0.0.5 // indirect @@ -101,23 +87,21 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/mtibben/percent v0.2.1 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rs/cors v1.9.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -129,19 +113,14 @@ require ( github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.2 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tendermint/btcd v0.1.1 // indirect - github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/tendermint v0.34.27 // indirect github.com/tendermint/tm-db v0.6.7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect gitlab.com/distributed_lab/figure v2.1.2+incompatible // indirect gitlab.com/distributed_lab/lorem v0.2.1 // indirect go.etcd.io/bbolt v1.3.7 // indirect @@ -152,12 +131,10 @@ require ( golang.org/x/net v0.24.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.20.0 // indirect - google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index e6ea617..9322ad6 100644 --- a/go.sum +++ b/go.sum @@ -1184,8 +1184,6 @@ github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bw github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= @@ -1264,9 +1262,6 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= @@ -1314,8 +1309,6 @@ github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= -github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= @@ -1333,7 +1326,6 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQ github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= @@ -1352,8 +1344,6 @@ github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUp github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= -github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= -github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= @@ -1376,8 +1366,6 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3 github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= @@ -1625,8 +1613,6 @@ github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIG github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= -github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -1705,7 +1691,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4Zs github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= @@ -1739,7 +1724,6 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= @@ -1780,8 +1764,6 @@ github.com/iden3/go-rapidsnark/types v0.0.3/go.mod h1:ApgcaUxKIgSRA6fAeFxK7p+lgX github.com/iden3/go-rapidsnark/verifier v0.0.5 h1:J7y0ovrEjDQoWtZmlrp4tgGng1A9faMeYsQH4igAEqA= github.com/iden3/go-rapidsnark/verifier v0.0.5/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= -github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -1946,7 +1928,6 @@ github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0Em github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= -github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= @@ -2030,7 +2011,6 @@ github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -2104,14 +2084,10 @@ github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rarimo/cosmos-sdk v0.46.7 h1:jU2PiWzc+19SF02cXM0O0puKPeH1C6Q6t2lzJ9s1ejc= github.com/rarimo/cosmos-sdk v0.46.7/go.mod h1:fqKqz39U5IlEFb4nbQ72951myztsDzFKKDtffYJ63nk= -github.com/rarimo/rarimo-core v0.0.0-20231004143803-6b209428ecbf h1:NvYhOErW0d7ohn2YzGxQYKssrgVrKOvjrKL1OBQgCB4= -github.com/rarimo/rarimo-core v0.0.0-20231004143803-6b209428ecbf/go.mod h1:Onkd0EJP94hw4dT/2KH7QXRwDG4eIGeaMffSjA1i6/s= -github.com/rarimo/zkverifier-kit v0.2.1 h1:t/5L27RIKQEtXmocPcNeta3XV5oxz891g8NFCLeIsao= -github.com/rarimo/zkverifier-kit v0.2.1/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= +github.com/rarimo/zkverifier-kit v0.2.2-rc.1 h1:IHf+Ctl/ilHxK37r6oJmhxNUz/tTWB6iDUSxD2uiEaA= +github.com/rarimo/zkverifier-kit v0.2.2-rc.1/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= -github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -2131,8 +2107,6 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= -github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos= github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= @@ -2202,8 +2176,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -2245,14 +2217,6 @@ github.com/tendermint/tendermint v0.34.24 h1:879MKKJWYYPJEMMKME+DWUTY4V9f/FBpnZD github.com/tendermint/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= @@ -2350,7 +2314,6 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= @@ -2362,7 +2325,6 @@ go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTV go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -2375,11 +2337,9 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -2559,7 +2519,6 @@ golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2993,7 +2952,6 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -3275,8 +3233,6 @@ modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index 279648b..af692bf 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -70,11 +70,13 @@ func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err e var txHash string defer func() { + r.UnlockNonce() if err != nil { r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusFailed) } }() + r.LockNonce() tx, err := r.genTx(ctx, airdrop) if err != nil { return fmt.Errorf("failed to generate tx: %w", err) @@ -135,6 +137,7 @@ func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types panic(errors.Wrap(err, "failed to mine transaction")) } + r.IncrementNonce() r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted) log.Debugf("was mined") diff --git a/internal/service/handlers/create_airdrop.go b/internal/service/handlers/create_airdrop.go index 10b01d0..54e7611 100644 --- a/internal/service/handlers/create_airdrop.go +++ b/internal/service/handlers/create_airdrop.go @@ -38,7 +38,7 @@ func CreateAirdrop(w http.ResponseWriter, r *http.Request) { return } - err = Verifier(r).VerifyProof(req.Data.Attributes.ZkProof, zk.WithRarimoAddress(req.Data.Attributes.Address)) + err = Verifier(r).VerifyProof(req.Data.Attributes.ZkProof, zk.WithEthereumAddress(req.Data.Attributes.Address)) if err != nil { if errors.Is(err, identity.ErrContractCall) { Log(r).WithError(err).Error("Failed to verify proof") diff --git a/internal/service/handlers/get_airdrop.go b/internal/service/handlers/get_airdrop.go index 0b3326d..41b5699 100644 --- a/internal/service/handlers/get_airdrop.go +++ b/internal/service/handlers/get_airdrop.go @@ -3,7 +3,7 @@ package handlers import ( "net/http" - data "github.com/rarimo/evm-airdrop-svc/internal/data" + "github.com/rarimo/evm-airdrop-svc/internal/data" "github.com/rarimo/evm-airdrop-svc/internal/service/requests" "github.com/rarimo/evm-airdrop-svc/resources" "gitlab.com/distributed_lab/ape" From b3943cc0f51e009a67a978a5da89bc10fe791e88 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 18:49:18 +0300 Subject: [PATCH 05/11] add: in progress status to prevent resending pending drops; update: filter by statuses; fix: typos and outdated params --- go.mod | 2 +- go.sum | 2 ++ internal/assets/migrations/001_initial.sql | 2 +- internal/broadcaster/broadcaster.go | 5 +++-- internal/config/airdrop.go | 2 +- internal/config/broadcaster.go | 1 + internal/data/airdrops.go | 11 ++++++----- internal/service/handlers/create_airdrop.go | 3 ++- internal/service/requests/create_airdrop.go | 9 +++++++-- internal/service/router.go | 2 +- 10 files changed, 25 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 4d74043..ed1e687 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/iden3/go-rapidsnark/types v0.0.3 - github.com/rarimo/zkverifier-kit v0.2.2-rc.1 + github.com/rarimo/zkverifier-kit v0.2.2-rc.2 github.com/rubenv/sql-migrate v1.6.1 gitlab.com/distributed_lab/ape v1.7.1 gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c diff --git a/go.sum b/go.sum index 9322ad6..a3c9bf4 100644 --- a/go.sum +++ b/go.sum @@ -2086,6 +2086,8 @@ github.com/rarimo/cosmos-sdk v0.46.7 h1:jU2PiWzc+19SF02cXM0O0puKPeH1C6Q6t2lzJ9s1 github.com/rarimo/cosmos-sdk v0.46.7/go.mod h1:fqKqz39U5IlEFb4nbQ72951myztsDzFKKDtffYJ63nk= github.com/rarimo/zkverifier-kit v0.2.2-rc.1 h1:IHf+Ctl/ilHxK37r6oJmhxNUz/tTWB6iDUSxD2uiEaA= github.com/rarimo/zkverifier-kit v0.2.2-rc.1/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= +github.com/rarimo/zkverifier-kit v0.2.2-rc.2 h1:jjdbYH33yzsb0NHGm9TXkG9yKVBYX3GrX8XIc/Z2rAk= +github.com/rarimo/zkverifier-kit v0.2.2-rc.2/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= diff --git a/internal/assets/migrations/001_initial.sql b/internal/assets/migrations/001_initial.sql index c02324d..cf2491b 100644 --- a/internal/assets/migrations/001_initial.sql +++ b/internal/assets/migrations/001_initial.sql @@ -1,5 +1,5 @@ -- +migrate Up -CREATE TYPE tx_status_enum AS ENUM ('pending', 'completed', 'failed'); +CREATE TYPE tx_status_enum AS ENUM ('pending', 'completed', 'failed', 'in progress'); CREATE TABLE airdrops ( diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index af692bf..b10c630 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -46,7 +46,7 @@ func Run(ctx context.Context, cfg *config.Config) { } func (r *Runner) run(ctx context.Context) error { - airdrops, err := r.q.New().FilterByStatus(data.TxStatusPending).Limit(r.QueryLimit).Select() + airdrops, err := r.q.New().FilterByStatuses(data.TxStatusPending).Limit(r.QueryLimit).Select() if err != nil { return fmt.Errorf("select airdrops: %w", err) } @@ -77,6 +77,8 @@ func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err e }() r.LockNonce() + r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusInProgress) + tx, err := r.genTx(ctx, airdrop) if err != nil { return fmt.Errorf("failed to generate tx: %w", err) @@ -189,7 +191,6 @@ func (r *Runner) getGasCosts( } gasLimit, err = r.RPC.EstimateGas(ctx, ethereum.CallMsg{ - From: r.Address, To: &receiver, GasPrice: gasPrice, Data: txData, diff --git a/internal/config/airdrop.go b/internal/config/airdrop.go index bd3833e..26837ef 100644 --- a/internal/config/airdrop.go +++ b/internal/config/airdrop.go @@ -48,6 +48,6 @@ func (v *airdrop) AridropConfig() AirdropConfig { })) } - return &result + return result }).(AirdropConfig) } diff --git a/internal/config/broadcaster.go b/internal/config/broadcaster.go index 4c88321..ed5f794 100644 --- a/internal/config/broadcaster.go +++ b/internal/config/broadcaster.go @@ -78,6 +78,7 @@ func (b *broadcasterer) Broadcaster() Broadcaster { } return Broadcaster{ + RPC: cfg.RPC, PrivateKey: cfg.SenderPrivateKey, Address: address, ChainID: cfg.ChainID, diff --git a/internal/data/airdrops.go b/internal/data/airdrops.go index b3c7b9e..107f85b 100644 --- a/internal/data/airdrops.go +++ b/internal/data/airdrops.go @@ -11,9 +11,10 @@ import ( ) const ( - TxStatusPending = "pending" - TxStatusCompleted = "completed" - TxStatusFailed = "failed" + TxStatusPending = "pending" + TxStatusInProgress = "in progress" + TxStatusCompleted = "completed" + TxStatusFailed = "failed" ) const airdropsTable = "airdrops" @@ -120,7 +121,7 @@ func (q *AirdropsQ) FilterByNullifier(nullifier string) *AirdropsQ { return q } -func (q *AirdropsQ) FilterByStatus(status string) *AirdropsQ { - q.selector = q.selector.Where(squirrel.Eq{"status": status}) +func (q *AirdropsQ) FilterByStatuses(statuses ...string) *AirdropsQ { + q.selector = q.selector.Where(squirrel.Eq{"status": statuses}) return q } diff --git a/internal/service/handlers/create_airdrop.go b/internal/service/handlers/create_airdrop.go index 54e7611..311fddc 100644 --- a/internal/service/handlers/create_airdrop.go +++ b/internal/service/handlers/create_airdrop.go @@ -26,7 +26,7 @@ func CreateAirdrop(w http.ResponseWriter, r *http.Request) { airdrop, err := AirdropsQ(r). FilterByNullifier(nullifier). - FilterByStatus(data.TxStatusCompleted). + FilterByStatuses(data.TxStatusCompleted, data.TxStatusPending, data.TxStatusInProgress). Get() if err != nil { Log(r).WithError(err).Error("Failed to get airdrop by nullifier") @@ -63,5 +63,6 @@ func CreateAirdrop(w http.ResponseWriter, r *http.Request) { return } + w.WriteHeader(http.StatusCreated) ape.Render(w, toAirdropResponse(*airdrop)) } diff --git a/internal/service/requests/create_airdrop.go b/internal/service/requests/create_airdrop.go index fd87066..06d08d9 100644 --- a/internal/service/requests/create_airdrop.go +++ b/internal/service/requests/create_airdrop.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "regexp" val "github.com/go-ozzo/ozzo-validation/v4" "github.com/rarimo/evm-airdrop-svc/resources" @@ -16,8 +17,12 @@ func NewCreateAirdrop(r *http.Request) (req resources.CreateAirdropRequest, err attr := req.Data.Attributes return req, val.Errors{ - "data/type": val.Validate(req.Data.Type, val.Required, val.In(resources.CREATE_AIRDROP)), - "data/attributes/address": val.Validate(attr.Address, val.Required, isRarimoAddr), + "data/type": val.Validate(req.Data.Type, val.Required, val.In(resources.CREATE_AIRDROP)), + "data/attributes/address": val.Validate( + attr.Address, + val.Required, + val.Match(regexp.MustCompile("^0x[0-9a-fA-F]{40}$")), + ), }.Filter() } diff --git a/internal/service/router.go b/internal/service/router.go index a6a1923..ca0e688 100644 --- a/internal/service/router.go +++ b/internal/service/router.go @@ -20,7 +20,7 @@ func Run(ctx context.Context, cfg *config.Config) { ape.CtxMiddleware( handlers.CtxLog(cfg.Log()), handlers.CtxVerifier(cfg.Verifier().ZkVerifier), - handlers.CtxAirdropAmount(cfg.Broadcaster().AirdropCoins.String()), + handlers.CtxAirdropAmount(cfg.AridropConfig().Amount.String()), handlers.CtxAirdropParams(cfg.Verifier().Params), ), handlers.DBCloneMiddleware(cfg.DB()), From 069c20e6e1a6860de790d42339ab6562931113f5 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 19:13:21 +0300 Subject: [PATCH 06/11] add: channel for errors during tx waiting instead of panic --- internal/broadcaster/broadcaster.go | 36 +++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index b10c630..9034d5f 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -29,6 +29,14 @@ type Runner struct { q *data.AirdropsQ config.Broadcaster config.AirdropConfig + + errChan chan *channelData +} + +type channelData struct { + err error + tx *types.Transaction + airdrop data.Airdrop } func Run(ctx context.Context, cfg *config.Config) { @@ -40,12 +48,16 @@ func Run(ctx context.Context, cfg *config.Config) { q: data.NewAirdropsQ(cfg.DB().Clone()), Broadcaster: cfg.Broadcaster(), AirdropConfig: cfg.AridropConfig(), + + errChan: make(chan *channelData), } running.WithBackOff(ctx, r.log, "builtin-broadcaster", r.run, 5*time.Second, 5*time.Second, 5*time.Second) } func (r *Runner) run(ctx context.Context) error { + go r.waitForTxErrors(ctx) + airdrops, err := r.q.New().FilterByStatuses(data.TxStatusPending).Limit(r.QueryLimit).Select() if err != nil { return fmt.Errorf("select airdrops: %w", err) @@ -53,6 +65,7 @@ func (r *Runner) run(ctx context.Context) error { if len(airdrops) == 0 { return nil } + r.log.Debugf("Got %d pending airdrops, broadcasting now", len(airdrops)) for _, drop := range airdrops { @@ -66,6 +79,16 @@ func (r *Runner) run(ctx context.Context) error { return nil } +func (r *Runner) waitForTxErrors(ctx context.Context) { + for { + select { + case errData := <-r.errChan: + r.updateAirdropStatus(ctx, errData.airdrop.ID, errData.tx.Hash().String(), data.TxStatusFailed) + return + } + } +} + func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err error) { var txHash string @@ -123,6 +146,7 @@ func (r *Runner) broadcastTx(ctx context.Context, tx *types.Transaction, airdrop return fmt.Errorf("failed to send tx: %w", err) } + r.IncrementNonce() r.waitForTransactionMined(ctx, tx, airdrop) return nil @@ -134,12 +158,16 @@ func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types go func() { log.Debugf("waiting to mine") - _, err := bind.WaitMined(ctx, r.RPC, transaction) - if err != nil { - panic(errors.Wrap(err, "failed to mine transaction")) + if _, err := bind.WaitMined(ctx, r.RPC, transaction); err != nil { + log.WithError(err).Error("Failed to wait for mined tx") + + r.errChan <- &channelData{ + err: err, + tx: transaction, + airdrop: airdrop, + } } - r.IncrementNonce() r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted) log.Debugf("was mined") From fe02b9c1012bd05a066221f54aaa868a17e6f1e8 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 19:18:15 +0300 Subject: [PATCH 07/11] update: use for range instead endless for loop with select for channel --- internal/broadcaster/broadcaster.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index 9034d5f..48501af 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -80,12 +80,8 @@ func (r *Runner) run(ctx context.Context) error { } func (r *Runner) waitForTxErrors(ctx context.Context) { - for { - select { - case errData := <-r.errChan: - r.updateAirdropStatus(ctx, errData.airdrop.ID, errData.tx.Hash().String(), data.TxStatusFailed) - return - } + for errData := range r.errChan { + r.updateAirdropStatus(ctx, errData.airdrop.ID, errData.tx.Hash().String(), data.TxStatusFailed) } } From b0815716069ee1d4aa5a46d763b5b75f816f95bd Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Fri, 24 May 2024 22:08:11 +0300 Subject: [PATCH 08/11] remove: redundant channel for failed tx, change status directly after failing --- internal/broadcaster/broadcaster.go | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index 48501af..039c670 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -29,14 +29,6 @@ type Runner struct { q *data.AirdropsQ config.Broadcaster config.AirdropConfig - - errChan chan *channelData -} - -type channelData struct { - err error - tx *types.Transaction - airdrop data.Airdrop } func Run(ctx context.Context, cfg *config.Config) { @@ -48,16 +40,12 @@ func Run(ctx context.Context, cfg *config.Config) { q: data.NewAirdropsQ(cfg.DB().Clone()), Broadcaster: cfg.Broadcaster(), AirdropConfig: cfg.AridropConfig(), - - errChan: make(chan *channelData), } running.WithBackOff(ctx, r.log, "builtin-broadcaster", r.run, 5*time.Second, 5*time.Second, 5*time.Second) } func (r *Runner) run(ctx context.Context) error { - go r.waitForTxErrors(ctx) - airdrops, err := r.q.New().FilterByStatuses(data.TxStatusPending).Limit(r.QueryLimit).Select() if err != nil { return fmt.Errorf("select airdrops: %w", err) @@ -79,12 +67,6 @@ func (r *Runner) run(ctx context.Context) error { return nil } -func (r *Runner) waitForTxErrors(ctx context.Context) { - for errData := range r.errChan { - r.updateAirdropStatus(ctx, errData.airdrop.ID, errData.tx.Hash().String(), data.TxStatusFailed) - } -} - func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err error) { var txHash string @@ -155,13 +137,8 @@ func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types log.Debugf("waiting to mine") if _, err := bind.WaitMined(ctx, r.RPC, transaction); err != nil { - log.WithError(err).Error("Failed to wait for mined tx") - - r.errChan <- &channelData{ - err: err, - tx: transaction, - airdrop: airdrop, - } + log.WithError(err).WithField("transaction", transaction).Error("failed to wait for mined tx") + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusFailed) } r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted) From da55119a1690dae653c8352b91bfcef048600ada Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Mon, 3 Jun 2024 12:27:20 +0300 Subject: [PATCH 09/11] add: error for failed airdrop transaction --- internal/assets/migrations/001_initial.sql | 1 + internal/broadcaster/broadcaster.go | 50 +++++++++++++++++++--- internal/data/airdrops.go | 1 + 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/internal/assets/migrations/001_initial.sql b/internal/assets/migrations/001_initial.sql index cf2491b..1db0684 100644 --- a/internal/assets/migrations/001_initial.sql +++ b/internal/assets/migrations/001_initial.sql @@ -7,6 +7,7 @@ CREATE TABLE airdrops nullifier text NOT NULL, address text NOT NULL, tx_hash text, + error text, amount text NOT NULL, status tx_status_enum NOT NULL, created_at timestamp without time zone NOT NULL DEFAULT NOW(), diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index 039c670..7b1ea26 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -73,12 +73,12 @@ func (r *Runner) handlePending(ctx context.Context, airdrop data.Airdrop) (err e defer func() { r.UnlockNonce() if err != nil { - r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusFailed) + r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusFailed, err) } }() r.LockNonce() - r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusInProgress) + r.updateAirdropStatus(ctx, airdrop.ID, txHash, data.TxStatusInProgress, nil) tx, err := r.genTx(ctx, airdrop) if err != nil { @@ -136,32 +136,68 @@ func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types go func() { log.Debugf("waiting to mine") - if _, err := bind.WaitMined(ctx, r.RPC, transaction); err != nil { + receipt, err := bind.WaitMined(ctx, r.RPC, transaction) + if err != nil { log.WithError(err).WithField("transaction", transaction).Error("failed to wait for mined tx") - r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusFailed) + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusFailed, err) + } + + if receipt.Status != types.ReceiptStatusSuccessful { + txErr, err := r.getTxError(ctx, transaction, r.Address) + if err != nil { + log.WithError(err).WithField("transaction", transaction).Error("failed to get tx error") + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusFailed, err) + } + + log.WithError(err).WithField("transaction", transaction).Error("transaction was mined with failed status") + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusFailed, txErr) } - r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted) + r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted, nil) - log.Debugf("was mined") + log.Debugf("was mined sucessfully") }() } +func (r *Runner) getTxError(ctx context.Context, tx *types.Transaction, txSender common.Address) (error, error) { + msg := ethereum.CallMsg{ + From: txSender, + To: tx.To(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + Value: tx.Value(), + Data: tx.Data(), + } + + res, err := r.RPC.CallContract(ctx, msg, nil) + if err != nil { + return nil, errors.Wrap(err, "failed to make call") + } + + return errors.New(string(res)), nil +} + // If we don't update tx status from pending, having the successful funds // transfer, it will be possible to double-spend. With this solution the // double-spend may still occur, if the service is restarted before the // successful update. There is a better solution with file creation on context // cancellation and parsing it on start. -func (r *Runner) updateAirdropStatus(ctx context.Context, id, txHash, status string) { +func (r *Runner) updateAirdropStatus(ctx context.Context, id, txHash, status string, txErr error) { running.UntilSuccess(ctx, r.log, "tx-status-updater", func(_ context.Context) (bool, error) { var ptr *string if txHash != "" { ptr = &txHash } + var errMsg *string + if txErr != nil { + msg := txErr.Error() + errMsg = &msg + } err := r.q.New().Update(id, map[string]any{ "status": status, "tx_hash": ptr, + "error": errMsg, }) return err == nil, err diff --git a/internal/data/airdrops.go b/internal/data/airdrops.go index 107f85b..3c1789b 100644 --- a/internal/data/airdrops.go +++ b/internal/data/airdrops.go @@ -24,6 +24,7 @@ type Airdrop struct { Nullifier string `db:"nullifier"` Address string `db:"address"` TxHash *string `db:"tx_hash"` + Error *string `db:"error"` Amount string `db:"amount"` Status string `db:"status"` CreatedAt time.Time `db:"created_at"` From 2d77f8599f2acc0420e9300f811452b661a33d80 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Mon, 3 Jun 2024 12:33:35 +0300 Subject: [PATCH 10/11] fix: typo in log --- internal/broadcaster/broadcaster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/broadcaster/broadcaster.go b/internal/broadcaster/broadcaster.go index 7b1ea26..c2a8795 100644 --- a/internal/broadcaster/broadcaster.go +++ b/internal/broadcaster/broadcaster.go @@ -155,7 +155,7 @@ func (r *Runner) waitForTransactionMined(ctx context.Context, transaction *types r.updateAirdropStatus(ctx, airdrop.ID, transaction.Hash().String(), data.TxStatusCompleted, nil) - log.Debugf("was mined sucessfully") + log.Debugf("was mined successfully") }() } From 100937d12a974da5108e49d3aefe3a077d7d5ac3 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Wed, 5 Jun 2024 19:06:21 +0300 Subject: [PATCH 11/11] update: zkverifier version, verifying proof by decoded eth addr --- go.mod | 2 +- go.sum | 2 ++ internal/service/handlers/create_airdrop.go | 13 ++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index ed1e687..221c57a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-chi/chi v4.1.2+incompatible github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/iden3/go-rapidsnark/types v0.0.3 - github.com/rarimo/zkverifier-kit v0.2.2-rc.2 + github.com/rarimo/zkverifier-kit v0.2.2-rc.3 github.com/rubenv/sql-migrate v1.6.1 gitlab.com/distributed_lab/ape v1.7.1 gitlab.com/distributed_lab/dig v0.0.0-20230207152643-c44f80a4294c diff --git a/go.sum b/go.sum index a3c9bf4..faaea24 100644 --- a/go.sum +++ b/go.sum @@ -2088,6 +2088,8 @@ github.com/rarimo/zkverifier-kit v0.2.2-rc.1 h1:IHf+Ctl/ilHxK37r6oJmhxNUz/tTWB6i github.com/rarimo/zkverifier-kit v0.2.2-rc.1/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rarimo/zkverifier-kit v0.2.2-rc.2 h1:jjdbYH33yzsb0NHGm9TXkG9yKVBYX3GrX8XIc/Z2rAk= github.com/rarimo/zkverifier-kit v0.2.2-rc.2/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= +github.com/rarimo/zkverifier-kit v0.2.2-rc.3 h1:QarWLZxDpng8FeNZ6LxO+0RBEB88N9fqnCFpC0MgQBE= +github.com/rarimo/zkverifier-kit v0.2.2-rc.3/go.mod h1:3YDg5dTkDRr4IdfaDHGYetopd6gS/2SuwSeseYTWwNw= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= diff --git a/internal/service/handlers/create_airdrop.go b/internal/service/handlers/create_airdrop.go index 311fddc..d86893d 100644 --- a/internal/service/handlers/create_airdrop.go +++ b/internal/service/handlers/create_airdrop.go @@ -4,12 +4,14 @@ import ( "errors" "net/http" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/rarimo/evm-airdrop-svc/internal/data" "github.com/rarimo/evm-airdrop-svc/internal/service/requests" zk "github.com/rarimo/zkverifier-kit" "github.com/rarimo/zkverifier-kit/identity" "gitlab.com/distributed_lab/ape" "gitlab.com/distributed_lab/ape/problems" + "gitlab.com/distributed_lab/logan/v3" ) // Full list of the OpenSSL signature algorithms and hash-functions is provided here: @@ -38,7 +40,16 @@ func CreateAirdrop(w http.ResponseWriter, r *http.Request) { return } - err = Verifier(r).VerifyProof(req.Data.Attributes.ZkProof, zk.WithEthereumAddress(req.Data.Attributes.Address)) + decodedAddress, err := hexutil.Decode(req.Data.Attributes.Address) + if err != nil { + Log(r).WithError(err).WithFields(logan.F{ + "address": req.Data.Attributes.Address, + }).Error("Failed to decode hex ethereum address") + ape.RenderErr(w, problems.InternalError()) + return + } + + err = Verifier(r).VerifyProof(req.Data.Attributes.ZkProof, zk.WithEventData(decodedAddress)) if err != nil { if errors.Is(err, identity.ErrContractCall) { Log(r).WithError(err).Error("Failed to verify proof")