Skip to content

Commit

Permalink
server/asset/eth: update server coin ID parsing
Browse files Browse the repository at this point in the history
Older notions of coin ID have evolved. Except in the case of a
funding coin, ETH coin ID will simply be the tx hash bytes.
  • Loading branch information
buck54321 committed Dec 2, 2021
1 parent ced9b02 commit 8c36984
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 14 deletions.
31 changes: 21 additions & 10 deletions server/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ func (d *Driver) Setup(configPath string, logger dex.Logger, network dex.Network

// DecodeCoinID creates a human-readable representation of a coin ID for Ethereum.
func (d *Driver) DecodeCoinID(coinID []byte) (string, error) {
coinId, err := dexeth.DecodeCoinID(coinID)
txHash, err := decodeCoinID(coinID)
if err != nil {
return "", err
}
return coinId.String(), nil
return txHash.String(), nil
}

// UnitInfo returns the dex.UnitInfo for the asset.
Expand Down Expand Up @@ -210,19 +210,18 @@ func (eth *Backend) Connect(ctx context.Context) (*sync.WaitGroup, error) {

// TxData fetches the raw transaction data.
func (eth *Backend) TxData(coinID []byte) ([]byte, error) {
cnr, err := dexeth.DecodeCoinID(coinID)
txHash, err := decodeCoinID(coinID)
if err != nil {
return nil, fmt.Errorf("coin ID decoding error: %v", err)
}
c, is := cnr.(*dexeth.TxCoinID)
if !is {
return nil, fmt.Errorf("wrong type of coin ID, %v", cnr)
}

tx, _, err := eth.node.transaction(eth.rpcCtx, c.TxID)
tx, _, err := eth.node.transaction(eth.rpcCtx, txHash)
if err != nil {
return nil, fmt.Errorf("error retrieving transaction: %w", err)
}
if tx == nil { // Possible?
return nil, fmt.Errorf("no transaction %s", txHash)
}

return tx.MarshalBinary()
}
Expand Down Expand Up @@ -336,11 +335,11 @@ func (eth *Backend) Redemption(redeemCoinID, contractCoinID []byte) (asset.Coin,

// ValidateCoinID attempts to decode the coinID.
func (eth *Backend) ValidateCoinID(coinID []byte) (string, error) {
coinId, err := dexeth.DecodeCoinID(coinID)
txHash, err := decodeCoinID(coinID)
if err != nil {
return "", err
}
return coinId.String(), nil
return txHash.String(), nil
}

// ValidateContract ensures that the secret hash is the correct length.
Expand Down Expand Up @@ -506,3 +505,15 @@ out:
// Wait for the RPC client to shut down.
wg.Wait()
}

// decodeCoinID decodes the coin ID into a common.Hash. For eth, there are no
// funding coin IDs, just an account address. Care should be taken not to use
// decodeCoinID or (Driver).DecodeCoinID for account addresses.
func decodeCoinID(coinID []byte) (common.Hash, error) {
if len(coinID) != common.HashLength {
return common.Hash{}, fmt.Errorf("wrong coin ID length. wanted %d, got %d", common.HashLength, len(coinID))
}
var h common.Hash
h.SetBytes(coinID)
return h, nil
}
60 changes: 56 additions & 4 deletions server/asset/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,50 @@ func TestLoad(t *testing.T) {
}
}

func TestDecodeCoinID(t *testing.T) {
drv := &Driver{}
txid := "0x1b86600b740d58ecc06eda8eba1c941c7ba3d285c78be89b56678da146ed53d1"
txHashB := mustDecodeHex("1b86600b740d58ecc06eda8eba1c941c7ba3d285c78be89b56678da146ed53d1")

type test struct {
name string
input []byte
wantErr bool
expRes string
}

tests := []test{{
name: "ok",
input: txHashB,
expRes: txid,
}, {
name: "too short",
input: txHashB[:len(txHashB)/2],
wantErr: true,
}, {
name: "too long",
input: append(txHashB, txHashB...),
wantErr: true,
}}

for _, tt := range tests {
res, err := drv.DecodeCoinID(tt.input)
if err != nil {
if !tt.wantErr {
t.Fatalf("%s: error: %v", tt.name, err)
}
continue
}

if tt.wantErr {
t.Fatalf("%s: no error", tt.name)
}
if res != tt.expRes {
t.Fatalf("%s: wrong result. wanted %s, got %s", tt.name, tt.expRes, res)
}
}
}

func TestRun(t *testing.T) {
// TODO: Test all paths.
ctx, cancel := context.WithCancel(context.Background())
Expand Down Expand Up @@ -551,7 +595,7 @@ func TestTxData(t *testing.T) {
addr := randomAddress()
data := encode.RandomBytes(5)
tx := tTx(gasPrice, value, addr, data)
goodCoinID := (&dexeth.TxCoinID{TxID: tx.Hash()}).Encode()
goodCoinID, _ := hex.DecodeString("09c3bed75b35c6cf0549b0636c9511161b18765c019ef371e2a9f01e4b4a1487")
node.tx = tx

// initial success
Expand All @@ -572,14 +616,14 @@ func TestTxData(t *testing.T) {
}

// Wrong type of coin ID
coinID = (&dexeth.SwapCoinID{}).Encode()
_, err = eth.TxData(coinID)
_, err = eth.TxData(goodCoinID[2:])
if err == nil {
t.Fatalf("no error for wrong coin type")
}

// No transaction
_, err = eth.TxData(coinID)
node.tx = nil
_, err = eth.TxData(goodCoinID)
if err == nil {
t.Fatalf("no error for missing tx")
}
Expand Down Expand Up @@ -652,3 +696,11 @@ func TestAccountBalance(t *testing.T) {
t.Fatalf("AccountBalance error: %v", err)
}
}

func mustDecodeHex(s string) []byte {
b, err := hex.DecodeString(s)
if err != nil {
panic("mustDecodeHex: " + err.Error())
}
return b
}

0 comments on commit 8c36984

Please sign in to comment.