From 80f76ae97372ea074ce660dbcaffd97c648ece22 Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 19 Sep 2020 19:32:37 -0400 Subject: fully support C<->X asset transfer --- go.sum | 1 + internal/ethapi/api.go | 5 +++-- plugin/evm/export_tx.go | 30 ++++++++++++++++++------------ plugin/evm/service.go | 3 +-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/go.sum b/go.sum index f3b1b46..46ee8bd 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ github.com/ava-labs/avalanchego v0.8.0-beta/go.mod h1:quYojL1hu0ue2glUT1ng28kADs github.com/ava-labs/avalanchego v0.8.0 h1:aAt4roNkkaQx8jgQeKDvTGqSJ2h++rilBAK/xo/uYqo= github.com/ava-labs/avalanchego v0.8.3 h1:ioc7RtSAzIv40qxHDikhqZGVxF3y+8cXeIrLpGz9jtc= github.com/ava-labs/avalanchego v0.8.3/go.mod h1:6zPzQv7m6vSvdKAwH+lLTga0IMd/0+HLMT5OULrpFcU= +github.com/ava-labs/avalanchego v0.8.4 h1:8ulQiUsw0r0G0/teZb+fR6fvsZo1YHPJ5fKxQWjT+LM= github.com/ava-labs/coreth v0.2.5/go.mod h1:pGolKipwq5vGIY2IBBcBkMYrqniXMsS5SBn+BBi4+Js= github.com/ava-labs/coreth v0.2.14-rc.1/go.mod h1:Zhb60GFIB7G5AnUCks0Jo4Rezx/EovL8o+z51aBF1A8= github.com/ava-labs/coreth v0.2.15-rc.4/go.mod h1:+sK2XGKCNA48uzeHWe4iBzmiOBYmYvnnzLtOkQeQfkk= diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9e50f64..825f8fc 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -25,6 +25,7 @@ import ( "strings" "time" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/coreth/accounts" "github.com/ava-labs/coreth/accounts/keystore" "github.com/ava-labs/coreth/accounts/scwallet" @@ -558,12 +559,12 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add // GetBalanceMultiCoin returns the amount of wei for the given address in the state of the // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta // block numbers are also allowed. -func (s *PublicBlockChainAPI) GetBalanceMultiCoin(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash, coinID common.Hash) (*hexutil.Big, error) { +func (s *PublicBlockChainAPI) GetAssetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash, assetID ids.ID) (*hexutil.Big, error) { state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) if state == nil || err != nil { return nil, err } - return (*hexutil.Big)(state.GetBalanceMultiCoin(address, coinID)), state.Error() + return (*hexutil.Big)(state.GetBalanceMultiCoin(address, assetID.Key())), state.Error() } // Result structs for GetProof diff --git a/plugin/evm/export_tx.go b/plugin/evm/export_tx.go index 9cfd5ba..8b512df 100644 --- a/plugin/evm/export_tx.go +++ b/plugin/evm/export_tx.go @@ -198,23 +198,25 @@ func (vm *VM) newExportTx( signers = append(signers, signers2...) } + exportOuts := []*avax.TransferableOutput{{ // Exported to X-Chain + Asset: avax.Asset{ID: assetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{to}, + }, + }, + }} + // Create the transaction utx := &UnsignedExportTx{ NetworkID: vm.ctx.NetworkID, BlockchainID: vm.ctx.ChainID, DestinationChain: chainID, Ins: ins, - ExportedOutputs: []*avax.TransferableOutput{{ // Exported to X-Chain - Asset: avax.Asset{ID: assetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: amount, - OutputOwners: secp256k1fx.OutputOwners{ - Locktime: 0, - Threshold: 1, - Addrs: []ids.ShortID{to}, - }, - }, - }}, + ExportedOutputs: exportOuts, } tx := &Tx{UnsignedTx: utx} if err := tx.Sign(vm.codec, signers); err != nil { @@ -224,6 +226,7 @@ func (vm *VM) newExportTx( } func (tx *UnsignedExportTx) EVMStateTransfer(vm *VM, state *state.StateDB) error { + addrs := map[[20]byte]uint64{} for _, from := range tx.Ins { log.Info("crosschain C->X", "addr", from.Address, "amount", from.Amount) amount := new(big.Int).Mul( @@ -243,7 +246,10 @@ func (tx *UnsignedExportTx) EVMStateTransfer(vm *VM, state *state.StateDB) error if state.GetNonce(from.Address) != from.Nonce { return errInvalidNonce } - state.SetNonce(from.Address, from.Nonce+1) + addrs[from.Address] = from.Nonce + } + for addr, nonce := range addrs { + state.SetNonce(addr, nonce+1) } return nil } diff --git a/plugin/evm/service.go b/plugin/evm/service.go index f50d66a..c34a59d 100644 --- a/plugin/evm/service.go +++ b/plugin/evm/service.go @@ -329,10 +329,9 @@ func (service *AvaxAPI) Export(_ *http.Request, args *ExportArgs, response *api. return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } - assetID := service.vm.ctx.AVAXAssetID // Create the transaction tx, err := service.vm.newExportTx( - assetID, // AssetID + args.AssetID, // AssetID uint64(args.Amount), // Amount chainID, // ID of the chain to send the funds to to, // Address -- cgit v1.2.3