vm

package
v0.0.0-...-0b9d80d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2016 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package vm implements the VM described in Chain Protocol 1.

The VM is for verifying transaction inputs and blocks. Accordingly there are two main entrypoints: VerifyTxInput and VerifyBlockHeader, both in vm.go. Each constructs a disposable VM object to perform its computation.

For VerifyTxInput, the program to execute comes from the input commitment: either the prevout's control program, if it's a spend input; or the issuance program, if it's an issuance. For VerifyBlockHeader, the program to execute is the previous block's consensus program. In all cases, the VM's data stack is first populated with witness data from the current object (transaction input or block).

The program is interpreted byte-by-byte by the main loop in virtualMachine.run(). Most bytes are opcodes in one of the following categories:

  • bitwise
  • control
  • crypto
  • introspection
  • numeric
  • pushdata
  • splice
  • stack

Each category has a corresponding .go file implementing those opcodes.

Each instruction incurs some cost when executed. These costs are deducted from (and in some cases refunded to) a predefined run limit. Costs are tallied in two conceptual phases: "before" the instruction runs and "after." In practice, "before" charges are applied on the fly in the body of each opcode's implementation, and "after" charges are deferred until the instruction finishes, at which point the VM main loop applies the deferred charges. As such, functions that have associated costs (chiefly stack pushing and popping) include a "deferred" flag as an argument.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAltStackUnderflow  = errors.New("alt stack underflow")
	ErrBadValue           = errors.New("bad value")
	ErrContext            = errors.New("wrong context")
	ErrDataStackUnderflow = errors.New("data stack underflow")
	ErrDisallowedOpcode   = errors.New("disallowed opcode")
	ErrDivZero            = errors.New("division by zero")
	ErrLongProgram        = errors.New("program size exceeds maxint32")
	ErrRange              = errors.New("range error")
	ErrReturn             = errors.New("RETURN executed")
	ErrRunLimitExceeded   = errors.New("run limit exceeded")
	ErrShortProgram       = errors.New("unexpected end of program")
	ErrToken              = errors.New("unrecognized token")
	ErrUnexpected         = errors.New("unexpected error")
	ErrUnsupportedTx      = errors.New("unsupported transaction type")
	ErrUnsupportedVM      = errors.New("unsupported VM")
	ErrVerifyFailed       = errors.New("VERIFY failed")
)
View Source
var TraceOut io.Writer

TraceOut - if non-nil - will receive trace output during execution.

Functions

func AsBool

func AsBool(bytes []byte) bool

func AsInt64

func AsInt64(b []byte) (int64, error)

func Assemble

func Assemble(s string) (res []byte, err error)

Assemble converts a string like "2 3 ADD 5 NUMEQUAL" into 0x525393559c. The input should not include PUSHDATA (or OP_<num>) ops; those will be inferred. Input may include jump-target labels of the form $foo, which can then be used as JUMP:$foo or JUMPIF:$foo.

func BoolBytes

func BoolBytes(b bool) (result []byte)

func Disassemble

func Disassemble(prog []byte) (string, error)

func Int64Bytes

func Int64Bytes(n int64) []byte

func PushdataBytes

func PushdataBytes(in []byte) []byte

func PushdataInt64

func PushdataInt64(n int64) []byte

func VerifyBlockHeader

func VerifyBlockHeader(prev *bc.BlockHeader, block *bc.Block) (ok bool, err error)

func VerifyTxInput

func VerifyTxInput(tx *bc.Tx, inputIndex int) (ok bool, err error)

Types

type Instruction

type Instruction struct {
	Op   Op
	Len  uint32
	Data []byte
}

func ParseOp

func ParseOp(prog []byte, pc uint32) (inst Instruction, err error)

ParseOp parses the op at position pc in prog, returning the parsed instruction (opcode plus any associated data).

func ParseProgram

func ParseProgram(prog []byte) ([]Instruction, error)

type Op

type Op uint8
const (
	OP_FALSE Op = 0x00
	OP_0     Op = 0x00 // synonym

	OP_1    Op = 0x51
	OP_TRUE Op = 0x51 // synonym

	OP_2  Op = 0x52
	OP_3  Op = 0x53
	OP_4  Op = 0x54
	OP_5  Op = 0x55
	OP_6  Op = 0x56
	OP_7  Op = 0x57
	OP_8  Op = 0x58
	OP_9  Op = 0x59
	OP_10 Op = 0x5a
	OP_11 Op = 0x5b
	OP_12 Op = 0x5c
	OP_13 Op = 0x5d
	OP_14 Op = 0x5e
	OP_15 Op = 0x5f
	OP_16 Op = 0x60

	OP_DATA_1  Op = 0x01
	OP_DATA_2  Op = 0x02
	OP_DATA_3  Op = 0x03
	OP_DATA_4  Op = 0x04
	OP_DATA_5  Op = 0x05
	OP_DATA_6  Op = 0x06
	OP_DATA_7  Op = 0x07
	OP_DATA_8  Op = 0x08
	OP_DATA_9  Op = 0x09
	OP_DATA_10 Op = 0x0a
	OP_DATA_11 Op = 0x0b
	OP_DATA_12 Op = 0x0c
	OP_DATA_13 Op = 0x0d
	OP_DATA_14 Op = 0x0e
	OP_DATA_15 Op = 0x0f
	OP_DATA_16 Op = 0x10
	OP_DATA_17 Op = 0x11
	OP_DATA_18 Op = 0x12
	OP_DATA_19 Op = 0x13
	OP_DATA_20 Op = 0x14
	OP_DATA_21 Op = 0x15
	OP_DATA_22 Op = 0x16
	OP_DATA_23 Op = 0x17
	OP_DATA_24 Op = 0x18
	OP_DATA_25 Op = 0x19
	OP_DATA_26 Op = 0x1a
	OP_DATA_27 Op = 0x1b
	OP_DATA_28 Op = 0x1c
	OP_DATA_29 Op = 0x1d
	OP_DATA_30 Op = 0x1e
	OP_DATA_31 Op = 0x1f
	OP_DATA_32 Op = 0x20
	OP_DATA_33 Op = 0x21
	OP_DATA_34 Op = 0x22
	OP_DATA_35 Op = 0x23
	OP_DATA_36 Op = 0x24
	OP_DATA_37 Op = 0x25
	OP_DATA_38 Op = 0x26
	OP_DATA_39 Op = 0x27
	OP_DATA_40 Op = 0x28
	OP_DATA_41 Op = 0x29
	OP_DATA_42 Op = 0x2a
	OP_DATA_43 Op = 0x2b
	OP_DATA_44 Op = 0x2c
	OP_DATA_45 Op = 0x2d
	OP_DATA_46 Op = 0x2e
	OP_DATA_47 Op = 0x2f
	OP_DATA_48 Op = 0x30
	OP_DATA_49 Op = 0x31
	OP_DATA_50 Op = 0x32
	OP_DATA_51 Op = 0x33
	OP_DATA_52 Op = 0x34
	OP_DATA_53 Op = 0x35
	OP_DATA_54 Op = 0x36
	OP_DATA_55 Op = 0x37
	OP_DATA_56 Op = 0x38
	OP_DATA_57 Op = 0x39
	OP_DATA_58 Op = 0x3a
	OP_DATA_59 Op = 0x3b
	OP_DATA_60 Op = 0x3c
	OP_DATA_61 Op = 0x3d
	OP_DATA_62 Op = 0x3e
	OP_DATA_63 Op = 0x3f
	OP_DATA_64 Op = 0x40
	OP_DATA_65 Op = 0x41
	OP_DATA_66 Op = 0x42
	OP_DATA_67 Op = 0x43
	OP_DATA_68 Op = 0x44
	OP_DATA_69 Op = 0x45
	OP_DATA_70 Op = 0x46
	OP_DATA_71 Op = 0x47
	OP_DATA_72 Op = 0x48
	OP_DATA_73 Op = 0x49
	OP_DATA_74 Op = 0x4a
	OP_DATA_75 Op = 0x4b

	OP_PUSHDATA1 Op = 0x4c
	OP_PUSHDATA2 Op = 0x4d
	OP_PUSHDATA4 Op = 0x4e
	OP_1NEGATE   Op = 0x4f
	OP_NOP       Op = 0x61

	OP_JUMP           Op = 0x63
	OP_JUMPIF         Op = 0x64
	OP_VERIFY         Op = 0x69
	OP_FAIL           Op = 0x6a
	OP_CHECKPREDICATE Op = 0xc0

	OP_TOALTSTACK   Op = 0x6b
	OP_FROMALTSTACK Op = 0x6c
	OP_2DROP        Op = 0x6d
	OP_2DUP         Op = 0x6e
	OP_3DUP         Op = 0x6f
	OP_2OVER        Op = 0x70
	OP_2ROT         Op = 0x71
	OP_2SWAP        Op = 0x72
	OP_IFDUP        Op = 0x73
	OP_DEPTH        Op = 0x74
	OP_DROP         Op = 0x75
	OP_DUP          Op = 0x76
	OP_NIP          Op = 0x77
	OP_OVER         Op = 0x78
	OP_PICK         Op = 0x79
	OP_ROLL         Op = 0x7a
	OP_ROT          Op = 0x7b
	OP_SWAP         Op = 0x7c
	OP_TUCK         Op = 0x7d

	OP_CAT         Op = 0x7e
	OP_SUBSTR      Op = 0x7f
	OP_LEFT        Op = 0x80
	OP_RIGHT       Op = 0x81
	OP_SIZE        Op = 0x82
	OP_CATPUSHDATA Op = 0x89

	OP_INVERT      Op = 0x83
	OP_AND         Op = 0x84
	OP_OR          Op = 0x85
	OP_XOR         Op = 0x86
	OP_EQUAL       Op = 0x87
	OP_EQUALVERIFY Op = 0x88

	OP_1ADD               Op = 0x8b
	OP_1SUB               Op = 0x8c
	OP_2MUL               Op = 0x8d
	OP_2DIV               Op = 0x8e
	OP_NEGATE             Op = 0x8f
	OP_ABS                Op = 0x90
	OP_NOT                Op = 0x91
	OP_0NOTEQUAL          Op = 0x92
	OP_ADD                Op = 0x93
	OP_SUB                Op = 0x94
	OP_MUL                Op = 0x95
	OP_DIV                Op = 0x96
	OP_MOD                Op = 0x97
	OP_LSHIFT             Op = 0x98
	OP_RSHIFT             Op = 0x99
	OP_BOOLAND            Op = 0x9a
	OP_BOOLOR             Op = 0x9b
	OP_NUMEQUAL           Op = 0x9c
	OP_NUMEQUALVERIFY     Op = 0x9d
	OP_NUMNOTEQUAL        Op = 0x9e
	OP_LESSTHAN           Op = 0x9f
	OP_GREATERTHAN        Op = 0xa0
	OP_LESSTHANOREQUAL    Op = 0xa1
	OP_GREATERTHANOREQUAL Op = 0xa2
	OP_MIN                Op = 0xa3
	OP_MAX                Op = 0xa4
	OP_WITHIN             Op = 0xa5

	OP_RIPEMD160     Op = 0xa6
	OP_SHA1          Op = 0xa7
	OP_SHA256        Op = 0xa8
	OP_SHA3          Op = 0xaa
	OP_CHECKSIG      Op = 0xac
	OP_CHECKMULTISIG Op = 0xad
	OP_TXSIGHASH     Op = 0xae
	OP_BLOCKSIGHASH  Op = 0xaf

	OP_CHECKOUTPUT   Op = 0xc1
	OP_ASSET         Op = 0xc2
	OP_AMOUNT        Op = 0xc3
	OP_PROGRAM       Op = 0xc4
	OP_MINTIME       Op = 0xc5
	OP_MAXTIME       Op = 0xc6
	OP_TXREFDATAHASH Op = 0xc7
	OP_REFDATAHASH   Op = 0xc8
	OP_INDEX         Op = 0xc9
	OP_OUTPOINT      Op = 0xcb
	OP_NONCE         Op = 0xcc
	OP_NEXTPROGRAM   Op = 0xcd
	OP_BLOCKTIME     Op = 0xce
)

func (Op) String

func (op Op) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL