aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephenButtolph <stephen@avalabs.org>2020-08-20 09:42:06 -0400
committerStephenButtolph <stephen@avalabs.org>2020-08-20 09:42:06 -0400
commit52c6ccd2f063a6cccc35f5b4380b22fb9dd0f102 (patch)
tree465d0b4981d28835483f56e19129b27e986494d6
parent6febda1bc51f6658ab8f5cf705454e3f9c24a1f4 (diff)
implemented exportTx accept
-rw-r--r--plugin/evm/block.go78
-rw-r--r--plugin/evm/export_tx.go35
-rw-r--r--plugin/evm/vm.go13
3 files changed, 82 insertions, 44 deletions
diff --git a/plugin/evm/block.go b/plugin/evm/block.go
index b3412a0..8e13c67 100644
--- a/plugin/evm/block.go
+++ b/plugin/evm/block.go
@@ -33,9 +33,12 @@ func (b *Block) Accept() error {
vm.updateStatus(b.ID(), choices.Accepted)
tx := vm.getAtomicTx(b.ethBlock)
+ if tx == nil {
+ return nil
+ }
utx, ok := tx.UnsignedTx.(UnsignedAtomicTx)
if !ok {
- return errors.New("unknown atomic tx type")
+ return errors.New("unknown tx type")
}
return utx.Accept(vm.ctx, nil)
@@ -73,47 +76,50 @@ func (b *Block) Parent() snowman.Block {
func (b *Block) Verify() error {
vm := b.vm
tx := vm.getAtomicTx(b.ethBlock)
- switch atx := tx.UnsignedTx.(type) {
- case *UnsignedImportTx:
- if b.ethBlock.Hash() == vm.genesisHash {
- return nil
- }
- p := b.Parent()
- path := []*Block{}
- inputs := new(ids.Set)
- for {
- if p.Status() == choices.Accepted || p.(*Block).ethBlock.Hash() == vm.genesisHash {
- break
+ if tx != nil {
+ switch atx := tx.UnsignedTx.(type) {
+ case *UnsignedImportTx:
+ if b.ethBlock.Hash() == vm.genesisHash {
+ return nil
}
- if ret, hit := vm.blockAtomicInputCache.Get(p.ID()); hit {
- inputs = ret.(*ids.Set)
- break
+ p := b.Parent()
+ path := []*Block{}
+ inputs := new(ids.Set)
+ for {
+ if p.Status() == choices.Accepted || p.(*Block).ethBlock.Hash() == vm.genesisHash {
+ break
+ }
+ if ret, hit := vm.blockAtomicInputCache.Get(p.ID()); hit {
+ inputs = ret.(*ids.Set)
+ break
+ }
+ path = append(path, p.(*Block))
+ p = p.Parent().(*Block)
}
- path = append(path, p.(*Block))
- p = p.Parent().(*Block)
- }
- for i := len(path) - 1; i >= 0; i-- {
- inputsCopy := new(ids.Set)
- p := path[i]
- atx := vm.getAtomicTx(p.ethBlock)
- inputs.Union(atx.UnsignedTx.(UnsignedAtomicTx).InputUTXOs())
- inputsCopy.Union(*inputs)
- vm.blockAtomicInputCache.Put(p.ID(), inputsCopy)
- }
- for _, in := range atx.InputUTXOs().List() {
- if inputs.Contains(in) {
- return errInvalidBlock
+ for i := len(path) - 1; i >= 0; i-- {
+ inputsCopy := new(ids.Set)
+ p := path[i]
+ atx := vm.getAtomicTx(p.ethBlock)
+ if atx != nil {
+ inputs.Union(atx.UnsignedTx.(UnsignedAtomicTx).InputUTXOs())
+ inputsCopy.Union(*inputs)
+ }
+ vm.blockAtomicInputCache.Put(p.ID(), inputsCopy)
}
+ for _, in := range atx.InputUTXOs().List() {
+ if inputs.Contains(in) {
+ return errInvalidBlock
+ }
+ }
+ case *UnsignedExportTx:
+ default:
+ return errors.New("unknown atomic tx type")
}
- case *UnsignedExportTx:
- default:
- return errors.New("unknown atomic tx type")
- }
- if tx.UnsignedTx.(UnsignedAtomicTx).SemanticVerify(vm, tx) != nil {
- return errInvalidBlock
+ if tx.UnsignedTx.(UnsignedAtomicTx).SemanticVerify(vm, tx) != nil {
+ return errInvalidBlock
+ }
}
-
_, err := b.vm.chain.InsertChain([]*types.Block{b.ethBlock})
return err
}
diff --git a/plugin/evm/export_tx.go b/plugin/evm/export_tx.go
index 8b3c4f8..31b4681 100644
--- a/plugin/evm/export_tx.go
+++ b/plugin/evm/export_tx.go
@@ -10,6 +10,7 @@ import (
"github.com/ava-labs/coreth/core/state"
"github.com/ava-labs/go-ethereum/log"
+ "github.com/ava-labs/gecko/chains/atomic"
"github.com/ava-labs/gecko/database"
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/snow"
@@ -126,9 +127,37 @@ func (tx *UnsignedExportTx) SemanticVerify(
}
// Accept this transaction.
-func (tx *UnsignedExportTx) Accept(ctx *snow.Context, batch database.Batch) error {
- // TODO: finish this function via gRPC
- return nil
+func (tx *UnsignedExportTx) Accept(ctx *snow.Context, _ database.Batch) error {
+ txID := tx.ID()
+
+ elems := make([]*atomic.Element, len(tx.ExportedOutputs))
+ for i, out := range tx.ExportedOutputs {
+ utxo := &avax.UTXO{
+ UTXOID: avax.UTXOID{
+ TxID: txID,
+ OutputIndex: uint32(i),
+ },
+ Asset: avax.Asset{ID: out.AssetID()},
+ Out: out.Out,
+ }
+
+ utxoBytes, err := Codec.Marshal(utxo)
+ if err != nil {
+ return err
+ }
+
+ elem := &atomic.Element{
+ Key: utxo.InputID().Bytes(),
+ Value: utxoBytes,
+ }
+ if out, ok := utxo.Out.(avax.Addressable); ok {
+ elem.Traits = out.Addresses()
+ }
+
+ elems[i] = elem
+ }
+
+ return ctx.SharedMemory.Put(tx.DestinationChain, elems)
}
// Create a new transaction
diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go
index 0910f6d..4ea3793 100644
--- a/plugin/evm/vm.go
+++ b/plugin/evm/vm.go
@@ -177,11 +177,10 @@ type VM struct {
}
func (vm *VM) getAtomicTx(block *types.Block) *Tx {
+ extdata := block.ExtraData()
atx := new(Tx)
- if extdata := block.ExtraData(); extdata != nil {
- if err := vm.codec.Unmarshal(extdata, atx); err != nil {
- panic(err)
- }
+ if err := vm.codec.Unmarshal(extdata, atx); err != nil {
+ return nil
}
atx.Sign(vm.codec, nil)
return atx
@@ -284,7 +283,11 @@ func (vm *VM) Initialize(
return vm.getLastAccepted().ethBlock
})
chain.SetOnExtraStateChange(func(block *types.Block, state *state.StateDB) error {
- return vm.getAtomicTx(block).UnsignedTx.(UnsignedAtomicTx).EVMStateTransfer(state)
+ tx := vm.getAtomicTx(block)
+ if tx == nil {
+ return nil
+ }
+ return tx.UnsignedTx.(UnsignedAtomicTx).EVMStateTransfer(state)
})
vm.blockCache = cache.LRU{Size: 2048}
vm.blockStatusCache = cache.LRU{Size: 1024}