diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go index 580a3cc023d1451f9d23b92a38c3044cf8bbf6df..a5f78963f214d13bd5946fd7581f46e111b52688 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go @@ -16,6 +16,7 @@ import ( . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state/types" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" vm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes" ) /* @@ -1242,17 +1243,17 @@ func snativeRoleTestInputTx(name string, user *acm.PrivAccount, role string) (sn func callContractCode(contractAddr []byte) []byte { // calldatacopy into mem and use as input to call memOff, inputOff := byte(0x0), byte(0x0) - contractCode := []byte{0x36, 0x60, inputOff, 0x60, memOff, 0x37} - - gas1, gas2 := byte(0x1), byte(0x1) value := byte(0x1) inOff := byte(0x0) retOff, retSize := byte(0x0), byte(0x20) + // this is the code we want to run (call a contract and return) - contractCode = append(contractCode, []byte{0x60, retSize, 0x60, retOff, 0x36, 0x60, inOff, 0x60, value, 0x73}...) - contractCode = append(contractCode, contractAddr...) - contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...) - return contractCode + return Bytecode(CALLDATASIZE, PUSH1, inputOff, PUSH1, memOff, + CALLDATACOPY, PUSH1, retSize, PUSH1, retOff, CALLDATASIZE, PUSH1, inOff, + PUSH1, value, PUSH20, contractAddr, + // Zeno loves us - call with half of the available gas each time we CALL + PUSH1, 2, GAS, DIV, CALL, + PUSH1, 32, PUSH1, 0, RETURN) } // convenience function for contract that is a factory for the code that comes as call data diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes/opcodes.go similarity index 81% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go rename to Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes/opcodes.go index 5ebd4807252a273b665359ffe6925e6f0fe7455d..284278396bdda627f41b2449306c749eb4dfcb8d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes/opcodes.go @@ -354,3 +354,51 @@ func AnalyzeJumpDests(code []byte) (dests *set.Set) { } return } + +// Convenience function to allow us to mix bytes, ints, and OpCodes that +// represent bytes in an EVM assembly code to make assembly more readable. +// Also allows us to splice together assembly +// fragments because any []byte arguments are flattened in the result. +func Bytecode(bytelikes ...interface{}) []byte { + bytes := make([]byte, len(bytelikes)) + for i, bytelike := range bytelikes { + switch b := bytelike.(type) { + case byte: + bytes[i] = b + case OpCode: + bytes[i] = byte(b) + case int: + bytes[i] = byte(b) + if int(bytes[i]) != b { + panic(fmt.Sprintf("The int %v does not fit inside a byte", b)) + } + case int64: + bytes[i] = byte(b) + if int64(bytes[i]) != b { + panic(fmt.Sprintf("The int64 %v does not fit inside a byte", b)) + } + case []byte: + // splice + return Concat(bytes[:i], b, Bytecode(bytelikes[i+1:]...)) + default: + panic("Only byte-like codes (and []byte sequences) can be used to form bytecode") + } + } + return bytes +} + +func Concat(bss ...[]byte) []byte { + offset := 0 + for _, bs := range bss { + offset += len(bs) + } + bytes := make([]byte, offset) + offset = 0 + for _, bs := range bss { + for i, b := range bs { + bytes[offset+i] = b + } + offset += len(bs) + } + return bytes +} \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go index c0fca12dd1ab36e51dfc34d47e340a570e81119f..0f09d9c308c44b338dc9eb8bb3150c2acf7b8e57 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go @@ -9,6 +9,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes" ) var expectedData = []byte{0x10} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go index 17b40bc5ef9d8532d929aba0c3b2e6cb8f6de933..f90fbf0820791fb4a6352218c59164cd925146bf 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go @@ -15,6 +15,7 @@ import ( ptypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes" "github.com/stretchr/testify/assert" ) @@ -207,20 +208,20 @@ func TestDelegateCallGas(t *testing.T) { // Do a simple operation using 1 gas unit calleeAccount, calleeAddress := makeAccountWithCode(appState, "callee", - bytecode(PUSH1, calleeReturnValue, return1())) + Bytecode(PUSH1, calleeReturnValue, return1())) // Here we split up the caller code so we can make a DELEGATE call with // different amounts of gas. The value we sandwich in the middle is the amount // we subtract from the available gas (that the caller has available), so: - // code := bytecode(callerCodePrefix, <amount to subtract from GAS> , callerCodeSuffix) + // code := Bytecode(callerCodePrefix, <amount to subtract from GAS> , callerCodeSuffix) // gives us the code to make the call - callerCodePrefix := bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, + callerCodePrefix := Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff, PUSH20, calleeAddress, PUSH1) - callerCodeSuffix := bytecode(GAS, SUB, DELEGATECALL, returnWord()) + callerCodeSuffix := Bytecode(GAS, SUB, DELEGATECALL, returnWord()) // Perform a delegate call callerAccount, _ := makeAccountWithCode(appState, "caller", - bytecode(callerCodePrefix, + Bytecode(callerCodePrefix, // Give just enough gas to make the DELEGATECALL costBetweenGasAndDelegateCall, callerCodeSuffix)) @@ -231,7 +232,7 @@ func TestDelegateCallGas(t *testing.T) { assert.NoError(t, err, "Should have sufficient funds for call") assert.Equal(t, Int64ToWord256(calleeReturnValue).Bytes(), output) - callerAccount.Code = bytecode(callerCodePrefix, + callerAccount.Code = Bytecode(callerCodePrefix, // Shouldn't be enough gas to make call costBetweenGasAndDelegateCall-1, callerCodeSuffix) @@ -245,12 +246,12 @@ func TestDelegateCallGas(t *testing.T) { // Store the top element of the stack (which is a 32-byte word) in memory // and return it. Useful for a simple return value. func return1() []byte { - return bytecode(PUSH1, 0, MSTORE, returnWord()) + return Bytecode(PUSH1, 0, MSTORE, returnWord()) } func returnWord() []byte { // PUSH1 => return size, PUSH1 => return offset, RETURN - return bytecode(PUSH1, 32, PUSH1, 0, RETURN) + return Bytecode(PUSH1, 32, PUSH1, 0, RETURN) } func makeAccountWithCode(appState AppState, name string, @@ -328,24 +329,24 @@ func callContractCode(addr []byte) []byte { inOff, inSize := byte(0x0), byte(0x0) // no call data retOff, retSize := byte(0x0), byte(0x20) // this is the code we want to run (send funds to an account and return) - return bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, + return Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize, PUSH1, retOff, RETURN) } func TestBytecode(t *testing.T) { assert.Equal(t, - bytecode(1, 2, 3, 4, 5, 6), - bytecode(1, 2, 3, bytecode(4, 5, 6))) + Bytecode(1, 2, 3, 4, 5, 6), + Bytecode(1, 2, 3, Bytecode(4, 5, 6))) assert.Equal(t, - bytecode(1, 2, 3, 4, 5, 6, 7, 8), - bytecode(1, 2, 3, bytecode(4, bytecode(5), 6), 7, 8)) + Bytecode(1, 2, 3, 4, 5, 6, 7, 8), + Bytecode(1, 2, 3, Bytecode(4, Bytecode(5), 6), 7, 8)) assert.Equal(t, - bytecode(PUSH1, 2), - bytecode(byte(PUSH1), 0x02)) + Bytecode(PUSH1, 2), + Bytecode(byte(PUSH1), 0x02)) assert.Equal(t, []byte{}, - bytecode(bytecode(bytecode()))) + Bytecode(Bytecode(Bytecode()))) contractAccount := &Account{Address: Int64ToWord256(102)} addr := contractAccount.Address.Postfix(20) @@ -353,7 +354,7 @@ func TestBytecode(t *testing.T) { value := byte(0x69) inOff, inSize := byte(0x0), byte(0x0) // no call data retOff, retSize := byte(0x0), byte(0x20) - contractCodeBytecode := bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, + contractCodeBytecode := Bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize, PUSH1, retOff, RETURN) contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73} @@ -365,62 +366,5 @@ func TestBytecode(t *testing.T) { func TestConcat(t *testing.T) { assert.Equal(t, []byte{0x01, 0x02, 0x03, 0x04}, - concat([]byte{0x01, 0x02}, []byte{0x03, 0x04})) + Concat([]byte{0x01, 0x02}, []byte{0x03, 0x04})) } - -// Convenience function to allow us to mix bytes, ints, and OpCodes that -// represent bytes in an EVM assembly code to make assembly more readable. -// Also allows us to splice together assembly -// fragments because any []byte arguments are flattened in the result. -func bytecode(bytelikes ...interface{}) []byte { - bytes := make([]byte, len(bytelikes)) - for i, bytelike := range bytelikes { - switch b := bytelike.(type) { - case byte: - bytes[i] = b - case OpCode: - bytes[i] = byte(b) - case int: - bytes[i] = byte(b) - if int(bytes[i]) != b { - panic(fmt.Sprintf("The int %v does not fit inside a byte", b)) - } - case int64: - bytes[i] = byte(b) - if int64(bytes[i]) != b { - panic(fmt.Sprintf("The int64 %v does not fit inside a byte", b)) - } - case []byte: - // splice - return concat(bytes[:i], b, bytecode(bytelikes[i+1:]...)) - default: - panic("Only byte-like codes (and []byte sequences) can be used to form bytecode") - } - } - return bytes -} - -func concat(bss ...[]byte) []byte { - offset := 0 - for _, bs := range bss { - offset += len(bs) - } - bytes := make([]byte, offset) - offset = 0 - for _, bs := range bss { - for i, b := range bs { - bytes[offset+i] = b - } - offset += len(bs) - } - return bytes -} - -/* - // infinite loop - code := []byte{0x5B, 0x60, 0x00, 0x56} - // mstore - code := []byte{0x60, 0x00, 0x60, 0x20} - // mstore, mload - code := []byte{0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x20, 0x51} -*/ diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go index e1f9c7e4a6b9f3fa91eea3ce9095ac1314dce716..0cec78a249c48539b88566c722bd7a27cf0b3056 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go @@ -10,6 +10,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" ptypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3" )