From ebb1b5a6a89e7da516ffaac76c2546b7a4d298b3 Mon Sep 17 00:00:00 2001 From: Colt Date: Tue, 15 Aug 2017 17:48:03 +0800 Subject: [PATCH] modify the validation level code for charge gas --- protocol/validation/block_test.go | 85 ---------------------------------- protocol/validation/validation.go | 23 ++++----- protocol/validation/validation_test.go | 1 + protocol/validation/vmcontext.go | 13 ------ 4 files changed, 11 insertions(+), 111 deletions(-) diff --git a/protocol/validation/block_test.go b/protocol/validation/block_test.go index f287f43b..e9176bb5 100644 --- a/protocol/validation/block_test.go +++ b/protocol/validation/block_test.go @@ -2,100 +2,15 @@ package validation import ( "testing" - "time" "github.com/blockchain/protocol/bc" "github.com/blockchain/protocol/bc/legacy" - "github.com/blockchain/protocol/vm" - "github.com/blockchain/protocol/vm/vmutil" ) -func TestValidateBlock1(t *testing.T) { - b1 := newInitialBlock(t) - err := ValidateBlock(b1, nil, b1.ID, dummyValidateTx) - if err != nil { - t.Errorf("ValidateBlock(%v, nil) = %v, want nil", b1, err) - } -} - -func TestValidateBlock1Err(t *testing.T) { - b1 := newInitialBlock(t) - transactionsRoot := bc.NewHash([32]byte{1}) - b1.TransactionsRoot = &transactionsRoot // make b1 be invalid - err := ValidateBlock(b1, nil, b1.ID, dummyValidateTx) - if err == nil { - t.Errorf("ValidateBlock(%v, nil) = nil, want error", b1) - } -} - -func TestValidateBlock2(t *testing.T) { - b1 := newInitialBlock(t) - b2 := generate(t, b1) - err := ValidateBlock(b2, b1, b2.ID, dummyValidateTx) - if err != nil { - t.Errorf("ValidateBlock(%v, %v) = %v, want nil", b2, b1, err) - } -} - -func TestValidateBlock2Err(t *testing.T) { - b1 := newInitialBlock(t) - b2 := generate(t, b1) - transactionsRoot := bc.NewHash([32]byte{1}) - b2.TransactionsRoot = &transactionsRoot // make b2 be invalid - err := ValidateBlock(b2, b1, b2.ID, dummyValidateTx) - if err == nil { - t.Errorf("ValidateBlock(%v, %v) = nil, want error", b2, b1) - } -} - -func TestValidateBlockSig2(t *testing.T) { - b1 := newInitialBlock(t) - b2 := generate(t, b1) - err := ValidateBlockSig(b2, b1.NextConsensusProgram) - if err != nil { - t.Errorf("ValidateBlockSig(%v, %v) = %v, want nil", b2, b1, err) - } -} - -func TestValidateBlockSig2Err(t *testing.T) { - b1 := newInitialBlock(t) - b2 := generate(t, b1) - prog := []byte{byte(vm.OP_FALSE)} // make b2 be invalid - err := ValidateBlockSig(b2, prog) - if err == nil { - t.Errorf("ValidateBlockSig(%v, %v) = nil, want error", b2, b1) - } -} - func dummyValidateTx(*bc.Tx) error { return nil } -func newInitialBlock(tb testing.TB) *bc.Block { - script, err := vmutil.BlockMultiSigProgram(nil, 0) - if err != nil { - tb.Fatal(err) - } - - root, err := bc.MerkleRoot(nil) // calculate the zero value of the tx merkle root - if err != nil { - tb.Fatal(err) - } - - b := &legacy.Block{ - BlockHeader: legacy.BlockHeader{ - Version: 1, - Height: 1, - TimestampMS: bc.Millis(time.Now()), - BlockCommitment: legacy.BlockCommitment{ - TransactionsMerkleRoot: root, - ConsensusProgram: script, - }, - }, - } - return legacy.MapBlock(b) -} - func generate(tb testing.TB, prev *bc.Block) *bc.Block { b := &legacy.Block{ BlockHeader: legacy.BlockHeader{ diff --git a/protocol/validation/validation.go b/protocol/validation/validation.go index c5e13230..6290f801 100644 --- a/protocol/validation/validation.go +++ b/protocol/validation/validation.go @@ -29,6 +29,9 @@ type validationState struct { // Memoized per-entry validation results cache map[bc.Hash]error + + // gas left for run the BVM + gasLimit int64 } var ( @@ -98,7 +101,7 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { } case *bc.Mux: - err = vm.Verify(NewTxVMContext(vs.tx, e, e.Program, e.WitnessArguments)) + vs.gasLimit, err = vm.Verify(NewTxVMContext(vs.tx, e, e.Program, e.WitnessArguments), vs.gasLimit) if err != nil { return errors.Wrap(err, "checking mux program") } @@ -153,7 +156,7 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { } case *bc.Nonce: - err = vm.Verify(NewTxVMContext(vs.tx, e, e.Program, e.WitnessArguments)) + vs.gasLimit, err = vm.Verify(NewTxVMContext(vs.tx, e, e.Program, e.WitnessArguments), vs.gasLimit) if err != nil { return errors.Wrap(err, "checking nonce program") } @@ -226,7 +229,7 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { return errors.Wrapf(bc.ErrMissingEntry, "entry for issuance anchor %x not found", e.AnchorId.Bytes()) } - err = vm.Verify(NewTxVMContext(vs.tx, e, e.WitnessAssetDefinition.IssuanceProgram, e.WitnessArguments)) + vs.gasLimit, err = vm.Verify(NewTxVMContext(vs.tx, e, e.WitnessAssetDefinition.IssuanceProgram, e.WitnessArguments), vs.gasLimit) if err != nil { return errors.Wrap(err, "checking issuance program") } @@ -276,7 +279,7 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { if err != nil { return errors.Wrap(err, "getting spend prevout") } - err = vm.Verify(NewTxVMContext(vs.tx, e, spentOutput.ControlProgram, e.WitnessArguments)) + vs.gasLimit, err = vm.Verify(NewTxVMContext(vs.tx, e, spentOutput.ControlProgram, e.WitnessArguments), vs.gasLimit) if err != nil { return errors.Wrap(err, "checking control program") } @@ -444,13 +447,6 @@ func checkValidDest(vs *validationState, vd *bc.ValueDestination) error { return nil } -// ValidateBlockSig runs the consensus program prog on b. -func ValidateBlockSig(b *bc.Block, prog []byte) error { - vmContext := newBlockVMContext(b, prog, b.WitnessArguments) - err := vm.Verify(vmContext) - return errors.Wrap(err, "evaluating previous block's next consensus program") -} - // ValidateBlock validates a block and the transactions within. // It does not run the consensus program; for that, see ValidateBlockSig. func ValidateBlock(b, prev *bc.Block, initialBlockID bc.Hash, validateTx func(*bc.Tx) error) error { @@ -516,12 +512,13 @@ func validateBlockAgainstPrev(b, prev *bc.Block) error { // ValidateTx validates a transaction. func ValidateTx(tx *bc.Tx, initialBlockID bc.Hash) error { + //TODO: handle the gas limit vs := &validationState{ blockchainID: initialBlockID, tx: tx, entryID: tx.ID, - - cache: make(map[bc.Hash]error), + gasLimit: 10000, + cache: make(map[bc.Hash]error), } return checkValid(vs, tx.TxHeader) } diff --git a/protocol/validation/validation_test.go b/protocol/validation/validation_test.go index a9d2c949..111a002f 100644 --- a/protocol/validation/validation_test.go +++ b/protocol/validation/validation_test.go @@ -345,6 +345,7 @@ func TestTxValidation(t *testing.T) { blockchainID: fixture.initialBlockID, tx: tx, entryID: tx.ID, + gasLimit: 10000, cache: make(map[bc.Hash]error), } out := tx.Entries[*tx.ResultIds[0]].(*bc.Output) diff --git a/protocol/validation/vmcontext.go b/protocol/validation/vmcontext.go index 3654f7a9..636bfd9a 100644 --- a/protocol/validation/vmcontext.go +++ b/protocol/validation/vmcontext.go @@ -9,19 +9,6 @@ import ( "github.com/blockchain/protocol/vm" ) -func newBlockVMContext(block *bc.Block, prog []byte, args [][]byte) *vm.Context { - blockHash := block.ID.Bytes() - return &vm.Context{ - VMVersion: 1, - Code: prog, - Arguments: args, - - BlockHash: &blockHash, - BlockTimeMS: &block.TimestampMs, - NextConsensusProgram: &block.NextConsensusProgram, - } -} - func NewTxVMContext(tx *bc.Tx, entry bc.Entry, prog *bc.Program, args [][]byte) *vm.Context { var ( numResults = uint64(len(tx.ResultIds)) -- 2.11.0