Handle transactions with missing ethereum To address

This commit is contained in:
Martin Boehm 2018-03-28 13:23:43 +02:00
parent bfb22c4f20
commit 39a31d4544
4 changed files with 87 additions and 5 deletions

View File

@ -2,9 +2,8 @@ package eth
import (
"blockbook/bchain"
"encoding/hex"
"errors"
ethcommon "github.com/ethereum/go-ethereum/common"
)
type EthParser struct {
@ -18,8 +17,21 @@ func (p *EthParser) GetAddrIDFromVout(output *bchain.Vout) ([]byte, error) {
}
func (p *EthParser) GetAddrIDFromAddress(address string) ([]byte, error) {
a := ethcommon.HexToAddress(address)
return a.Bytes(), nil
// github.com/ethereum/go-ethereum/common.HexToAddress does not handle address errors, using own decoding
if len(address) > 1 {
if address[0:2] == "0x" || address[0:2] == "0X" {
address = address[2:]
}
} else {
if len(address) == 0 {
return nil, bchain.ErrAddressMissing
}
return nil, errors.New("Invalid address")
}
if len(address)&1 == 1 {
address = "0" + address
}
return hex.DecodeString(address)
}
func (p *EthParser) AddressToOutputScript(address string) ([]byte, error) {

View File

@ -0,0 +1,61 @@
package eth
import (
"encoding/hex"
"reflect"
"testing"
)
func TestEthParser_GetAddrIDFromAddress(t *testing.T) {
type args struct {
address string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "with 0x prefix",
args: args{address: "0x81b7e08f65bdf5648606c89998a9cc8164397647"},
want: "81b7e08f65bdf5648606c89998a9cc8164397647",
},
{
name: "without 0x prefix",
args: args{address: "47526228d673e9f079630d6cdaff5a2ed13e0e60"},
want: "47526228d673e9f079630d6cdaff5a2ed13e0e60",
},
{
name: "odd address",
args: args{address: "7526228d673e9f079630d6cdaff5a2ed13e0e60"},
want: "07526228d673e9f079630d6cdaff5a2ed13e0e60",
},
{
name: "ErrAddressMissing",
args: args{address: ""},
want: "",
wantErr: true,
},
{
name: "error - not eth address",
args: args{address: "1JKgN43B9SyLuZH19H5ECvr4KcfrbVHzZ6"},
want: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &EthParser{}
got, err := p.GetAddrIDFromAddress(tt.args.address)
if (err != nil) != tt.wantErr {
t.Errorf("EthParser.GetAddrIDFromAddress() error = %v, wantErr %v", err, tt.wantErr)
return
}
h := hex.EncodeToString(got)
if !reflect.DeepEqual(h, tt.want) {
t.Errorf("EthParser.GetAddrIDFromAddress() = %v, want %v", h, tt.want)
}
})
}
}

View File

@ -11,6 +11,9 @@ var (
// either unknown hash or too high height
// can be returned from GetBlockHash, GetBlockHeader, GetBlock
ErrBlockNotFound = errors.New("Block not found")
// ErrAddressMissing is returned if address is not specified
// for example To address in ethereum can be missing in case of contract transaction
ErrAddressMissing = errors.New("Address missing")
)
type ScriptSig struct {

View File

@ -143,6 +143,9 @@ func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, f
glog.Infof("rocksdb: address get %s %d-%d ", address, lower, higher)
}
addrID, err := d.chainParser.GetAddrIDFromAddress(address)
if err != nil {
return err
}
kstart, err := packOutputKey(addrID, lower)
if err != nil {
@ -283,7 +286,10 @@ func (d *RocksDB) writeOutputs(wb *gorocksdb.WriteBatch, block *bchain.Block, op
for _, output := range tx.Vout {
addrID, err := d.chainParser.GetAddrIDFromVout(&output)
if err != nil {
glog.Warningf("rocksdb: addrID: %v - %d %s", err, block.Height, addrID)
// do not log ErrAddressMissing, transactions can be without to address (for example eth contracts)
if err != bchain.ErrAddressMissing {
glog.Warningf("rocksdb: addrID: %v - height %d, tx %v, output %v", err, block.Height, tx.Txid, output)
}
continue
}
err = d.addAddrIDToRecords(op, wb, records, addrID, tx.Txid, int32(output.N), block.Height)