MCPcopy Index your code
hub / github.com/btcsuite/btcd / Step

Method Step

txscript/engine.go:993–1109  ·  view source on GitHub ↗

Step executes the next instruction and moves the program counter to the next opcode in the script, or the next script if the current has ended. Step will return true in the case that the last opcode was successfully executed. The result of calling Step or any other method is undefined if an error

()

Source from the content-addressed store, hash-verified

991// The result of calling Step or any other method is undefined if an error is
992// returned.
993func (vm *Engine) Step() (done bool, err error) {
994 // Verify the engine is pointing to a valid program counter.
995 if err := vm.checkValidPC(); err != nil {
996 return true, err
997 }
998
999 // Attempt to parse the next opcode from the current script.
1000 if !vm.tokenizer.Next() {
1001 // Note that due to the fact that all scripts are checked for parse
1002 // failures before this code ever runs, there should never be an error
1003 // here, but check again to be safe in case a refactor breaks that
1004 // assumption or new script versions are introduced with different
1005 // semantics.
1006 if err := vm.tokenizer.Err(); err != nil {
1007 return false, err
1008 }
1009
1010 str := fmt.Sprintf("attempt to step beyond script index %d (bytes %x)",
1011 vm.scriptIdx, vm.scripts[vm.scriptIdx])
1012 return true, scriptError(ErrInvalidProgramCounter, str)
1013 }
1014
1015 // Execute the opcode while taking into account several things such as
1016 // disabled opcodes, illegal opcodes, maximum allowed operations per script,
1017 // maximum script element sizes, and conditionals.
1018 err = vm.executeOpcode(vm.tokenizer.op, vm.tokenizer.Data())
1019 if err != nil {
1020 return true, err
1021 }
1022
1023 // The number of elements in the combination of the data and alt stacks
1024 // must not exceed the maximum number of stack elements allowed.
1025 combinedStackSize := vm.dstack.Depth() + vm.astack.Depth()
1026 if combinedStackSize > MaxStackSize {
1027 str := fmt.Sprintf("combined stack size %d > max allowed %d",
1028 combinedStackSize, MaxStackSize)
1029 return false, scriptError(ErrStackOverflow, str)
1030 }
1031
1032 // Prepare for next instruction.
1033 vm.opcodeIdx++
1034 if vm.tokenizer.Done() {
1035 // Illegal to have a conditional that straddles two scripts.
1036 if len(vm.condStack) != 0 {
1037 return false, scriptError(ErrUnbalancedConditional,
1038 "end of script reached in conditional execution")
1039 }
1040
1041 // Alt stack doesn't persist between scripts.
1042 _ = vm.astack.DropN(vm.astack.Depth())
1043
1044 // The number of operations is per script.
1045 vm.numOps = 0
1046
1047 // Reset the opcode index for the next script.
1048 vm.opcodeIdx = 0
1049
1050 // Advance to the next script as needed.

Callers 3

ExecuteMethod · 0.95
TestBadPCFunction · 0.95
TestCheckErrorConditionFunction · 0.95

Calls 15

checkValidPCMethod · 0.95
executeOpcodeMethod · 0.95
GetStackMethod · 0.95
CheckErrorConditionMethod · 0.95
SetStackMethod · 0.95
verifyWitnessProgramMethod · 0.95
scriptErrorFunction · 0.85
checkScriptParsesFunction · 0.85
MakeScriptTokenizerFunction · 0.85
ErrMethod · 0.80
DataMethod · 0.80
DropNMethod · 0.80

Tested by 2

TestBadPCFunction · 0.76
TestCheckErrorConditionFunction · 0.76