aboutsummaryrefslogblamecommitdiff
path: root/plugin/evm/import_tx_test.go
blob: fcd18acc9d74a029c160f3d8c24141f49b24a534 (plain) (tree)
1
2
3
4
5
6
7
8
9







                                                     
                                                       
                                             
                                                      




                                                             
                                      























































                                                                                                       




                                                                                


                                                                                              
 

                                              

                                              


                                                                                               
 


                                              
                                                 


                                                                                                  
 


                                              
                                                        







                                                                                                 
                                             












































































































































































































































                                                                                                                        
 
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
	"testing"

	"github.com/ava-labs/avalanchego/chains/atomic"
	"github.com/ava-labs/avalanchego/ids"
	"github.com/ava-labs/avalanchego/utils/crypto"
	"github.com/ava-labs/avalanchego/vms/components/avax"
	"github.com/ava-labs/avalanchego/vms/secp256k1fx"
)

func TestImportTxVerifyNil(t *testing.T) {
	var importTx *UnsignedImportTx
	if err := importTx.Verify(testXChainID, NewContext(), testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("Verify should have failed due to nil transaction")
	}
}

func TestImportTxVerify(t *testing.T) {
	var importAmount uint64 = 10000000
	txID := ids.NewID([32]byte{0xff})
	importTx := &UnsignedImportTx{
		NetworkID:    testNetworkID,
		BlockchainID: testCChainID,
		SourceChain:  testXChainID,
		ImportedInputs: []*avax.TransferableInput{
			{
				UTXOID: avax.UTXOID{
					TxID:        txID,
					OutputIndex: uint32(0),
				},
				Asset: avax.Asset{ID: testAvaxAssetID},
				In: &secp256k1fx.TransferInput{
					Amt: importAmount,
					Input: secp256k1fx.Input{
						SigIndices: []uint32{0},
					},
				},
			},
			{
				UTXOID: avax.UTXOID{
					TxID:        txID,
					OutputIndex: uint32(1),
				},
				Asset: avax.Asset{ID: testAvaxAssetID},
				In: &secp256k1fx.TransferInput{
					Amt: importAmount,
					Input: secp256k1fx.Input{
						SigIndices: []uint32{0},
					},
				},
			},
		},
		Outs: []EVMOutput{
			{
				Address: testEthAddrs[0],
				Amount:  importAmount,
				AssetID: testAvaxAssetID,
			},
			{
				Address: testEthAddrs[1],
				Amount:  importAmount,
				AssetID: testAvaxAssetID,
			},
		},
	}

	ctx := NewContext()

	// // Sort the inputs and outputs to ensure the transaction is canonical
	avax.SortTransferableInputs(importTx.ImportedInputs)
	SortEVMOutputs(importTx.Outs)

	// Test Valid ImportTx
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err != nil {
		t.Fatalf("Failed to verify ImportTx: %w", err)
	}

	importTx.syntacticallyVerified = false
	importTx.NetworkID = testNetworkID + 1

	// // Test Incorrect Network ID Errors
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to incorrect network ID")
	}

	importTx.syntacticallyVerified = false
	importTx.NetworkID = testNetworkID
	importTx.BlockchainID = nonExistentID
	// // Test Incorrect Blockchain ID Errors
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to incorrect blockchain ID")
	}

	importTx.syntacticallyVerified = false
	importTx.BlockchainID = testCChainID
	importTx.SourceChain = nonExistentID
	// // Test Incorrect Destination Chain ID Errors
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to incorrect source chain")
	}

	importTx.syntacticallyVerified = false
	importTx.SourceChain = testXChainID
	importedIns := importTx.ImportedInputs
	importTx.ImportedInputs = nil
	// // Test No Exported Outputs Errors
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to no imported inputs")
	}

	importTx.syntacticallyVerified = false
	importTx.ImportedInputs = []*avax.TransferableInput{importedIns[1], importedIns[0]}
	// // Test Unsorted Imported Inputs Errors
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to unsorted import inputs")
	}

	importTx.syntacticallyVerified = false
	importTx.ImportedInputs = []*avax.TransferableInput{importedIns[0], nil}
	if err := importTx.Verify(testXChainID, ctx, testTxFee, testAvaxAssetID); err == nil {
		t.Fatal("ImportTx should have failed verification due to invalid input")
	}
}

func TestImportTxSemanticVerify(t *testing.T) {
	_, vm, _, sharedMemory := GenesisVM(t, false)

	xChainSharedMemory := sharedMemory.NewSharedMemory(vm.ctx.XChainID)

	importAmount := uint64(1000000)
	utxoID := avax.UTXOID{
		TxID: ids.NewID([32]byte{
			0x0f, 0x2f, 0x4f, 0x6f, 0x8e, 0xae, 0xce, 0xee,
			0x0d, 0x2d, 0x4d, 0x6d, 0x8c, 0xac, 0xcc, 0xec,
			0x0b, 0x2b, 0x4b, 0x6b, 0x8a, 0xaa, 0xca, 0xea,
			0x09, 0x29, 0x49, 0x69, 0x88, 0xa8, 0xc8, 0xe8,
		}),
	}

	utxo := &avax.UTXO{
		UTXOID: utxoID,
		Asset:  avax.Asset{ID: vm.ctx.AVAXAssetID},
		Out: &secp256k1fx.TransferOutput{
			Amt: importAmount,
			OutputOwners: secp256k1fx.OutputOwners{
				Threshold: 1,
				Addrs:     []ids.ShortID{testKeys[0].PublicKey().Address()},
			},
		},
	}
	utxoBytes, err := vm.codec.Marshal(utxo)
	if err != nil {
		t.Fatal(err)
	}

	evmOutput := EVMOutput{
		Address: testEthAddrs[0],
		Amount:  importAmount,
		AssetID: vm.ctx.AVAXAssetID,
	}
	unsignedImportTx := &UnsignedImportTx{
		NetworkID:    vm.ctx.NetworkID,
		BlockchainID: vm.ctx.ChainID,
		SourceChain:  vm.ctx.XChainID,
		ImportedInputs: []*avax.TransferableInput{{
			UTXOID: utxoID,
			Asset:  avax.Asset{ID: vm.ctx.AVAXAssetID},
			In: &secp256k1fx.TransferInput{
				Amt:   importAmount,
				Input: secp256k1fx.