Match transfer to every account that is being watched
This commit is contained in:
parent
0165b028c9
commit
7454586889
|
@ -101,36 +101,32 @@ func (d *ETHTransferDownloader) GetTransfersByNumber(ctx context.Context, number
|
||||||
|
|
||||||
func (d *ETHTransferDownloader) getTransfersInBlock(ctx context.Context, blk *types.Block, accounts []common.Address) (rst []Transfer, err error) {
|
func (d *ETHTransferDownloader) getTransfersInBlock(ctx context.Context, blk *types.Block, accounts []common.Address) (rst []Transfer, err error) {
|
||||||
for _, tx := range blk.Transactions() {
|
for _, tx := range blk.Transactions() {
|
||||||
var address *common.Address
|
for _, address := range accounts {
|
||||||
from, err := types.Sender(d.signer, tx)
|
from, err := types.Sender(d.signer, tx)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if any(from, accounts) {
|
|
||||||
address = &from
|
|
||||||
} else if tx.To() != nil && any(*tx.To(), accounts) {
|
|
||||||
address = tx.To()
|
|
||||||
}
|
|
||||||
if address != nil {
|
|
||||||
receipt, err := d.client.TransactionReceipt(ctx, tx.Hash())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if isTokenTransfer(receipt.Logs) {
|
if from == address || (tx.To() != nil && *tx.To() == address) {
|
||||||
log.Debug("eth downloader found token transfer", "hash", tx.Hash())
|
receipt, err := d.client.TransactionReceipt(ctx, tx.Hash())
|
||||||
continue
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
rst = append(rst, Transfer{
|
}
|
||||||
Type: ethTransfer,
|
if isTokenTransfer(receipt.Logs) {
|
||||||
ID: tx.Hash(),
|
log.Debug("eth downloader found token transfer", "hash", tx.Hash())
|
||||||
Address: *address,
|
continue
|
||||||
BlockNumber: blk.Number(),
|
}
|
||||||
BlockHash: blk.Hash(),
|
rst = append(rst, Transfer{
|
||||||
Timestamp: blk.Time(),
|
Type: ethTransfer,
|
||||||
Transaction: tx,
|
ID: tx.Hash(),
|
||||||
From: from,
|
Address: address,
|
||||||
Receipt: receipt})
|
BlockNumber: blk.Number(),
|
||||||
|
BlockHash: blk.Hash(),
|
||||||
|
Timestamp: blk.Time(),
|
||||||
|
Transaction: tx,
|
||||||
|
From: from,
|
||||||
|
Receipt: receipt})
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO(dshulyak) test that balance difference was covered by transactions
|
// TODO(dshulyak) test that balance difference was covered by transactions
|
||||||
|
@ -311,15 +307,6 @@ func (d *ERC20TransfersDownloader) GetTransfersInRange(parent context.Context, f
|
||||||
return transfers, nil
|
return transfers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func any(address common.Address, compare []common.Address) bool {
|
|
||||||
for _, c := range compare {
|
|
||||||
if c == address {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isTokenTransfer(logs []*types.Log) bool {
|
func isTokenTransfer(logs []*types.Log) bool {
|
||||||
signature := crypto.Keccak256Hash([]byte(erc20TransferEventSignature))
|
signature := crypto.Keccak256Hash([]byte(erc20TransferEventSignature))
|
||||||
for _, l := range logs {
|
for _, l := range logs {
|
||||||
|
|
|
@ -24,10 +24,10 @@ func TestETHTransfers(t *testing.T) {
|
||||||
type ETHTransferSuite struct {
|
type ETHTransferSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
|
|
||||||
ethclient *ethclient.Client
|
ethclient *ethclient.Client
|
||||||
identity *ecdsa.PrivateKey
|
identity, secondary *ecdsa.PrivateKey
|
||||||
faucet *ecdsa.PrivateKey
|
faucet *ecdsa.PrivateKey
|
||||||
signer types.Signer
|
signer types.Signer
|
||||||
|
|
||||||
downloader *ETHTransferDownloader
|
downloader *ETHTransferDownloader
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ func (s *ETHTransferSuite) SetupTest() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.faucet, err = crypto.GenerateKey()
|
s.faucet, err = crypto.GenerateKey()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
s.secondary, err = crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
node, err := miner.NewDevNode(crypto.PubkeyToAddress(s.faucet.PublicKey))
|
node, err := miner.NewDevNode(crypto.PubkeyToAddress(s.faucet.PublicKey))
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -48,22 +50,33 @@ func (s *ETHTransferSuite) SetupTest() {
|
||||||
s.ethclient = ethclient.NewClient(client)
|
s.ethclient = ethclient.NewClient(client)
|
||||||
s.signer = types.NewEIP155Signer(big.NewInt(1337))
|
s.signer = types.NewEIP155Signer(big.NewInt(1337))
|
||||||
s.downloader = ÐTransferDownloader{
|
s.downloader = ÐTransferDownloader{
|
||||||
signer: s.signer,
|
signer: s.signer,
|
||||||
client: s.ethclient,
|
client: s.ethclient,
|
||||||
accounts: []common.Address{crypto.PubkeyToAddress(s.identity.PublicKey)},
|
accounts: []common.Address{
|
||||||
|
crypto.PubkeyToAddress(s.identity.PublicKey),
|
||||||
|
crypto.PubkeyToAddress(s.secondary.PublicKey)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// signAndMineTx signs transaction with provided key and waits for it to be mined.
|
||||||
|
// uses configured faucet key if pkey is nil.
|
||||||
|
func (s *ETHTransferSuite) signAndMineTx(tx *types.Transaction, pkey *ecdsa.PrivateKey) {
|
||||||
|
if pkey == nil {
|
||||||
|
pkey = s.faucet
|
||||||
|
}
|
||||||
|
tx, err := types.SignTx(tx, s.signer, pkey)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.ethclient.SendTransaction(context.Background(), tx))
|
||||||
|
timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
_, err = bind.WaitMined(timeout, s.ethclient, tx)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *ETHTransferSuite) TestNoBalance() {
|
func (s *ETHTransferSuite) TestNoBalance() {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1e18), 1e6, big.NewInt(10), nil)
|
tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1e18), 1e6, big.NewInt(10), nil)
|
||||||
tx, err := types.SignTx(tx, s.signer, s.faucet)
|
s.signAndMineTx(tx, nil)
|
||||||
s.Require().NoError(err)
|
|
||||||
s.Require().NoError(s.ethclient.SendTransaction(ctx, tx))
|
|
||||||
timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
_, err = bind.WaitMined(timeout, s.ethclient, tx)
|
|
||||||
s.Require().NoError(err)
|
|
||||||
|
|
||||||
header, err := s.ethclient.HeaderByNumber(ctx, nil)
|
header, err := s.ethclient.HeaderByNumber(ctx, nil)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -119,6 +132,20 @@ func (s *ETHTransferSuite) TestBalanceUpdatedOnOutbound() {
|
||||||
s.Require().Len(transfers, 1)
|
s.Require().Len(transfers, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ETHTransferSuite) TestMultipleReferences() {
|
||||||
|
tx := types.NewTransaction(0, crypto.PubkeyToAddress(s.identity.PublicKey), big.NewInt(1e18), 1e6, big.NewInt(10), nil)
|
||||||
|
s.signAndMineTx(tx, nil)
|
||||||
|
tx = types.NewTransaction(0, crypto.PubkeyToAddress(s.secondary.PublicKey), big.NewInt(1e17), 1e6, big.NewInt(10), nil)
|
||||||
|
s.signAndMineTx(tx, s.identity)
|
||||||
|
|
||||||
|
header, err := s.ethclient.HeaderByNumber(context.Background(), nil)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Equal(big.NewInt(2), header.Number)
|
||||||
|
transfers, err := s.downloader.GetTransfers(context.Background(), toDBHeader(header))
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(transfers, 2)
|
||||||
|
}
|
||||||
|
|
||||||
func TestERC20Transfers(t *testing.T) {
|
func TestERC20Transfers(t *testing.T) {
|
||||||
suite.Run(t, new(ERC20TransferSuite))
|
suite.Run(t, new(ERC20TransferSuite))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue