diff options
Diffstat (limited to 'plugin')
-rw-r--r-- | plugin/evm/block.go | 24 | ||||
-rw-r--r-- | plugin/evm/vm.go | 6 |
2 files changed, 26 insertions, 4 deletions
diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 9c15834..45a888f 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -61,23 +61,39 @@ func (b *Block) Parent() snowman.Block { // Verify implements the snowman.Block interface func (b *Block) Verify() error { - p := b + vm := b.vm + if b.ethBlock.Hash() == vm.genesisHash { + return nil + } + p := b.Parent() path := []*Block{} + inputs := new(ids.Set) for { if p.Status() == choices.Accepted { break } - path = append(path, p) + if ret, hit := vm.blockAtomicInputCache.Get(p.ID()); hit { + inputs = ret.(*ids.Set) + break + } + path = append(path, p.(*Block)) p = p.Parent().(*Block) } - inputs := new(ids.Set) for i := len(path) - 1; i >= 0; i-- { + inputs_copy := new(ids.Set) p := path[i] - atx := p.vm.getAtomicTx(p.ethBlock) + atx := vm.getAtomicTx(p.ethBlock) inputs.Union(atx.UnsignedTx.(UnsignedAtomicTx).InputUTXOs()) + inputs_copy.Union(*inputs) + vm.blockAtomicInputCache.Put(p.ID(), inputs_copy) } tx := b.vm.getAtomicTx(b.ethBlock) atx := tx.UnsignedTx.(*UnsignedImportTx) + for _, in := range atx.InputUTXOs().List() { + if inputs.Contains(in) { + return errInvalidBlock + } + } if atx.SemanticVerify(b.vm, tx) != nil { return errInvalidBlock } diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 4fe4cc0..7a310bf 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -134,6 +134,7 @@ type VM struct { genlock sync.Mutex txSubmitChan <-chan struct{} + atomicTxSubmitChan chan struct{} codec codec.Codec clock timer.Clock avaxAssetID ids.ID @@ -211,6 +212,7 @@ func (vm *VM) Initialize( case atx := <-vm.pendingAtomicTxs: raw, _ := vm.codec.Marshal(atx) block.SetExtraData(raw) + // TODO: make sure the atomic Tx is valid } return nil }) @@ -313,6 +315,9 @@ func (vm *VM) Initialize( case <-vm.txSubmitChan: vm.ctx.Log.Verbo("New tx detected, trying to generate a block") vm.tryBlockGen() + case <-vm.atomicTxSubmitChan: + vm.ctx.Log.Verbo("New atomic Tx detected, trying to generate a block") + vm.tryBlockGen() case <-time.After(5 * time.Second): vm.tryBlockGen() } @@ -628,6 +633,7 @@ func (vm *VM) FormatAddress(addr common.Address) (string, error) { func (vm *VM) issueTx(tx *Tx) error { select { case vm.pendingAtomicTxs <- tx: + vm.atomicTxSubmitChan <- struct{}{} default: return errTooManyAtomicTx } |