@@ -2,12 +2,14 @@ package txserver
2
2
3
3
import (
4
4
"context"
5
+ "encoding/hex"
5
6
"encoding/json"
6
7
"errors"
7
8
"fmt"
8
9
"math/big"
9
10
"os"
10
11
"strings"
12
+ "time"
11
13
12
14
"github.com/cosmos/cosmos-sdk/client"
13
15
"github.com/cosmos/cosmos-sdk/client/flags"
@@ -33,6 +35,7 @@ import (
33
35
etherminttypes "github.com/evmos/ethermint/types"
34
36
evmtypes "github.com/evmos/ethermint/x/evm/types"
35
37
rpchttp "github.com/tendermint/tendermint/rpc/client/http"
38
+ coretypes "github.com/tendermint/tendermint/rpc/core/types"
36
39
"github.com/zeta-chain/zetacore/cmd/zetacored/config"
37
40
"github.com/zeta-chain/zetacore/pkg/chains"
38
41
"github.com/zeta-chain/zetacore/pkg/coin"
@@ -48,11 +51,12 @@ const EmissionsPoolAddress = "zeta1w43fn2ze2wyhu5hfmegr6vp52c3dgn0srdgymy"
48
51
49
52
// ZetaTxServer is a ZetaChain tx server for E2E test
50
53
type ZetaTxServer struct {
51
- clientCtx client.Context
52
- txFactory tx.Factory
53
- name []string
54
- mnemonic []string
55
- address []string
54
+ clientCtx client.Context
55
+ txFactory tx.Factory
56
+ name []string
57
+ mnemonic []string
58
+ address []string
59
+ blockTimeout time.Duration
56
60
}
57
61
58
62
// NewZetaTxServer returns a new TxServer with provided account
@@ -102,11 +106,12 @@ func NewZetaTxServer(rpcAddr string, names []string, mnemonics []string, chainID
102
106
txf := newFactory (clientCtx )
103
107
104
108
return ZetaTxServer {
105
- clientCtx : clientCtx ,
106
- txFactory : txf ,
107
- name : names ,
108
- mnemonic : mnemonics ,
109
- address : addresses ,
109
+ clientCtx : clientCtx ,
110
+ txFactory : txf ,
111
+ name : names ,
112
+ mnemonic : mnemonics ,
113
+ address : addresses ,
114
+ blockTimeout : 1 * time .Minute ,
110
115
}, nil
111
116
}
112
117
@@ -157,6 +162,7 @@ func (zts ZetaTxServer) GetAccountMnemonic(index int) string {
157
162
}
158
163
159
164
// BroadcastTx broadcasts a tx to ZetaChain with the provided msg from the account
165
+ // and waiting for blockTime for tx to be included in the block
160
166
func (zts ZetaTxServer ) BroadcastTx (account string , msg sdktypes.Msg ) (* sdktypes.TxResponse , error ) {
161
167
// Find number and sequence and set it
162
168
acc , err := zts .clientCtx .Keyring .Key (account )
@@ -188,8 +194,61 @@ func (zts ZetaTxServer) BroadcastTx(account string, msg sdktypes.Msg) (*sdktypes
188
194
return nil , err
189
195
}
190
196
191
- // Broadcast tx
192
- return zts .clientCtx .BroadcastTx (txBytes )
197
+ return broadcastWithBlockTimeout (zts , txBytes )
198
+ }
199
+
200
+ func broadcastWithBlockTimeout (zts ZetaTxServer , txBytes []byte ) (* sdktypes.TxResponse , error ) {
201
+ res , err := zts .clientCtx .BroadcastTx (txBytes )
202
+ if err != nil {
203
+ if res == nil {
204
+ return nil , err
205
+ }
206
+ return & sdktypes.TxResponse {
207
+ Code : res .Code ,
208
+ Codespace : res .Codespace ,
209
+ TxHash : res .TxHash ,
210
+ }, err
211
+ }
212
+
213
+ exitAfter := time .After (zts .blockTimeout )
214
+ hash , err := hex .DecodeString (res .TxHash )
215
+ if err != nil {
216
+ return nil , err
217
+ }
218
+ for {
219
+ select {
220
+ case <- exitAfter :
221
+ return nil , fmt .Errorf ("timed out after waiting for tx to get included in the block: %d" , zts .blockTimeout )
222
+ case <- time .After (time .Millisecond * 100 ):
223
+ resTx , err := zts .clientCtx .Client .Tx (context .TODO (), hash , false )
224
+ if err == nil {
225
+ txRes , err := mkTxResult (zts .clientCtx , resTx )
226
+ if err == nil {
227
+ return txRes , nil
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ func mkTxResult (clientCtx client.Context , resTx * coretypes.ResultTx ) (* sdktypes.TxResponse , error ) {
235
+ txb , err := clientCtx .TxConfig .TxDecoder ()(resTx .Tx )
236
+ if err != nil {
237
+ return nil , err
238
+ }
239
+ p , ok := txb .(intoAny )
240
+ if ! ok {
241
+ return nil , fmt .Errorf ("expecting a type implementing intoAny, got: %T" , txb )
242
+ }
243
+ resBlock , err := clientCtx .Client .Block (context .TODO (), & resTx .Height )
244
+ if err != nil {
245
+ return nil , err
246
+ }
247
+ return sdktypes .NewResponseResultTx (resTx , p .AsAny (), resBlock .Block .Time .Format (time .RFC3339 )), nil
248
+ }
249
+
250
+ type intoAny interface {
251
+ AsAny () * codectypes.Any
193
252
}
194
253
195
254
// DeploySystemContractsAndZRC20 deploys the system contracts and ZRC20 contracts
@@ -373,7 +432,7 @@ func newContext(
373
432
WithLegacyAmino (codec .NewLegacyAmino ()).
374
433
WithInput (os .Stdin ).
375
434
WithOutput (os .Stdout ).
376
- WithBroadcastMode (flags .BroadcastBlock ).
435
+ WithBroadcastMode (flags .BroadcastSync ).
377
436
WithClient (rpc ).
378
437
WithSkipConfirmation (true ).
379
438
WithFromName ("creator" ).
0 commit comments