60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
|
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 {
|
||
|
Wait() error
|
||
|
}
|
||
|
|
||
|
type transaction struct {
|
||
|
*types.Transaction
|
||
|
ctx context.Context
|
||
|
client Client
|
||
|
pendingCheckPeriod time.Duration
|
||
|
}
|
||
|
|
||
|
func NewTransaction(ctx context.Context, client Client, pendingCheckPeriod time.Duration, tx *types.Transaction) Transaction {
|
||
|
return &transaction{
|
||
|
Transaction: tx,
|
||
|
ctx: ctx,
|
||
|
client: client,
|
||
|
pendingCheckPeriod: pendingCheckPeriod,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (t *transaction) Wait() error {
|
||
|
hash := t.Hash()
|
||
|
notfoundmax := 10
|
||
|
notfoundcount := 0
|
||
|
ticker := time.NewTicker(t.pendingCheckPeriod)
|
||
|
for {
|
||
|
select {
|
||
|
case <-t.ctx.Done():
|
||
|
return errors.New("context canceled")
|
||
|
case <-ticker.C:
|
||
|
_, pending, err := t.client.TransactionByHash(t.ctx, hash)
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|