diff --git a/server/asset/eth/eth.go b/server/asset/eth/eth.go index 88b09a3604..0ccbba1ae7 100644 --- a/server/asset/eth/eth.go +++ b/server/asset/eth/eth.go @@ -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. @@ -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() } @@ -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. @@ -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 +} diff --git a/server/asset/eth/eth_test.go b/server/asset/eth/eth_test.go index 5ac59abcf3..946b0d6358 100644 --- a/server/asset/eth/eth_test.go +++ b/server/asset/eth/eth_test.go @@ -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()) @@ -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 @@ -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") } @@ -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 +}