Skip to content

Commit

Permalink
checkpoint. redid server. tests passing. no v1 tests on server yet.
Browse files Browse the repository at this point in the history
  • Loading branch information
buck54321 committed Sep 11, 2023
1 parent cedd287 commit 9f934c8
Show file tree
Hide file tree
Showing 15 changed files with 867 additions and 555 deletions.
25 changes: 12 additions & 13 deletions client/asset/eth/contractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,6 @@ func (c *tokenContractorV0) tokenAddress() common.Address {
type contractorV1 struct {
contractV1
abi *abi.ABI
net dex.Network
contractAddr common.Address
acctAddr common.Address
cb bind.ContractBackend
Expand All @@ -597,19 +596,14 @@ type contractorV1 struct {

var _ contractor = (*contractorV1)(nil)

func newV1Contractor(net dex.Network, acctAddr common.Address, cb bind.ContractBackend) (contractor, error) {
contractAddr, exists := dexeth.ContractAddresses[1][net]
if !exists || contractAddr == (common.Address{}) {
return nil, fmt.Errorf("no contract address for version 0, net %s", net)
}
func newV1Contractor(contractAddr, acctAddr common.Address, cb bind.ContractBackend) (contractor, error) {
c, err := swapv1.NewETHSwap(contractAddr, cb)
if err != nil {
return nil, err
}
return &contractorV1{
contractV1: c,
abi: dexeth.ABIs[1],
net: net,
contractAddr: contractAddr,
acctAddr: acctAddr,
cb: cb,
Expand Down Expand Up @@ -701,7 +695,7 @@ func (c *contractorV1) redeem(txOpts *bind.TransactOpts, redeems []*asset.Redemp

// Not checking version from DecodeLocator because it was already
// audited and incorrect version locator would err below anyway.
_, locator, err := dexeth.DecodeLocator(r.Spends.Contract)
_, locator, err := dexeth.DecodeContractData(r.Spends.Contract)
if err != nil {
return nil, fmt.Errorf("error parsing locator redeem: %w", err)
}
Expand Down Expand Up @@ -852,11 +846,17 @@ type tokenContractorV1 struct {
tokenAddr common.Address
}

func newV1TokenContractor(net dex.Network, assetID uint32, acctAddr common.Address, cb bind.ContractBackend) (tokenContractor, error) {
token, tokenAddr, swapContractAddr, err := dexeth.VersionedNetworkToken(assetID, 1, net)
if err != nil {
return nil, err
func newV1TokenContractor(net dex.Network, token *dexeth.Token, acctAddr common.Address, cb bind.ContractBackend) (tokenContractor, error) {
netToken, ok := token.NetTokens[net]
if !ok {
return nil, fmt.Errorf("No %s token for network %s", token.Name, net)
}
swapContract, ok := netToken.SwapContracts[1]
if !ok {
return nil, fmt.Errorf("no version 1 swap contract for %s", token.Name)
}

tokenAddr, swapContractAddr := netToken.Address, swapContract.Address

c, err := erc20v1.NewERC20Swap(swapContractAddr, cb)
if err != nil {
Expand All @@ -880,7 +880,6 @@ func newV1TokenContractor(net dex.Network, assetID uint32, acctAddr common.Addre
contractorV1: &contractorV1{
contractV1: c,
abi: dexeth.ABIs[1],
net: net,
contractAddr: swapContractAddr,
acctAddr: acctAddr,
cb: cb,
Expand Down
71 changes: 26 additions & 45 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ const (
// TODO: Find a way to ask the host about their config set max fee and
// gas values.
maxTxFeeGwei = 1_000_000_000

contractVersionERC20 = ^uint32(0)
contractVersionUnknown = contractVersionERC20 - 1
)

var (
Expand Down Expand Up @@ -619,14 +616,7 @@ func privKeyFromSeed(seed []byte) (pk []byte, zero func(), err error) {
// contractVersion converts a server version to a contract version. It applies
// to both tokens and eth right now, but that may not always be the case.
func contractVersion(serverVer uint32) uint32 {
switch serverVer {
case 0:
return 0
case 1:
return 1
default:
return contractVersionUnknown
}
return dexeth.ProtocolVersion(serverVer).ContractVersion()
}

func CreateEVMWallet(chainID int64, createWalletParams *asset.CreateWalletParams, compat *CompatibilityData, skipConnect bool) error {
Expand Down Expand Up @@ -1392,9 +1382,10 @@ func (w *baseWallet) MaxFundingFees(_ uint32, _ uint64, _ map[string]string) uin

// SingleLotSwapRefundFees returns the fees for a swap transaction for a single lot.
func (w *assetWallet) SingleLotSwapRefundFees(serverVer uint32, feeSuggestion uint64, _ bool) (swapFees uint64, refundFees uint64, err error) {
g := w.gases(contractVersion(serverVer))
contractVer := contractVersion(serverVer)
g := w.gases(contractVer)
if g == nil {
return 0, 0, fmt.Errorf("no gases known for %d version %d", w.assetID, version)
return 0, 0, fmt.Errorf("no gases known for %d, contract version %d", w.assetID, contractVer)
}
return g.Swap * feeSuggestion, g.Refund * feeSuggestion, nil
}
Expand Down Expand Up @@ -2054,7 +2045,7 @@ func (w *ETHWallet) Swap(swaps *asset.Swaps) ([]asset.Receipt, asset.Coin, uint6
txHash: txHash,
locator: acToLocator(contractVer, swap, w.addr),
contractVer: contractVer,
contractAddr: w.versionedContracts[contractVer][w.net].String(),
contractAddr: w.versionedContracts[contractVer].String(),
})
}

Expand Down Expand Up @@ -2221,7 +2212,7 @@ func (w *assetWallet) Redeem(form *asset.RedeemForm, feeWallet *assetWallet, non
// from redemption.Spends.Contract. Even for scriptable UTXO assets, the
// redeem script in this Contract field is redundant with the SecretHash
// field as ExtractSwapDetails can be applied to extract the hash.
ver, locator, err := dexeth.DecodeLocator(redemption.Spends.Contract)
ver, locator, err := dexeth.DecodeContractData(redemption.Spends.Contract)
if err != nil {
return fail(fmt.Errorf("Redeem: invalid versioned swap contract data: %w", err))
}
Expand Down Expand Up @@ -2376,7 +2367,7 @@ func recoverPubkey(msgHash, sig []byte) ([]byte, error) {
// tokenBalance checks the token balance of the account handled by the wallet.
func (w *assetWallet) tokenBalance() (bal *big.Int, err error) {
// We don't care about the version.
return bal, w.withTokenContractor(w.assetID, contractVersionERC20, func(c tokenContractor) error {
return bal, w.withTokenContractor(w.assetID, dexeth.ContractVersionERC20, func(c tokenContractor) error {
bal, err = c.balance(w.ctx)
return err
})
Expand All @@ -2385,7 +2376,7 @@ func (w *assetWallet) tokenBalance() (bal *big.Int, err error) {
// tokenAllowance checks the amount of tokens that the swap contract is approved
// to spend on behalf of the account handled by the wallet.
func (w *assetWallet) tokenAllowance() (allowance *big.Int, err error) {
return allowance, w.withTokenContractor(w.assetID, contractVersionERC20, func(c tokenContractor) error {
return allowance, w.withTokenContractor(w.assetID, dexeth.ContractVersionERC20, func(c tokenContractor) error {
allowance, err = c.allowance(w.ctx)
return err
})
Expand Down Expand Up @@ -2750,7 +2741,7 @@ func (w *assetWallet) AuditContract(coinID, contract, serializedTx dex.Bytes, re
return nil, fmt.Errorf("AuditContract: coin id != txHash - coin id: %x, txHash: %s", coinID, tx.Hash())
}

version, locator, err := dexeth.DecodeLocator(contract)
version, locator, err := dexeth.DecodeContractData(contract)
if err != nil {
return nil, fmt.Errorf("AuditContract: failed to decode contract data: %w", err)
}
Expand Down Expand Up @@ -2792,19 +2783,8 @@ func (w *assetWallet) AuditContract(coinID, contract, serializedTx dex.Bytes, re
if !ok {
return nil, errors.New("AuditContract: tx does not initiate secret hash")
}
// Check vector equivalence. Secret hash equivalence is implied by the
// vectors presence in the map returned from ParseInitiateData.
if vec.Value != txVec.Value {
return nil, errors.New("tx data value doesn't match reported locator data")
}
if vec.To != txVec.To {
return nil, errors.New("tx to address doesn't match reported locator data")
}
if vec.From != txVec.From {
return nil, errors.New("tx from address doesn't match reported locator data")
}
if vec.LockTime != txVec.LockTime {
return nil, errors.New("tx lock time doesn't match reported locator data")
if !dexeth.CompareVectors(vec, txVec) {
return nil, fmt.Errorf("tx vector doesn't match expectation. %+v != %+v", txVec, vec)
}
val = vec.Value
participant = vec.To.String()
Expand Down Expand Up @@ -2853,7 +2833,7 @@ func (w *assetWallet) LockTimeExpired(ctx context.Context, lockTime time.Time) (
// ContractLockTimeExpired returns true if the specified contract's locktime has
// expired, making it possible to issue a Refund.
func (w *assetWallet) ContractLockTimeExpired(ctx context.Context, contract dex.Bytes) (bool, time.Time, error) {
contractVer, locator, err := dexeth.DecodeLocator(contract)
contractVer, locator, err := dexeth.DecodeContractData(contract)
if err != nil {
return false, time.Time{}, err
}
Expand Down Expand Up @@ -2941,7 +2921,7 @@ func (w *assetWallet) FindRedemption(ctx context.Context, _, contract dex.Bytes)
// contract, so we are basically doing the next best thing here.
const coinIDTmpl = coinIDTakerFoundMakerRedemption + "%s"

contractVer, locator, err := dexeth.DecodeLocator(contract)
contractVer, locator, err := dexeth.DecodeContractData(contract)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -3020,7 +3000,7 @@ func (w *assetWallet) findSecret(locator []byte, contractVer uint32) ([]byte, st
// Refund refunds a contract. This can only be used after the time lock has
// expired.
func (w *assetWallet) Refund(_, contract dex.Bytes, feeRate uint64) (dex.Bytes, error) {
contractVer, locator, err := dexeth.DecodeLocator(contract)
contractVer, locator, err := dexeth.DecodeContractData(contract)
if err != nil {
return nil, fmt.Errorf("Refund: failed to decode contract: %w", err)
}
Expand Down Expand Up @@ -3118,7 +3098,7 @@ func (w *ETHWallet) EstimateRegistrationTxFee(feeRate uint64) uint64 {
// EstimateRegistrationTxFee returns an estimate for the tx fee needed to
// pay the registration fee using the provided feeRate.
func (w *TokenWallet) EstimateRegistrationTxFee(feeRate uint64) uint64 {
g := w.gases(contractVersionERC20)
g := w.gases(dexeth.ContractVersionERC20)
if g == nil {
w.log.Errorf("no gas table")
return math.MaxUint64
Expand Down Expand Up @@ -3193,7 +3173,7 @@ func (w *TokenWallet) canSend(value uint64, verifyBalance, isPreEstimate bool) (
return 0, nil, fmt.Errorf("error getting max fee rate: %w", err)
}

g := w.gases(contractVersionERC20)
g := w.gases(dexeth.ContractVersionERC20)
if g == nil {
return 0, nil, fmt.Errorf("gas table not found")
}
Expand Down Expand Up @@ -3285,7 +3265,7 @@ func (w *ETHWallet) RestorationInfo(seed []byte) ([]*asset.WalletRestoration, er
// SwapConfirmations gets the number of confirmations and the spend status
// for the specified swap.
func (w *assetWallet) SwapConfirmations(ctx context.Context, coinID dex.Bytes, contract dex.Bytes, _ time.Time) (confs uint32, spent bool, err error) {
contractVer, secretHash, err := dexeth.DecodeLocator(contract)
contractVer, secretHash, err := dexeth.DecodeContractData(contract)
if err != nil {
return 0, false, err
}
Expand Down Expand Up @@ -3464,7 +3444,7 @@ func (eth *assetWallet) DynamicRedemptionFeesPaid(ctx context.Context, coinID, c
// secret hashes.
func (eth *baseWallet) swapOrRedemptionFeesPaid(ctx context.Context, coinID, contractData dex.Bytes,
isInit bool) (fee uint64, secretHashes [][]byte, err error) {
contractVer, locator, err := dexeth.DecodeLocator(contractData)
contractVer, locator, err := dexeth.DecodeContractData(contractData)
if err != nil {
return 0, nil, err
}
Expand Down Expand Up @@ -4068,7 +4048,7 @@ func (w *assetWallet) checkUnconfirmedRedemption(locator []byte, contractVer uin
// entire redemption batch, a new transaction containing only the swap we are
// searching for will be created.
func (w *assetWallet) confirmRedemptionWithoutMonitoredTx(txHash common.Hash, redemption *asset.Redemption, feeWallet *assetWallet) (*asset.ConfirmRedemptionStatus, error) {
contractVer, locator, err := dexeth.DecodeLocator(redemption.Spends.Contract)
contractVer, locator, err := dexeth.DecodeContractData(redemption.Spends.Contract)
if err != nil {
return nil, fmt.Errorf("failed to decode contract data: %w", err)
}
Expand Down Expand Up @@ -4161,7 +4141,7 @@ func (w *assetWallet) confirmRedemption(coinID dex.Bytes, redemption *asset.Rede
txHash = monitoredTxHash
}

contractVer, locator, err := dexeth.DecodeLocator(redemption.Spends.Contract)
contractVer, locator, err := dexeth.DecodeContractData(redemption.Spends.Contract)
if err != nil {
return nil, fmt.Errorf("failed to decode contract data: %w", err)
}
Expand Down Expand Up @@ -4465,15 +4445,15 @@ func (w *ETHWallet) sendToAddr(addr common.Address, amt uint64, maxFeeRate *big.
func (w *TokenWallet) sendToAddr(addr common.Address, amt uint64, maxFeeRate *big.Int) (tx *types.Transaction, err error) {
w.baseWallet.nonceSendMtx.Lock()
defer w.baseWallet.nonceSendMtx.Unlock()
g := w.gases(contractVersionERC20)
g := w.gases(dexeth.ContractVersionERC20)
if g == nil {
return nil, fmt.Errorf("no gas table")
}
txOpts, err := w.node.txOpts(w.ctx, 0, g.Transfer, nil, nil)
if err != nil {
return nil, err
}
return tx, w.withTokenContractor(w.assetID, contractVersionERC20, func(c tokenContractor) error {
return tx, w.withTokenContractor(w.assetID, dexeth.ContractVersionERC20, func(c tokenContractor) error {
tx, err = c.transfer(txOpts, addr, w.evmify(amt))
if err != nil {
c.voidUnusedNonce()
Expand Down Expand Up @@ -4596,7 +4576,7 @@ func (w *assetWallet) loadContractors() error {

// withContractor runs the provided function with the versioned contractor.
func (w *assetWallet) withContractor(contractVer uint32, f func(contractor) error) error {
if contractVer == contractVersionERC20 {
if contractVer == dexeth.ContractVersionERC20 {
// For ERC02 methods, use the most recent contractor version.
var bestVer uint32
var bestContractor contractor
Expand Down Expand Up @@ -4629,16 +4609,17 @@ func (w *assetWallet) withTokenContractor(assetID, ver uint32, f func(tokenContr
// estimateApproveGas estimates the gas required for a transaction approving a
// spender for an ERC20 contract.
func (w *assetWallet) estimateApproveGas(newGas *big.Int) (gas uint64, err error) {
return gas, w.withTokenContractor(w.assetID, contractVersionERC20, func(c tokenContractor) error {
return gas, w.withTokenContractor(w.assetID, dexeth.ContractVersionERC20, func(c tokenContractor) error {
gas, err = c.estimateApproveGas(w.ctx, newGas)
return err
})
}

// estimateTransferGas estimates the gas needed for a token transfer call to an
// ERC20 contract.
// TODO: Delete this and contractor methods. Unused.
func (w *assetWallet) estimateTransferGas(val uint64) (gas uint64, err error) {
return gas, w.withTokenContractor(w.assetID, contractVersionERC20, func(c tokenContractor) error {
return gas, w.withTokenContractor(w.assetID, dexeth.ContractVersionERC20, func(c tokenContractor) error {
gas, err = c.estimateTransferGas(w.ctx, w.evmify(val))
return err
})
Expand Down
Loading

0 comments on commit 9f934c8

Please sign in to comment.