CheckErrorCondition returns nil if the running script has ended and was successful, leaving a a true boolean on the stack. An error otherwise, including if the script has not finished.
(finalScript bool)
| 926 | // successful, leaving a a true boolean on the stack. An error otherwise, |
| 927 | // including if the script has not finished. |
| 928 | func (vm *Engine) CheckErrorCondition(finalScript bool) error { |
| 929 | if vm.taprootCtx != nil && vm.taprootCtx.mustSucceed { |
| 930 | return nil |
| 931 | } |
| 932 | |
| 933 | // Check execution is actually done by ensuring the script index is after |
| 934 | // the final script in the array script. |
| 935 | if vm.scriptIdx < len(vm.scripts) { |
| 936 | return scriptError(ErrScriptUnfinished, |
| 937 | "error check when script unfinished") |
| 938 | } |
| 939 | |
| 940 | // If we're in version zero witness execution mode, and this was the |
| 941 | // final script, then the stack MUST be clean in order to maintain |
| 942 | // compatibility with BIP16. |
| 943 | if finalScript && vm.isWitnessVersionActive(BaseSegwitWitnessVersion) && |
| 944 | vm.dstack.Depth() != 1 { |
| 945 | return scriptError(ErrCleanStack, "witness program must "+ |
| 946 | "have clean stack") |
| 947 | } |
| 948 | |
| 949 | // The final script must end with exactly one data stack item when the |
| 950 | // verify clean stack flag is set. Otherwise, there must be at least one |
| 951 | // data stack item in order to interpret it as a boolean. |
| 952 | cleanStackActive := vm.hasFlag(ScriptVerifyCleanStack) || vm.taprootCtx != nil |
| 953 | if finalScript && cleanStackActive && vm.dstack.Depth() != 1 { |
| 954 | |
| 955 | str := fmt.Sprintf( |
| 956 | "stack must contain exactly one item (contains %d)", |
| 957 | vm.dstack.Depth(), |
| 958 | ) |
| 959 | return scriptError(ErrCleanStack, str) |
| 960 | } else if vm.dstack.Depth() < 1 { |
| 961 | return scriptError(ErrEmptyStack, |
| 962 | "stack empty at end of script execution") |
| 963 | } |
| 964 | |
| 965 | v, err := vm.dstack.PopBool() |
| 966 | if err != nil { |
| 967 | return err |
| 968 | } |
| 969 | if !v { |
| 970 | // Log interesting data. |
| 971 | log.Tracef("%v", newLogClosure(func() string { |
| 972 | var buf strings.Builder |
| 973 | buf.WriteString("scripts failed:\n") |
| 974 | for i := range vm.scripts { |
| 975 | dis, _ := vm.DisasmScript(i) |
| 976 | buf.WriteString(fmt.Sprintf("script%d:\n", i)) |
| 977 | buf.WriteString(dis) |
| 978 | } |
| 979 | return buf.String() |
| 980 | })) |
| 981 | return scriptError(ErrEvalFalse, |
| 982 | "false stack entry at end of script execution") |
| 983 | } |
| 984 | return nil |
| 985 | } |