2021-11-08 18:20:31 +00:00
|
|
|
package evm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Transaction interface {
|
2021-11-08 18:35:39 +00:00
|
|
|
Wait(ctx context.Context) error
|
2021-11-08 18:20:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type transaction struct {
|
|
|
|
*types.Transaction
|
|
|
|
client Client
|
|
|
|
pendingCheckPeriod time.Duration
|
|
|
|
}
|
|
|
|
|
2021-11-08 18:35:39 +00:00
|
|
|
func NewTransaction(client Client, pendingCheckPeriod time.Duration, tx *types.Transaction) Transaction {
|
2021-11-08 18:20:31 +00:00
|
|
|
return &transaction{
|
|
|
|
Transaction: tx,
|
|
|
|
client: client,
|
|
|
|
pendingCheckPeriod: pendingCheckPeriod,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-08 18:35:39 +00:00
|
|
|
func (t *transaction) Wait(ctx context.Context) error {
|
2021-11-08 18:20:31 +00:00
|
|
|
hash := t.Hash()
|
|
|
|
notfoundmax := 10
|
|
|
|
notfoundcount := 0
|
|
|
|
ticker := time.NewTicker(t.pendingCheckPeriod)
|
|
|
|
for {
|
|
|
|
select {
|
2021-11-08 18:35:39 +00:00
|
|
|
case <-ctx.Done():
|
2021-11-08 18:20:31 +00:00
|
|
|
return errors.New("context canceled")
|
|
|
|
case <-ticker.C:
|
2021-11-08 18:35:39 +00:00
|
|
|
_, pending, err := t.client.TransactionByHash(ctx, hash)
|
2021-11-08 18:20:31 +00:00
|
|
|
if err != nil {
|
|
|
|
if err == ethereum.NotFound && notfoundcount < notfoundmax {
|
|
|
|
notfoundcount++
|
|
|
|
log.Debug().Msgf("%d/%d - tx not found %s", notfoundcount, notfoundmax, hash)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return errors.Wrapf(err, "retrieving transaction state for hash %s", hash)
|
|
|
|
}
|
|
|
|
if pending {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
log.Debug().Msg("//TX// tx done")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|