aboutsummaryrefslogtreecommitdiff
path: root/plugin/evm/export_tx.go
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2020-09-19 01:22:25 -0400
committerDeterminant <[email protected]>2020-09-19 01:22:25 -0400
commit573ff7bbf2a0b529fd3f8acf4aa825e446c73423 (patch)
treef02eef21d4017d326c91fbc6a6b994374fd4b64d /plugin/evm/export_tx.go
parentd0bbfb33f16a69ce24e123b01ebb30de8193ddc8 (diff)
WIP: fix bugs in crosschain transfer and support general assets
Diffstat (limited to 'plugin/evm/export_tx.go')
-rw-r--r--plugin/evm/export_tx.go38
1 files changed, 30 insertions, 8 deletions
diff --git a/plugin/evm/export_tx.go b/plugin/evm/export_tx.go
index 0487c44..231afee 100644
--- a/plugin/evm/export_tx.go
+++ b/plugin/evm/export_tx.go
@@ -8,7 +8,6 @@ import (
"math/big"
"github.com/ava-labs/coreth/core/state"
- "github.com/ethereum/go-ethereum/log"
"github.com/ava-labs/avalanchego/chains/atomic"
"github.com/ava-labs/avalanchego/database"
@@ -18,6 +17,7 @@ import (
safemath "github.com/ava-labs/avalanchego/utils/math"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
+ "github.com/ethereum/go-ethereum/log"
)
// UnsignedExportTx is an unsigned ExportTx
@@ -162,6 +162,7 @@ func (tx *UnsignedExportTx) Accept(ctx *snow.Context, _ database.Batch) error {
// Create a new transaction
func (vm *VM) newExportTx(
+ assetID ids.ID, // AssetID of the tokens to export
amount uint64, // Amount of tokens to export
chainID ids.ID, // Chain to send the UTXOs to
to ids.ShortID, // Address of chain recipient
@@ -171,15 +172,32 @@ func (vm *VM) newExportTx(
return nil, errWrongChainID
}
- toBurn, err := safemath.Add64(amount, vm.txFee)
- if err != nil {
- return nil, errOverflowExport
+ var toBurn uint64
+ var err error
+ if assetID == vm.ctx.AVAXAssetID {
+ toBurn, err = safemath.Add64(amount, vm.txFee)
+ if err != nil {
+ return nil, errOverflowExport
+ }
+ } else {
+ toBurn = vm.txFee
}
- ins, signers, err := vm.GetSpendableCanonical(keys, toBurn)
+ // burn AVAX
+ ins, signers, err := vm.GetSpendableCanonical(keys, vm.ctx.AVAXAssetID, toBurn)
if err != nil {
return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err)
}
+ // burn non-AVAX
+ if assetID != vm.ctx.AVAXAssetID {
+ ins2, signers2, err := vm.GetSpendableCanonical(keys, assetID, toBurn)
+ if err != nil {
+ return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err)
+ }
+ ins = append(ins, ins2...)
+ signers = append(signers, signers2...)
+ }
+
// Create the transaction
utx := &UnsignedExportTx{
NetworkID: vm.ctx.NetworkID,
@@ -205,15 +223,19 @@ func (vm *VM) newExportTx(
return tx, utx.Verify(vm.ctx.XChainID, vm.ctx, vm.txFee, vm.ctx.AVAXAssetID)
}
-func (tx *UnsignedExportTx) EVMStateTransfer(state *state.StateDB) error {
+func (tx *UnsignedExportTx) EVMStateTransfer(vm *VM, state *state.StateDB) error {
for _, from := range tx.Ins {
- log.Info("consume", "in", from.Address, "amount", from.Amount, "nonce", from.Nonce, "nonce0", state.GetNonce(from.Address))
+ log.Info("crosschain C->X", "addr", from.Address, "amount", from.Amount)
amount := new(big.Int).Mul(
new(big.Int).SetUint64(from.Amount), x2cRate)
if state.GetBalance(from.Address).Cmp(amount) < 0 {
return errInsufficientFunds
}
- state.SubBalance(from.Address, amount)
+ if from.AssetID == vm.ctx.AVAXAssetID {
+ state.SubBalance(from.Address, amount)
+ } else {
+ state.SubBalanceMultiCoin(from.Address, from.AssetID.Key(), amount)
+ }
if state.GetNonce(from.Address) != from.Nonce {
return errInvalidNonce
}