Match transfer to every account that is being watched

This commit is contained in:
dmitry 2019-08-27 12:16:09 +03:00 committed by Dmitry Shulyak
parent 0165b028c9
commit 7454586889
2 changed files with 63 additions and 49 deletions

View File

@ -101,17 +101,12 @@ 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) {
for _, tx := range blk.Transactions() {
var address *common.Address
for _, address := range accounts {
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 {
if from == address || (tx.To() != nil && *tx.To() == address) {
receipt, err := d.client.TransactionReceipt(ctx, tx.Hash())
if err != nil {
return nil, err
@ -123,7 +118,7 @@ func (d *ETHTransferDownloader) getTransfersInBlock(ctx context.Context, blk *ty
rst = append(rst, Transfer{
Type: ethTransfer,
ID: tx.Hash(),
Address: *address,
Address: address,
BlockNumber: blk.Number(),
BlockHash: blk.Hash(),
Timestamp: blk.Time(),
@ -133,6 +128,7 @@ func (d *ETHTransferDownloader) getTransfersInBlock(ctx context.Context, blk *ty
}
}
}
// TODO(dshulyak) test that balance difference was covered by transactions
return rst, nil
}
@ -311,15 +307,6 @@ func (d *ERC20TransfersDownloader) GetTransfersInRange(parent context.Context, f
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 {
signature := crypto.Keccak256Hash([]byte(erc20TransferEventSignature))
for _, l := range logs {

View File

@ -25,7 +25,7 @@ type ETHTransferSuite struct {
suite.Suite
ethclient *ethclient.Client
identity *ecdsa.PrivateKey
identity, secondary *ecdsa.PrivateKey
faucet *ecdsa.PrivateKey
signer types.Signer
@ -38,6 +38,8 @@ func (s *ETHTransferSuite) SetupTest() {
s.Require().NoError(err)
s.faucet, err = crypto.GenerateKey()
s.Require().NoError(err)
s.secondary, err = crypto.GenerateKey()
s.Require().NoError(err)
node, err := miner.NewDevNode(crypto.PubkeyToAddress(s.faucet.PublicKey))
s.Require().NoError(err)
@ -50,20 +52,31 @@ func (s *ETHTransferSuite) SetupTest() {
s.downloader = &ETHTransferDownloader{
signer: s.signer,
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() {
ctx := context.TODO()
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.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)
s.signAndMineTx(tx, nil)
header, err := s.ethclient.HeaderByNumber(ctx, nil)
s.Require().NoError(err)
@ -119,6 +132,20 @@ func (s *ETHTransferSuite) TestBalanceUpdatedOnOutbound() {
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) {
suite.Run(t, new(ERC20TransferSuite))
}