From 14fe03cbfecf508848bcd1172ea8d2ee3e41fda4 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Thu, 30 Jul 2020 22:00:38 -0700 Subject: TWEAK: Set minimum gas price. --- plugin/evm/block.go | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 449e261..1a2bf9e 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -61,6 +61,15 @@ func (b *Block) Parent() snowman.Block { // Verify implements the snowman.Block interface func (b *Block) Verify() error { + // Ensure the minimum gas price is paid for every transaction + for _, tx := range b.ethBlock.Transactions() { + if tx.GasPrice().Cmp(minGasPrice) < 0 { + return errInvalidBlock + } + } + + // Attempt to add the block to the chain and consider the block valid iff it's + // accepted _, err := b.vm.chain.InsertChain([]*types.Block{b.ethBlock}) return err } -- cgit v1.2.3 From 4945ae1427399d9a0f6b3561306f50f360011613 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Wed, 12 Aug 2020 22:50:17 -0400 Subject: read blocks with caching --- plugin/evm/block.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index eaa78a5..2912d2c 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -50,11 +50,7 @@ func (b *Block) Status() choices.Status { // Parent implements the snowman.Block interface func (b *Block) Parent() snowman.Block { parentID := ids.NewID(b.ethBlock.ParentHash()) - block := &Block{ - id: parentID, - ethBlock: b.vm.getCachedBlock(parentID), - vm: b.vm, - } + block := b.vm.getBlock(parentID) b.vm.ctx.Log.Verbo("Parent(%s) has status: %s", block.ID(), block.Status()) return block } -- cgit v1.2.3 From 9616c7265c06952530674fdbc193c824e099c2c4 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Thu, 13 Aug 2020 01:22:15 -0400 Subject: fixed parent block nil pointer --- plugin/evm/block.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 2912d2c..80c03a2 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/gecko/ids" "github.com/ava-labs/gecko/snow/choices" "github.com/ava-labs/gecko/snow/consensus/snowman" + "github.com/ava-labs/gecko/vms/components/missing" ) // Block implements the snowman.Block interface @@ -50,9 +51,12 @@ func (b *Block) Status() choices.Status { // Parent implements the snowman.Block interface func (b *Block) Parent() snowman.Block { parentID := ids.NewID(b.ethBlock.ParentHash()) - block := b.vm.getBlock(parentID) - b.vm.ctx.Log.Verbo("Parent(%s) has status: %s", block.ID(), block.Status()) - return block + if block := b.vm.getBlock(parentID); block != nil { + b.vm.ctx.Log.Verbo("Parent(%s) has status: %s", parentID, block.Status()) + return block + } + b.vm.ctx.Log.Verbo("Parent(%s) has status: %s", parentID, choices.Unknown) + return &missing.Block{BlkID: parentID} } // Verify implements the snowman.Block interface -- cgit v1.2.3 From 0844c8c6919f6d98ebe8a9501360ef5bc362dff3 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 19 Aug 2020 01:25:20 -0400 Subject: catch up with the new P-Chain cross-chain impl --- plugin/evm/block.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 449e261..9c15834 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -61,6 +61,27 @@ func (b *Block) Parent() snowman.Block { // Verify implements the snowman.Block interface func (b *Block) Verify() error { + p := b + path := []*Block{} + for { + if p.Status() == choices.Accepted { + break + } + path = append(path, p) + p = p.Parent().(*Block) + } + inputs := new(ids.Set) + for i := len(path) - 1; i >= 0; i-- { + p := path[i] + atx := p.vm.getAtomicTx(p.ethBlock) + inputs.Union(atx.UnsignedTx.(UnsignedAtomicTx).InputUTXOs()) + } + tx := b.vm.getAtomicTx(b.ethBlock) + atx := tx.UnsignedTx.(*UnsignedImportTx) + if atx.SemanticVerify(b.vm, tx) != nil { + return errInvalidBlock + } + _, err := b.vm.chain.InsertChain([]*types.Block{b.ethBlock}) return err } -- cgit v1.2.3 From 315ad2c63fa4879e5a91c3aa013c93f8f4969362 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 19 Aug 2020 11:16:35 -0400 Subject: finish the block verification impl --- plugin/evm/block.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'plugin/evm/block.go') 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 } -- cgit v1.2.3 From fbcfc73c7a92d0a2615ef90c4dffa4746161b9c7 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 19 Aug 2020 11:45:32 -0400 Subject: ... --- plugin/evm/block.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 45a888f..a2ffb69 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -80,12 +80,12 @@ func (b *Block) Verify() error { p = p.Parent().(*Block) } for i := len(path) - 1; i >= 0; i-- { - inputs_copy := new(ids.Set) + inputsCopy := new(ids.Set) p := path[i] atx := vm.getAtomicTx(p.ethBlock) inputs.Union(atx.UnsignedTx.(UnsignedAtomicTx).InputUTXOs()) - inputs_copy.Union(*inputs) - vm.blockAtomicInputCache.Put(p.ID(), inputs_copy) + inputsCopy.Union(*inputs) + vm.blockAtomicInputCache.Put(p.ID(), inputsCopy) } tx := b.vm.getAtomicTx(b.ethBlock) atx := tx.UnsignedTx.(*UnsignedImportTx) -- cgit v1.2.3 From 1e9599e88a5d88e0090b0ebddfae756e343e605a Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 19 Aug 2020 20:32:18 -0400 Subject: make the basic X-to-C logic work --- plugin/evm/block.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index a2ffb69..1cbf0b7 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -69,7 +69,7 @@ func (b *Block) Verify() error { path := []*Block{} inputs := new(ids.Set) for { - if p.Status() == choices.Accepted { + if p.Status() == choices.Accepted || p.(*Block).ethBlock.Hash() == vm.genesisHash { break } if ret, hit := vm.blockAtomicInputCache.Get(p.ID()); hit { -- cgit v1.2.3 From 5fc26bb832c715cfd2628585d41bb82209ecdfe4 Mon Sep 17 00:00:00 2001 From: Determinant Date: Thu, 20 Aug 2020 00:44:56 -0400 Subject: ... --- plugin/evm/block.go | 65 +++++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 1cbf0b7..d75ea1d 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -4,6 +4,7 @@ package evm import ( + "errors" "fmt" "github.com/ava-labs/coreth/core/types" @@ -62,39 +63,45 @@ func (b *Block) Parent() snowman.Block { // Verify implements the snowman.Block interface func (b *Block) Verify() error { 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 || p.(*Block).ethBlock.Hash() == vm.genesisHash { - break + tx := vm.getAtomicTx(b.ethBlock) + 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) - } - tx := b.vm.getAtomicTx(b.ethBlock) - atx := tx.UnsignedTx.(*UnsignedImportTx) - 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) + 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") } - if atx.SemanticVerify(b.vm, tx) != nil { + + if tx.UnsignedTx.(UnsignedAtomicTx).SemanticVerify(vm, tx) != nil { return errInvalidBlock } -- cgit v1.2.3 From 1c078567367ef45884da079cecc09a71d1761b01 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Thu, 20 Aug 2020 01:09:43 -0400 Subject: Added first pass of importTx verification --- plugin/evm/block.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index d75ea1d..b3412a0 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -27,9 +27,18 @@ func (b *Block) ID() ids.ID { return b.id } // Accept implements the snowman.Block interface func (b *Block) Accept() error { - b.vm.ctx.Log.Verbo("Block %s is accepted", b.ID()) - b.vm.updateStatus(b.ID(), choices.Accepted) - return nil + vm := b.vm + + vm.ctx.Log.Verbo("Block %s is accepted", b.ID()) + vm.updateStatus(b.ID(), choices.Accepted) + + tx := vm.getAtomicTx(b.ethBlock) + utx, ok := tx.UnsignedTx.(UnsignedAtomicTx) + if !ok { + return errors.New("unknown atomic tx type") + } + + return utx.Accept(vm.ctx, nil) } // Reject implements the snowman.Block interface -- cgit v1.2.3 From 52c6ccd2f063a6cccc35f5b4380b22fb9dd0f102 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Thu, 20 Aug 2020 09:42:06 -0400 Subject: implemented exportTx accept --- plugin/evm/block.go | 78 ++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 36 deletions(-) (limited to 'plugin/evm/block.go') 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 } -- cgit v1.2.3 From b05d11d451fb73843abcf6bd5fc8664b069433a4 Mon Sep 17 00:00:00 2001 From: StephenButtolph Date: Tue, 25 Aug 2020 13:20:28 -0400 Subject: fixed potential vulnerability with bootstrapping blocks --- plugin/evm/block.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'plugin/evm/block.go') diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 375dc6d..5c30fe1 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -74,10 +74,13 @@ func (b *Block) Parent() snowman.Block { // Verify implements the snowman.Block interface func (b *Block) Verify() error { - // Ensure the minimum gas price is paid for every transaction - for _, tx := range b.ethBlock.Transactions() { - if tx.GasPrice().Cmp(minGasPrice) < 0 { - return errInvalidBlock + // Only enforce a minimum fee when bootstrapping has finished + if b.vm.ctx.IsBootstrapped() { + // Ensure the minimum gas price is paid for every transaction + for _, tx := range b.ethBlock.Transactions() { + if tx.GasPrice().Cmp(minGasPrice) < 0 { + return errInvalidBlock + } } } -- cgit v1.2.3