Revert "params: core, core/vm, miner: 64bit gas instructions (#3514)"
This reverts commit 8b57c49490.
			
			
This commit is contained in:
		@@ -156,7 +156,7 @@ func run(ctx *cli.Context) error {
 | 
				
			|||||||
		ret, _, err = runtime.Create(input, &runtime.Config{
 | 
							ret, _, err = runtime.Create(input, &runtime.Config{
 | 
				
			||||||
			Origin:   sender.Address(),
 | 
								Origin:   sender.Address(),
 | 
				
			||||||
			State:    statedb,
 | 
								State:    statedb,
 | 
				
			||||||
			GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)).Uint64(),
 | 
								GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
 | 
				
			||||||
			GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
 | 
								GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
 | 
				
			||||||
			Value:    common.Big(ctx.GlobalString(ValueFlag.Name)),
 | 
								Value:    common.Big(ctx.GlobalString(ValueFlag.Name)),
 | 
				
			||||||
			EVMConfig: vm.Config{
 | 
								EVMConfig: vm.Config{
 | 
				
			||||||
@@ -172,7 +172,7 @@ func run(ctx *cli.Context) error {
 | 
				
			|||||||
		ret, err = runtime.Call(receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{
 | 
							ret, err = runtime.Call(receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), &runtime.Config{
 | 
				
			||||||
			Origin:   sender.Address(),
 | 
								Origin:   sender.Address(),
 | 
				
			||||||
			State:    statedb,
 | 
								State:    statedb,
 | 
				
			||||||
			GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)).Uint64(),
 | 
								GasLimit: common.Big(ctx.GlobalString(GasFlag.Name)),
 | 
				
			||||||
			GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
 | 
								GasPrice: common.Big(ctx.GlobalString(PriceFlag.Name)),
 | 
				
			||||||
			Value:    common.Big(ctx.GlobalString(ValueFlag.Name)),
 | 
								Value:    common.Big(ctx.GlobalString(ValueFlag.Name)),
 | 
				
			||||||
			EVMConfig: vm.Config{
 | 
								EVMConfig: vm.Config{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -205,7 +205,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
 | 
							glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if uint64(len(extra)) > params.MaximumExtraDataSize {
 | 
						if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
 | 
				
			||||||
		glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
 | 
							glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
 | 
				
			||||||
		glog.V(logger.Debug).Infof("extra: %x\n", extra)
 | 
							glog.V(logger.Debug).Infof("extra: %x\n", extra)
 | 
				
			||||||
		extra = nil
 | 
							extra = nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,25 +0,0 @@
 | 
				
			|||||||
package math
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import gmath "math"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * NOTE: The following methods need to be optimised using either bit checking or asm
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SafeSub returns subtraction result and whether overflow occurred.
 | 
					 | 
				
			||||||
func SafeSub(x, y uint64) (uint64, bool) {
 | 
					 | 
				
			||||||
	return x - y, x < y
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SafeAdd returns the result and whether overflow occurred.
 | 
					 | 
				
			||||||
func SafeAdd(x, y uint64) (uint64, bool) {
 | 
					 | 
				
			||||||
	return x + y, y > gmath.MaxUint64-x
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SafeMul returns multiplication result and whether overflow occurred.
 | 
					 | 
				
			||||||
func SafeMul(x, y uint64) (uint64, bool) {
 | 
					 | 
				
			||||||
	if x == 0 {
 | 
					 | 
				
			||||||
		return 0, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return x * y, x != 0 && y != 0 && y > gmath.MaxUint64/x
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,50 +0,0 @@
 | 
				
			|||||||
package math
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	gmath "math"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type operation byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	sub operation = iota
 | 
					 | 
				
			||||||
	add
 | 
					 | 
				
			||||||
	mul
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestOverflow(t *testing.T) {
 | 
					 | 
				
			||||||
	for i, test := range []struct {
 | 
					 | 
				
			||||||
		x        uint64
 | 
					 | 
				
			||||||
		y        uint64
 | 
					 | 
				
			||||||
		overflow bool
 | 
					 | 
				
			||||||
		op       operation
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		// add operations
 | 
					 | 
				
			||||||
		{gmath.MaxUint64, 1, true, add},
 | 
					 | 
				
			||||||
		{gmath.MaxUint64 - 1, 1, false, add},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// sub operations
 | 
					 | 
				
			||||||
		{0, 1, true, sub},
 | 
					 | 
				
			||||||
		{0, 0, false, sub},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// mul operations
 | 
					 | 
				
			||||||
		{10, 10, false, mul},
 | 
					 | 
				
			||||||
		{gmath.MaxUint64, 2, true, mul},
 | 
					 | 
				
			||||||
		{gmath.MaxUint64, 1, false, mul},
 | 
					 | 
				
			||||||
	} {
 | 
					 | 
				
			||||||
		var overflows bool
 | 
					 | 
				
			||||||
		switch test.op {
 | 
					 | 
				
			||||||
		case sub:
 | 
					 | 
				
			||||||
			_, overflows = SafeSub(test.x, test.y)
 | 
					 | 
				
			||||||
		case add:
 | 
					 | 
				
			||||||
			_, overflows = SafeAdd(test.x, test.y)
 | 
					 | 
				
			||||||
		case mul:
 | 
					 | 
				
			||||||
			_, overflows = SafeMul(test.x, test.y)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if test.overflow != overflows {
 | 
					 | 
				
			||||||
			t.Errorf("%d failed. Expected test to be %v, got %v", i, test.overflow, overflows)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -92,7 +92,6 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
 | 
				
			|||||||
var (
 | 
					var (
 | 
				
			||||||
	ringKeys  = make([]*ecdsa.PrivateKey, 1000)
 | 
						ringKeys  = make([]*ecdsa.PrivateKey, 1000)
 | 
				
			||||||
	ringAddrs = make([]common.Address, len(ringKeys))
 | 
						ringAddrs = make([]common.Address, len(ringKeys))
 | 
				
			||||||
	bigTxGas  = new(big.Int).SetUint64(params.TxGas)
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
@@ -112,8 +111,8 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
 | 
				
			|||||||
	return func(i int, gen *BlockGen) {
 | 
						return func(i int, gen *BlockGen) {
 | 
				
			||||||
		gas := CalcGasLimit(gen.PrevBlock(i - 1))
 | 
							gas := CalcGasLimit(gen.PrevBlock(i - 1))
 | 
				
			||||||
		for {
 | 
							for {
 | 
				
			||||||
			gas.Sub(gas, bigTxGas)
 | 
								gas.Sub(gas, params.TxGas)
 | 
				
			||||||
			if gas.Cmp(bigTxGas) < 0 {
 | 
								if gas.Cmp(params.TxGas) < 0 {
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			to := (from + 1) % naccounts
 | 
								to := (from + 1) % naccounts
 | 
				
			||||||
@@ -121,7 +120,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
 | 
				
			|||||||
				gen.TxNonce(ringAddrs[from]),
 | 
									gen.TxNonce(ringAddrs[from]),
 | 
				
			||||||
				ringAddrs[to],
 | 
									ringAddrs[to],
 | 
				
			||||||
				benchRootFunds,
 | 
									benchRootFunds,
 | 
				
			||||||
				bigTxGas,
 | 
									params.TxGas,
 | 
				
			||||||
				nil,
 | 
									nil,
 | 
				
			||||||
				nil,
 | 
									nil,
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,7 +204,7 @@ func (v *BlockValidator) ValidateHeader(header, parent *types.Header, checkPow b
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// See YP section 4.3.4. "Block Header Validity"
 | 
					// See YP section 4.3.4. "Block Header Validity"
 | 
				
			||||||
func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
 | 
					func ValidateHeader(config *params.ChainConfig, pow pow.PoW, header *types.Header, parent *types.Header, checkPow, uncle bool) error {
 | 
				
			||||||
	if uint64(len(header.Extra)) > params.MaximumExtraDataSize {
 | 
						if big.NewInt(int64(len(header.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
 | 
				
			||||||
		return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
 | 
							return fmt.Errorf("Header extra data too long (%d)", len(header.Extra))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -719,7 +719,7 @@ func TestFastVsFullChains(t *testing.T) {
 | 
				
			|||||||
		// If the block number is multiple of 3, send a few bonus transactions to the miner
 | 
							// If the block number is multiple of 3, send a few bonus transactions to the miner
 | 
				
			||||||
		if i%3 == 2 {
 | 
							if i%3 == 2 {
 | 
				
			||||||
			for j := 0; j < i%4+1; j++ {
 | 
								for j := 0; j < i%4+1; j++ {
 | 
				
			||||||
				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), bigTxGas, nil, nil), signer, key)
 | 
									tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					panic(err)
 | 
										panic(err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -883,8 +883,8 @@ func TestChainTxReorgs(t *testing.T) {
 | 
				
			|||||||
	// Create two transactions shared between the chains:
 | 
						// Create two transactions shared between the chains:
 | 
				
			||||||
	//  - postponed: transaction included at a later block in the forked chain
 | 
						//  - postponed: transaction included at a later block in the forked chain
 | 
				
			||||||
	//  - swapped: transaction included at the same block number in the forked chain
 | 
						//  - swapped: transaction included at the same block number in the forked chain
 | 
				
			||||||
	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1)
 | 
						postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
 | 
				
			||||||
	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1)
 | 
						swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create two transactions that will be dropped by the forked chain:
 | 
						// Create two transactions that will be dropped by the forked chain:
 | 
				
			||||||
	//  - pastDrop: transaction dropped retroactively from a past block
 | 
						//  - pastDrop: transaction dropped retroactively from a past block
 | 
				
			||||||
@@ -900,13 +900,13 @@ func TestChainTxReorgs(t *testing.T) {
 | 
				
			|||||||
	chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {
 | 
						chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {
 | 
				
			||||||
		switch i {
 | 
							switch i {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2)
 | 
								pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
 | 
								gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
 | 
				
			||||||
			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
 | 
								gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2)
 | 
								freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
 | 
								gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
 | 
				
			||||||
			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
 | 
								gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
 | 
				
			||||||
@@ -925,18 +925,18 @@ func TestChainTxReorgs(t *testing.T) {
 | 
				
			|||||||
	chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 5, func(i int, gen *BlockGen) {
 | 
						chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 5, func(i int, gen *BlockGen) {
 | 
				
			||||||
		switch i {
 | 
							switch i {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
 | 
								pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
 | 
				
			||||||
			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
 | 
								gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
 | 
								gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
 | 
				
			||||||
			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
 | 
								gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
 | 
								freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
 | 
				
			||||||
			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
 | 
								gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case 3:
 | 
							case 3:
 | 
				
			||||||
			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
 | 
								futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
 | 
				
			||||||
			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
 | 
								gen.AddTx(futureAdd) // This transaction will be added after a full reorg
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,13 +56,13 @@ func ExampleGenerateChain() {
 | 
				
			|||||||
		switch i {
 | 
							switch i {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			// In block 1, addr1 sends addr2 some ether.
 | 
								// In block 1, addr1 sends addr2 some ether.
 | 
				
			||||||
			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), bigTxGas, nil, nil), signer, key1)
 | 
								tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
 | 
				
			||||||
			gen.AddTx(tx)
 | 
								gen.AddTx(tx)
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
			// In block 2, addr1 sends some more ether to addr2.
 | 
								// In block 2, addr1 sends some more ether to addr2.
 | 
				
			||||||
			// addr2 passes it on to addr3.
 | 
								// addr2 passes it on to addr3.
 | 
				
			||||||
			tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key1)
 | 
								tx1, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
 | 
				
			||||||
			tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key2)
 | 
								tx2, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
 | 
				
			||||||
			gen.AddTx(tx1)
 | 
								gen.AddTx(tx1)
 | 
				
			||||||
			gen.AddTx(tx2)
 | 
								gen.AddTx(tx2)
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,16 +49,15 @@ The state transitioning model does all all the necessary work to work out a vali
 | 
				
			|||||||
6) Derive new state root
 | 
					6) Derive new state root
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
type StateTransition struct {
 | 
					type StateTransition struct {
 | 
				
			||||||
	gp         *GasPool
 | 
						gp            *GasPool
 | 
				
			||||||
	msg        Message
 | 
						msg           Message
 | 
				
			||||||
	gas        uint64
 | 
						gas, gasPrice *big.Int
 | 
				
			||||||
	gasPrice   *big.Int
 | 
						initialGas    *big.Int
 | 
				
			||||||
	initialGas *big.Int
 | 
						value         *big.Int
 | 
				
			||||||
	value      *big.Int
 | 
						data          []byte
 | 
				
			||||||
	data       []byte
 | 
						state         vm.StateDB
 | 
				
			||||||
	state      vm.StateDB
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	evm *vm.EVM
 | 
						env *vm.EVM
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Message represents a message sent to a contract.
 | 
					// Message represents a message sent to a contract.
 | 
				
			||||||
@@ -82,14 +81,12 @@ func MessageCreatesContract(msg Message) bool {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// IntrinsicGas computes the 'intrinsic gas' for a message
 | 
					// IntrinsicGas computes the 'intrinsic gas' for a message
 | 
				
			||||||
// with the given data.
 | 
					// with the given data.
 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// TODO convert to uint64
 | 
					 | 
				
			||||||
func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
 | 
					func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
 | 
				
			||||||
	igas := new(big.Int)
 | 
						igas := new(big.Int)
 | 
				
			||||||
	if contractCreation && homestead {
 | 
						if contractCreation && homestead {
 | 
				
			||||||
		igas.SetUint64(params.TxGasContractCreation)
 | 
							igas.Set(params.TxGasContractCreation)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		igas.SetUint64(params.TxGas)
 | 
							igas.Set(params.TxGas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(data) > 0 {
 | 
						if len(data) > 0 {
 | 
				
			||||||
		var nz int64
 | 
							var nz int64
 | 
				
			||||||
@@ -99,26 +96,27 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) *big.Int {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		m := big.NewInt(nz)
 | 
							m := big.NewInt(nz)
 | 
				
			||||||
		m.Mul(m, new(big.Int).SetUint64(params.TxDataNonZeroGas))
 | 
							m.Mul(m, params.TxDataNonZeroGas)
 | 
				
			||||||
		igas.Add(igas, m)
 | 
							igas.Add(igas, m)
 | 
				
			||||||
		m.SetInt64(int64(len(data)) - nz)
 | 
							m.SetInt64(int64(len(data)) - nz)
 | 
				
			||||||
		m.Mul(m, new(big.Int).SetUint64(params.TxDataZeroGas))
 | 
							m.Mul(m, params.TxDataZeroGas)
 | 
				
			||||||
		igas.Add(igas, m)
 | 
							igas.Add(igas, m)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return igas
 | 
						return igas
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewStateTransition initialises and returns a new state transition object.
 | 
					// NewStateTransition initialises and returns a new state transition object.
 | 
				
			||||||
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
 | 
					func NewStateTransition(env *vm.EVM, msg Message, gp *GasPool) *StateTransition {
 | 
				
			||||||
	return &StateTransition{
 | 
						return &StateTransition{
 | 
				
			||||||
		gp:         gp,
 | 
							gp:         gp,
 | 
				
			||||||
		evm:        evm,
 | 
							env:        env,
 | 
				
			||||||
		msg:        msg,
 | 
							msg:        msg,
 | 
				
			||||||
 | 
							gas:        new(big.Int),
 | 
				
			||||||
		gasPrice:   msg.GasPrice(),
 | 
							gasPrice:   msg.GasPrice(),
 | 
				
			||||||
		initialGas: new(big.Int),
 | 
							initialGas: new(big.Int),
 | 
				
			||||||
		value:      msg.Value(),
 | 
							value:      msg.Value(),
 | 
				
			||||||
		data:       msg.Data(),
 | 
							data:       msg.Data(),
 | 
				
			||||||
		state:      evm.StateDB,
 | 
							state:      env.StateDB,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -129,8 +127,8 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
 | 
				
			|||||||
// the gas used (which includes gas refunds) and an error if it failed. An error always
 | 
					// the gas used (which includes gas refunds) and an error if it failed. An error always
 | 
				
			||||||
// indicates a core error meaning that the message would always fail for that particular
 | 
					// indicates a core error meaning that the message would always fail for that particular
 | 
				
			||||||
// state and would never be accepted within a block.
 | 
					// state and would never be accepted within a block.
 | 
				
			||||||
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
 | 
					func ApplyMessage(env *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) {
 | 
				
			||||||
	st := NewStateTransition(evm, msg, gp)
 | 
						st := NewStateTransition(env, msg, gp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, _, gasUsed, err := st.TransitionDb()
 | 
						ret, _, gasUsed, err := st.TransitionDb()
 | 
				
			||||||
	return ret, gasUsed, err
 | 
						return ret, gasUsed, err
 | 
				
			||||||
@@ -159,21 +157,21 @@ func (self *StateTransition) to() vm.Account {
 | 
				
			|||||||
	return self.state.GetAccount(*to)
 | 
						return self.state.GetAccount(*to)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (self *StateTransition) useGas(amount uint64) error {
 | 
					func (self *StateTransition) useGas(amount *big.Int) error {
 | 
				
			||||||
	if self.gas < amount {
 | 
						if self.gas.Cmp(amount) < 0 {
 | 
				
			||||||
		return vm.ErrOutOfGas
 | 
							return vm.ErrOutOfGas
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	self.gas -= amount
 | 
						self.gas.Sub(self.gas, amount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *StateTransition) addGas(amount *big.Int) {
 | 
				
			||||||
 | 
						self.gas.Add(self.gas, amount)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (self *StateTransition) buyGas() error {
 | 
					func (self *StateTransition) buyGas() error {
 | 
				
			||||||
	mgas := self.msg.Gas()
 | 
						mgas := self.msg.Gas()
 | 
				
			||||||
	if mgas.BitLen() > 64 {
 | 
					 | 
				
			||||||
		return vm.ErrOutOfGas
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mgval := new(big.Int).Mul(mgas, self.gasPrice)
 | 
						mgval := new(big.Int).Mul(mgas, self.gasPrice)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sender := self.from()
 | 
						sender := self.from()
 | 
				
			||||||
@@ -183,8 +181,7 @@ func (self *StateTransition) buyGas() error {
 | 
				
			|||||||
	if err := self.gp.SubGas(mgas); err != nil {
 | 
						if err := self.gp.SubGas(mgas); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	self.gas += mgas.Uint64()
 | 
						self.addGas(mgas)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	self.initialGas.Set(mgas)
 | 
						self.initialGas.Set(mgas)
 | 
				
			||||||
	sender.SubBalance(mgval)
 | 
						sender.SubBalance(mgval)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -212,9 +209,7 @@ func (self *StateTransition) preCheck() (err error) {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TransitionDb will transition the state by applying the current message and returning the result
 | 
					// TransitionDb will move the state by applying the message against the given environment.
 | 
				
			||||||
// including the required gas for the operation as well as the used gas. It returns an error if it
 | 
					 | 
				
			||||||
// failed. An error indicates a consensus issue.
 | 
					 | 
				
			||||||
func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) {
 | 
					func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) {
 | 
				
			||||||
	if err = self.preCheck(); err != nil {
 | 
						if err = self.preCheck(); err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -222,32 +217,26 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
 | 
				
			|||||||
	msg := self.msg
 | 
						msg := self.msg
 | 
				
			||||||
	sender := self.from() // err checked in preCheck
 | 
						sender := self.from() // err checked in preCheck
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	homestead := self.evm.ChainConfig().IsHomestead(self.evm.BlockNumber)
 | 
						homestead := self.env.ChainConfig().IsHomestead(self.env.BlockNumber)
 | 
				
			||||||
	contractCreation := MessageCreatesContract(msg)
 | 
						contractCreation := MessageCreatesContract(msg)
 | 
				
			||||||
	// Pay intrinsic gas
 | 
						// Pay intrinsic gas
 | 
				
			||||||
	// TODO convert to uint64
 | 
						if err = self.useGas(IntrinsicGas(self.data, contractCreation, homestead)); err != nil {
 | 
				
			||||||
	intrinsicGas := IntrinsicGas(self.data, contractCreation, homestead)
 | 
					 | 
				
			||||||
	if intrinsicGas.BitLen() > 64 {
 | 
					 | 
				
			||||||
		return nil, nil, nil, InvalidTxError(vm.ErrOutOfGas)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err = self.useGas(intrinsicGas.Uint64()); err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, InvalidTxError(err)
 | 
							return nil, nil, nil, InvalidTxError(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		evm = self.evm
 | 
							vmenv = self.env
 | 
				
			||||||
		// vm errors do not effect consensus and are therefor
 | 
							// vm errors do not effect consensus and are therefor
 | 
				
			||||||
		// not assigned to err, except for insufficient balance
 | 
							// not assigned to err, except for insufficient balance
 | 
				
			||||||
		// error.
 | 
							// error.
 | 
				
			||||||
		vmerr error
 | 
							vmerr error
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if contractCreation {
 | 
						if contractCreation {
 | 
				
			||||||
		ret, _, self.gas, vmerr = evm.Create(sender, self.data, self.gas, self.value)
 | 
							ret, _, vmerr = vmenv.Create(sender, self.data, self.gas, self.value)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Increment the nonce for the next transaction
 | 
							// Increment the nonce for the next transaction
 | 
				
			||||||
		self.state.SetNonce(sender.Address(), self.state.GetNonce(sender.Address())+1)
 | 
							self.state.SetNonce(sender.Address(), self.state.GetNonce(sender.Address())+1)
 | 
				
			||||||
		ret, self.gas, vmerr = evm.Call(sender, self.to().Address(), self.data, self.gas, self.value)
 | 
							ret, vmerr = vmenv.Call(sender, self.to().Address(), self.data, self.gas, self.value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if vmerr != nil {
 | 
						if vmerr != nil {
 | 
				
			||||||
		glog.V(logger.Core).Infoln("vm returned with error:", err)
 | 
							glog.V(logger.Core).Infoln("vm returned with error:", err)
 | 
				
			||||||
@@ -262,7 +251,7 @@ func (self *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *b
 | 
				
			|||||||
	requiredGas = new(big.Int).Set(self.gasUsed())
 | 
						requiredGas = new(big.Int).Set(self.gasUsed())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	self.refundGas()
 | 
						self.refundGas()
 | 
				
			||||||
	self.state.AddBalance(self.evm.Coinbase, new(big.Int).Mul(self.gasUsed(), self.gasPrice))
 | 
						self.state.AddBalance(self.env.Coinbase, new(big.Int).Mul(self.gasUsed(), self.gasPrice))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret, requiredGas, self.gasUsed(), err
 | 
						return ret, requiredGas, self.gasUsed(), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -271,21 +260,20 @@ func (self *StateTransition) refundGas() {
 | 
				
			|||||||
	// Return eth for remaining gas to the sender account,
 | 
						// Return eth for remaining gas to the sender account,
 | 
				
			||||||
	// exchanged at the original rate.
 | 
						// exchanged at the original rate.
 | 
				
			||||||
	sender := self.from() // err already checked
 | 
						sender := self.from() // err already checked
 | 
				
			||||||
	remaining := new(big.Int).Mul(new(big.Int).SetUint64(self.gas), self.gasPrice)
 | 
						remaining := new(big.Int).Mul(self.gas, self.gasPrice)
 | 
				
			||||||
	sender.AddBalance(remaining)
 | 
						sender.AddBalance(remaining)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Apply refund counter, capped to half of the used gas.
 | 
						// Apply refund counter, capped to half of the used gas.
 | 
				
			||||||
	uhalf := remaining.Div(self.gasUsed(), common.Big2)
 | 
						uhalf := remaining.Div(self.gasUsed(), common.Big2)
 | 
				
			||||||
	refund := common.BigMin(uhalf, self.state.GetRefund())
 | 
						refund := common.BigMin(uhalf, self.state.GetRefund())
 | 
				
			||||||
	self.gas += refund.Uint64()
 | 
						self.gas.Add(self.gas, refund)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	self.state.AddBalance(sender.Address(), refund.Mul(refund, self.gasPrice))
 | 
						self.state.AddBalance(sender.Address(), refund.Mul(refund, self.gasPrice))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Also return remaining gas to the block gas counter so it is
 | 
						// Also return remaining gas to the block gas counter so it is
 | 
				
			||||||
	// available for the next transaction.
 | 
						// available for the next transaction.
 | 
				
			||||||
	self.gp.AddGas(new(big.Int).SetUint64(self.gas))
 | 
						self.gp.AddGas(self.gas)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (self *StateTransition) gasUsed() *big.Int {
 | 
					func (self *StateTransition) gasUsed() *big.Int {
 | 
				
			||||||
	return new(big.Int).Sub(self.initialGas, new(big.Int).SetUint64(self.gas))
 | 
						return new(big.Int).Sub(self.initialGas, self.gas)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,11 +21,28 @@ import (
 | 
				
			|||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Type is the VM type accepted by **NewVm**
 | 
				
			||||||
 | 
					type Type byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						StdVmTy Type = iota // Default standard VM
 | 
				
			||||||
 | 
						JitVmTy             // LLVM JIT VM
 | 
				
			||||||
 | 
						MaxVmTy
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
 | 
						Pow256 = common.BigPow(2, 256) // Pow256 is 2**256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	U256 = common.U256 // Shortcut to common.U256
 | 
						U256 = common.U256 // Shortcut to common.U256
 | 
				
			||||||
	S256 = common.S256 // Shortcut to common.S256
 | 
						S256 = common.S256 // Shortcut to common.S256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Zero = common.Big0 // Shortcut to common.Big0
 | 
				
			||||||
 | 
						One  = common.Big1 // Shortcut to common.Big1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						max = big.NewInt(math.MaxInt64) // Maximum 64 bit integer
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// calculates the memory size required for a step
 | 
					// calculates the memory size required for a step
 | 
				
			||||||
@@ -37,6 +54,48 @@ func calcMemSize(off, l *big.Int) *big.Int {
 | 
				
			|||||||
	return new(big.Int).Add(off, l)
 | 
						return new(big.Int).Add(off, l)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// calculates the quadratic gas
 | 
				
			||||||
 | 
					func quadMemGas(mem *Memory, newMemSize, gas *big.Int) {
 | 
				
			||||||
 | 
						if newMemSize.Cmp(common.Big0) > 0 {
 | 
				
			||||||
 | 
							newMemSizeWords := toWordSize(newMemSize)
 | 
				
			||||||
 | 
							newMemSize.Mul(newMemSizeWords, u256(32))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
 | 
				
			||||||
 | 
								// be careful reusing variables here when changing.
 | 
				
			||||||
 | 
								// The order has been optimised to reduce allocation
 | 
				
			||||||
 | 
								oldSize := toWordSize(big.NewInt(int64(mem.Len())))
 | 
				
			||||||
 | 
								pow := new(big.Int).Exp(oldSize, common.Big2, Zero)
 | 
				
			||||||
 | 
								linCoef := oldSize.Mul(oldSize, params.MemoryGas)
 | 
				
			||||||
 | 
								quadCoef := new(big.Int).Div(pow, params.QuadCoeffDiv)
 | 
				
			||||||
 | 
								oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								pow.Exp(newMemSizeWords, common.Big2, Zero)
 | 
				
			||||||
 | 
								linCoef = linCoef.Mul(newMemSizeWords, params.MemoryGas)
 | 
				
			||||||
 | 
								quadCoef = quadCoef.Div(pow, params.QuadCoeffDiv)
 | 
				
			||||||
 | 
								newTotalFee := linCoef.Add(linCoef, quadCoef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fee := newTotalFee.Sub(newTotalFee, oldTotalFee)
 | 
				
			||||||
 | 
								gas.Add(gas, fee)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Simple helper
 | 
				
			||||||
 | 
					func u256(n int64) *big.Int {
 | 
				
			||||||
 | 
						return big.NewInt(n)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mainly used for print variables and passing to Print*
 | 
				
			||||||
 | 
					func toValue(val *big.Int) interface{} {
 | 
				
			||||||
 | 
						// Let's assume a string on right padded zero's
 | 
				
			||||||
 | 
						b := val.Bytes()
 | 
				
			||||||
 | 
						if b[0] != 0 && b[len(b)-1] == 0x0 && b[len(b)-2] == 0x0 {
 | 
				
			||||||
 | 
							return string(b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return val
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// getData returns a slice from the data based on the start and size and pads
 | 
					// getData returns a slice from the data based on the start and size and pads
 | 
				
			||||||
// up to size with zero's. This function is overflow safe.
 | 
					// up to size with zero's. This function is overflow safe.
 | 
				
			||||||
func getData(data []byte, start, size *big.Int) []byte {
 | 
					func getData(data []byte, start, size *big.Int) []byte {
 | 
				
			||||||
@@ -47,17 +106,14 @@ func getData(data []byte, start, size *big.Int) []byte {
 | 
				
			|||||||
	return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64()))
 | 
						return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64()))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// bigUint64 returns the integer casted to a uint64 and returns whether it
 | 
					// useGas attempts to subtract the amount of gas and returns whether it was
 | 
				
			||||||
// overflowed in the process.
 | 
					// successful
 | 
				
			||||||
func bigUint64(v *big.Int) (uint64, bool) {
 | 
					func useGas(gas, amount *big.Int) bool {
 | 
				
			||||||
	return v.Uint64(), v.BitLen() > 64
 | 
						if gas.Cmp(amount) < 0 {
 | 
				
			||||||
}
 | 
							return false
 | 
				
			||||||
 | 
					 | 
				
			||||||
// toWordSize returns the ceiled word size required for memory expansion.
 | 
					 | 
				
			||||||
func toWordSize(size uint64) uint64 {
 | 
					 | 
				
			||||||
	if size > math.MaxUint64-31 {
 | 
					 | 
				
			||||||
		return math.MaxUint64/32 + 1
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (size + 31) / 32
 | 
						// Sub the amount of gas from the remaining
 | 
				
			||||||
 | 
						gas.Sub(gas, amount)
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ContractRef is a reference to the contract's backing object
 | 
					// ContractRef is a reference to the contract's backing object
 | 
				
			||||||
type ContractRef interface {
 | 
					type ContractRef interface {
 | 
				
			||||||
 | 
						ReturnGas(*big.Int)
 | 
				
			||||||
	Address() common.Address
 | 
						Address() common.Address
 | 
				
			||||||
	Value() *big.Int
 | 
						Value() *big.Int
 | 
				
			||||||
	SetCode(common.Hash, []byte)
 | 
						SetCode(common.Hash, []byte)
 | 
				
			||||||
@@ -47,8 +48,7 @@ type Contract struct {
 | 
				
			|||||||
	CodeAddr *common.Address
 | 
						CodeAddr *common.Address
 | 
				
			||||||
	Input    []byte
 | 
						Input    []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Gas   uint64
 | 
						value, Gas, UsedGas *big.Int
 | 
				
			||||||
	value *big.Int
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Args []byte
 | 
						Args []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -56,7 +56,7 @@ type Contract struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewContract returns a new contract environment for the execution of EVM.
 | 
					// NewContract returns a new contract environment for the execution of EVM.
 | 
				
			||||||
func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uint64) *Contract {
 | 
					func NewContract(caller ContractRef, object ContractRef, value, gas *big.Int) *Contract {
 | 
				
			||||||
	c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
 | 
						c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object, Args: nil}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if parent, ok := caller.(*Contract); ok {
 | 
						if parent, ok := caller.(*Contract); ok {
 | 
				
			||||||
@@ -68,8 +68,9 @@ func NewContract(caller ContractRef, object ContractRef, value *big.Int, gas uin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Gas should be a pointer so it can safely be reduced through the run
 | 
						// Gas should be a pointer so it can safely be reduced through the run
 | 
				
			||||||
	// This pointer will be off the state transition
 | 
						// This pointer will be off the state transition
 | 
				
			||||||
	c.Gas = gas
 | 
						c.Gas = gas //new(big.Int).Set(gas)
 | 
				
			||||||
	c.value = new(big.Int).Set(value)
 | 
						c.value = new(big.Int).Set(value)
 | 
				
			||||||
 | 
						c.UsedGas = new(big.Int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c
 | 
						return c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -106,13 +107,27 @@ func (c *Contract) Caller() common.Address {
 | 
				
			|||||||
	return c.CallerAddress
 | 
						return c.CallerAddress
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Finalise finalises the contract and returning any remaining gas to the original
 | 
				
			||||||
 | 
					// caller.
 | 
				
			||||||
 | 
					func (c *Contract) Finalise() {
 | 
				
			||||||
 | 
						// Return the remaining gas to the caller
 | 
				
			||||||
 | 
						c.caller.ReturnGas(c.Gas)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UseGas attempts the use gas and subtracts it and returns true on success
 | 
					// UseGas attempts the use gas and subtracts it and returns true on success
 | 
				
			||||||
func (c *Contract) UseGas(gas uint64) (ok bool) {
 | 
					func (c *Contract) UseGas(gas *big.Int) (ok bool) {
 | 
				
			||||||
	if c.Gas < gas {
 | 
						ok = useGas(c.Gas, gas)
 | 
				
			||||||
		return false
 | 
						if ok {
 | 
				
			||||||
 | 
							c.UsedGas.Add(c.UsedGas, gas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.Gas -= gas
 | 
						return
 | 
				
			||||||
	return true
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReturnGas adds the given gas back to itself.
 | 
				
			||||||
 | 
					func (c *Contract) ReturnGas(gas *big.Int) {
 | 
				
			||||||
 | 
						// Return the gas to the context
 | 
				
			||||||
 | 
						c.Gas.Add(c.Gas, gas)
 | 
				
			||||||
 | 
						c.UsedGas.Sub(c.UsedGas, gas)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Address returns the contracts address
 | 
					// Address returns the contracts address
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,8 @@
 | 
				
			|||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/crypto"
 | 
						"github.com/ethereum/go-ethereum/crypto"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/logger"
 | 
						"github.com/ethereum/go-ethereum/logger"
 | 
				
			||||||
@@ -28,8 +30,8 @@ import (
 | 
				
			|||||||
// requires a deterministic gas count based on the input size of the Run method of the
 | 
					// requires a deterministic gas count based on the input size of the Run method of the
 | 
				
			||||||
// contract.
 | 
					// contract.
 | 
				
			||||||
type PrecompiledContract interface {
 | 
					type PrecompiledContract interface {
 | 
				
			||||||
	RequiredGas(inputSize int) uint64 // RequiredPrice calculates the contract gas use
 | 
						RequiredGas(inputSize int) *big.Int // RequiredPrice calculates the contract gas use
 | 
				
			||||||
	Run(input []byte) []byte          // Run runs the precompiled contract
 | 
						Run(input []byte) []byte            // Run runs the precompiled contract
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Precompiled contains the default set of ethereum contracts
 | 
					// Precompiled contains the default set of ethereum contracts
 | 
				
			||||||
@@ -55,7 +57,7 @@ func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contr
 | 
				
			|||||||
// ECRECOVER implemented as a native contract
 | 
					// ECRECOVER implemented as a native contract
 | 
				
			||||||
type ecrecover struct{}
 | 
					type ecrecover struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *ecrecover) RequiredGas(inputSize int) uint64 {
 | 
					func (c *ecrecover) RequiredGas(inputSize int) *big.Int {
 | 
				
			||||||
	return params.EcrecoverGas
 | 
						return params.EcrecoverGas
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,12 +92,10 @@ func (c *ecrecover) Run(in []byte) []byte {
 | 
				
			|||||||
// SHA256 implemented as a native contract
 | 
					// SHA256 implemented as a native contract
 | 
				
			||||||
type sha256 struct{}
 | 
					type sha256 struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
 | 
					func (c *sha256) RequiredGas(inputSize int) *big.Int {
 | 
				
			||||||
//
 | 
						n := big.NewInt(int64(inputSize+31) / 32)
 | 
				
			||||||
// This method does not require any overflow checking as the input size gas costs
 | 
						n.Mul(n, params.Sha256WordGas)
 | 
				
			||||||
// required for anything significant is so high it's impossible to pay for.
 | 
						return n.Add(n, params.Sha256Gas)
 | 
				
			||||||
func (c *sha256) RequiredGas(inputSize int) uint64 {
 | 
					 | 
				
			||||||
	return uint64(inputSize+31)/32*params.Sha256WordGas + params.Sha256Gas
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (c *sha256) Run(in []byte) []byte {
 | 
					func (c *sha256) Run(in []byte) []byte {
 | 
				
			||||||
	return crypto.Sha256(in)
 | 
						return crypto.Sha256(in)
 | 
				
			||||||
@@ -104,12 +104,10 @@ func (c *sha256) Run(in []byte) []byte {
 | 
				
			|||||||
// RIPMED160 implemented as a native contract
 | 
					// RIPMED160 implemented as a native contract
 | 
				
			||||||
type ripemd160 struct{}
 | 
					type ripemd160 struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
 | 
					func (c *ripemd160) RequiredGas(inputSize int) *big.Int {
 | 
				
			||||||
//
 | 
						n := big.NewInt(int64(inputSize+31) / 32)
 | 
				
			||||||
// This method does not require any overflow checking as the input size gas costs
 | 
						n.Mul(n, params.Ripemd160WordGas)
 | 
				
			||||||
// required for anything significant is so high it's impossible to pay for.
 | 
						return n.Add(n, params.Ripemd160Gas)
 | 
				
			||||||
func (c *ripemd160) RequiredGas(inputSize int) uint64 {
 | 
					 | 
				
			||||||
	return uint64(inputSize+31)/32*params.Ripemd160WordGas + params.Ripemd160Gas
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (c *ripemd160) Run(in []byte) []byte {
 | 
					func (c *ripemd160) Run(in []byte) []byte {
 | 
				
			||||||
	return common.LeftPadBytes(crypto.Ripemd160(in), 32)
 | 
						return common.LeftPadBytes(crypto.Ripemd160(in), 32)
 | 
				
			||||||
@@ -118,12 +116,11 @@ func (c *ripemd160) Run(in []byte) []byte {
 | 
				
			|||||||
// data copy implemented as a native contract
 | 
					// data copy implemented as a native contract
 | 
				
			||||||
type dataCopy struct{}
 | 
					type dataCopy struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RequiredGas returns the gas required to execute the pre-compiled contract.
 | 
					func (c *dataCopy) RequiredGas(inputSize int) *big.Int {
 | 
				
			||||||
//
 | 
						n := big.NewInt(int64(inputSize+31) / 32)
 | 
				
			||||||
// This method does not require any overflow checking as the input size gas costs
 | 
						n.Mul(n, params.IdentityWordGas)
 | 
				
			||||||
// required for anything significant is so high it's impossible to pay for.
 | 
					
 | 
				
			||||||
func (c *dataCopy) RequiredGas(inputSize int) uint64 {
 | 
						return n.Add(n, params.IdentityGas)
 | 
				
			||||||
	return uint64(inputSize+31)/32*params.IdentityWordGas + params.IdentityGas
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (c *dataCopy) Run(in []byte) []byte {
 | 
					func (c *dataCopy) Run(in []byte) []byte {
 | 
				
			||||||
	return in
 | 
						return in
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -101,18 +102,24 @@ func (evm *EVM) Cancel() {
 | 
				
			|||||||
// Call executes the contract associated with the addr with the given input as parameters. It also handles any
 | 
					// Call executes the contract associated with the addr with the given input as parameters. It also handles any
 | 
				
			||||||
// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
 | 
					// necessary value transfer required and takes the necessary steps to create accounts and reverses the state in
 | 
				
			||||||
// case of an execution error or failed value transfer.
 | 
					// case of an execution error or failed value transfer.
 | 
				
			||||||
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
 | 
					func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
 | 
				
			||||||
	if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
						if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
				
			||||||
		return nil, gas, nil
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Depth check execution. Fail if we're trying to execute above the
 | 
						// Depth check execution. Fail if we're trying to execute above the
 | 
				
			||||||
	// limit.
 | 
						// limit.
 | 
				
			||||||
	if evm.depth > int(params.CallCreateDepth) {
 | 
						if evm.depth > int(params.CallCreateDepth.Int64()) {
 | 
				
			||||||
		return nil, gas, ErrDepth
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, ErrDepth
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
						if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
				
			||||||
		return nil, gas, ErrInsufficientBalance
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, ErrInsufficientBalance
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -121,7 +128,8 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
	if !evm.StateDB.Exist(addr) {
 | 
						if !evm.StateDB.Exist(addr) {
 | 
				
			||||||
		if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.BitLen() == 0 {
 | 
							if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.BitLen() == 0 {
 | 
				
			||||||
			return nil, gas, nil
 | 
								caller.ReturnGas(gas)
 | 
				
			||||||
 | 
								return nil, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		to = evm.StateDB.CreateAccount(addr)
 | 
							to = evm.StateDB.CreateAccount(addr)
 | 
				
			||||||
@@ -135,6 +143,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 | 
				
			|||||||
	// only.
 | 
						// only.
 | 
				
			||||||
	contract := NewContract(caller, to, value, gas)
 | 
						contract := NewContract(caller, to, value, gas)
 | 
				
			||||||
	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
						contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
				
			||||||
 | 
						defer contract.Finalise()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, err = evm.interpreter.Run(contract, input)
 | 
						ret, err = evm.interpreter.Run(contract, input)
 | 
				
			||||||
	// When an error was returned by the EVM or when setting the creation code
 | 
						// When an error was returned by the EVM or when setting the creation code
 | 
				
			||||||
@@ -145,7 +154,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		evm.StateDB.RevertToSnapshot(snapshot)
 | 
							evm.StateDB.RevertToSnapshot(snapshot)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret, contract.Gas, err
 | 
						return ret, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CallCode executes the contract associated with the addr with the given input as parameters. It also handles any
 | 
					// CallCode executes the contract associated with the addr with the given input as parameters. It also handles any
 | 
				
			||||||
@@ -153,18 +162,24 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
 | 
				
			|||||||
// case of an execution error or failed value transfer.
 | 
					// case of an execution error or failed value transfer.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
 | 
					// CallCode differs from Call in the sense that it executes the given address' code with the caller as context.
 | 
				
			||||||
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
 | 
					func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas, value *big.Int) (ret []byte, err error) {
 | 
				
			||||||
	if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
						if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
				
			||||||
		return nil, gas, nil
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Depth check execution. Fail if we're trying to execute above the
 | 
						// Depth check execution. Fail if we're trying to execute above the
 | 
				
			||||||
	// limit.
 | 
						// limit.
 | 
				
			||||||
	if evm.depth > int(params.CallCreateDepth) {
 | 
						if evm.depth > int(params.CallCreateDepth.Int64()) {
 | 
				
			||||||
		return nil, gas, ErrDepth
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, ErrDepth
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
						if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
				
			||||||
		return nil, gas, ErrInsufficientBalance
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("insufficient funds to transfer value. Req %v, has %v", value, evm.StateDB.GetBalance(caller.Address()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -176,6 +191,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 | 
				
			|||||||
	// only.
 | 
						// only.
 | 
				
			||||||
	contract := NewContract(caller, to, value, gas)
 | 
						contract := NewContract(caller, to, value, gas)
 | 
				
			||||||
	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
						contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
				
			||||||
 | 
						defer contract.Finalise()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, err = evm.interpreter.Run(contract, input)
 | 
						ret, err = evm.interpreter.Run(contract, input)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -184,7 +200,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 | 
				
			|||||||
		evm.StateDB.RevertToSnapshot(snapshot)
 | 
							evm.StateDB.RevertToSnapshot(snapshot)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret, contract.Gas, err
 | 
						return ret, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DelegateCall executes the contract associated with the addr with the given input as parameters.
 | 
					// DelegateCall executes the contract associated with the addr with the given input as parameters.
 | 
				
			||||||
@@ -192,15 +208,18 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
 | 
					// DelegateCall differs from CallCode in the sense that it executes the given address' code with the caller as context
 | 
				
			||||||
// and the caller is set to the caller of the caller.
 | 
					// and the caller is set to the caller of the caller.
 | 
				
			||||||
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
 | 
					func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas *big.Int) (ret []byte, err error) {
 | 
				
			||||||
	if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
						if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
				
			||||||
		return nil, gas, nil
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Depth check execution. Fail if we're trying to execute above the
 | 
						// Depth check execution. Fail if we're trying to execute above the
 | 
				
			||||||
	// limit.
 | 
						// limit.
 | 
				
			||||||
	if evm.depth > int(params.CallCreateDepth) {
 | 
						if evm.depth > int(params.CallCreateDepth.Int64()) {
 | 
				
			||||||
		return nil, gas, ErrDepth
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
							return nil, ErrDepth
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -211,6 +230,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
 | 
				
			|||||||
	// Iinitialise a new contract and make initialise the delegate values
 | 
						// Iinitialise a new contract and make initialise the delegate values
 | 
				
			||||||
	contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
 | 
						contract := NewContract(caller, to, caller.Value(), gas).AsDelegate()
 | 
				
			||||||
	contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
						contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
 | 
				
			||||||
 | 
						defer contract.Finalise()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, err = evm.interpreter.Run(contract, input)
 | 
						ret, err = evm.interpreter.Run(contract, input)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -219,22 +239,28 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
 | 
				
			|||||||
		evm.StateDB.RevertToSnapshot(snapshot)
 | 
							evm.StateDB.RevertToSnapshot(snapshot)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret, contract.Gas, err
 | 
						return ret, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create creates a new contract using code as deployment code.
 | 
					// Create creates a new contract using code as deployment code.
 | 
				
			||||||
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
 | 
					func (evm *EVM) Create(caller ContractRef, code []byte, gas, value *big.Int) (ret []byte, contractAddr common.Address, err error) {
 | 
				
			||||||
	if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
						if evm.vmConfig.NoRecursion && evm.depth > 0 {
 | 
				
			||||||
		return nil, common.Address{}, gas, nil
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, common.Address{}, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Depth check execution. Fail if we're trying to execute above the
 | 
						// Depth check execution. Fail if we're trying to execute above the
 | 
				
			||||||
	// limit.
 | 
						// limit.
 | 
				
			||||||
	if evm.depth > int(params.CallCreateDepth) {
 | 
						if evm.depth > int(params.CallCreateDepth.Int64()) {
 | 
				
			||||||
		return nil, common.Address{}, gas, ErrDepth
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, common.Address{}, ErrDepth
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
						if !evm.CanTransfer(evm.StateDB, caller.Address(), value) {
 | 
				
			||||||
		return nil, common.Address{}, gas, ErrInsufficientBalance
 | 
							caller.ReturnGas(gas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil, common.Address{}, ErrInsufficientBalance
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create a new account on the state
 | 
						// Create a new account on the state
 | 
				
			||||||
@@ -254,6 +280,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
 | 
				
			|||||||
	// only.
 | 
						// only.
 | 
				
			||||||
	contract := NewContract(caller, to, value, gas)
 | 
						contract := NewContract(caller, to, value, gas)
 | 
				
			||||||
	contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
 | 
						contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)
 | 
				
			||||||
 | 
						defer contract.Finalise()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, err = evm.interpreter.Run(contract, nil)
 | 
						ret, err = evm.interpreter.Run(contract, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -264,8 +291,9 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
 | 
				
			|||||||
	// be stored due to not enough gas set an error and let it be handled
 | 
						// be stored due to not enough gas set an error and let it be handled
 | 
				
			||||||
	// by the error checking condition below.
 | 
						// by the error checking condition below.
 | 
				
			||||||
	if err == nil && !maxCodeSizeExceeded {
 | 
						if err == nil && !maxCodeSizeExceeded {
 | 
				
			||||||
		createDataGas := uint64(len(ret)) * params.CreateDataGas
 | 
							dataGas := big.NewInt(int64(len(ret)))
 | 
				
			||||||
		if contract.UseGas(createDataGas) {
 | 
							dataGas.Mul(dataGas, params.CreateDataGas)
 | 
				
			||||||
 | 
							if contract.UseGas(dataGas) {
 | 
				
			||||||
			evm.StateDB.SetCode(contractAddr, ret)
 | 
								evm.StateDB.SetCode(contractAddr, ret)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			err = ErrCodeStoreOutOfGas
 | 
								err = ErrCodeStoreOutOfGas
 | 
				
			||||||
@@ -277,10 +305,11 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
 | 
				
			|||||||
	// when we're in homestead this also counts for code storage gas errors.
 | 
						// when we're in homestead this also counts for code storage gas errors.
 | 
				
			||||||
	if maxCodeSizeExceeded ||
 | 
						if maxCodeSizeExceeded ||
 | 
				
			||||||
		(err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
 | 
							(err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
 | 
				
			||||||
 | 
							contract.UseGas(contract.Gas)
 | 
				
			||||||
		evm.StateDB.RevertToSnapshot(snapshot)
 | 
							evm.StateDB.RevertToSnapshot(snapshot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Nothing should be returned when an error is thrown.
 | 
							// Nothing should be returned when an error is thrown.
 | 
				
			||||||
		return nil, contractAddr, 0, err
 | 
							return nil, contractAddr, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// If the vm returned with an error the return value should be set to nil.
 | 
						// If the vm returned with an error the return value should be set to nil.
 | 
				
			||||||
	// This isn't consensus critical but merely to for behaviour reasons such as
 | 
						// This isn't consensus critical but merely to for behaviour reasons such as
 | 
				
			||||||
@@ -289,7 +318,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I
 | 
				
			|||||||
		ret = nil
 | 
							ret = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret, contractAddr, contract.Gas, err
 | 
						return ret, contractAddr, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChainConfig returns the evmironment's chain configuration
 | 
					// ChainConfig returns the evmironment's chain configuration
 | 
				
			||||||
							
								
								
									
										151
									
								
								core/vm/gas.go
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								core/vm/gas.go
									
									
									
									
									
								
							@@ -17,42 +17,149 @@
 | 
				
			|||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					var (
 | 
				
			||||||
	GasQuickStep   uint64 = 2
 | 
						GasQuickStep   = big.NewInt(2)
 | 
				
			||||||
	GasFastestStep uint64 = 3
 | 
						GasFastestStep = big.NewInt(3)
 | 
				
			||||||
	GasFastStep    uint64 = 5
 | 
						GasFastStep    = big.NewInt(5)
 | 
				
			||||||
	GasMidStep     uint64 = 8
 | 
						GasMidStep     = big.NewInt(8)
 | 
				
			||||||
	GasSlowStep    uint64 = 10
 | 
						GasSlowStep    = big.NewInt(10)
 | 
				
			||||||
	GasExtStep     uint64 = 20
 | 
						GasExtStep     = big.NewInt(20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GasReturn       uint64 = 0
 | 
						GasReturn = big.NewInt(0)
 | 
				
			||||||
	GasStop         uint64 = 0
 | 
						GasStop   = big.NewInt(0)
 | 
				
			||||||
	GasContractByte uint64 = 200
 | 
					
 | 
				
			||||||
 | 
						GasContractByte = big.NewInt(200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n64 = big.NewInt(64)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// calcGas returns the actual gas cost of the call.
 | 
					// calcGas returns the actual gas cost of the call.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The cost of gas was changed during the homestead price change HF. To allow for EIP150
 | 
					// The cost of gas was changed during the homestead price change HF. To allow for EIP150
 | 
				
			||||||
// to be implemented. The returned gas is gas - base * 63 / 64.
 | 
					// to be implemented. The returned gas is gas - base * 63 / 64.
 | 
				
			||||||
func callGas(gasTable params.GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) {
 | 
					func callGas(gasTable params.GasTable, availableGas, base, callCost *big.Int) *big.Int {
 | 
				
			||||||
	if gasTable.CreateBySuicide > 0 {
 | 
						if gasTable.CreateBySuicide != nil {
 | 
				
			||||||
		availableGas = availableGas - base
 | 
							availableGas = new(big.Int).Sub(availableGas, base)
 | 
				
			||||||
		gas := availableGas - availableGas/64
 | 
							g := new(big.Int).Div(availableGas, n64)
 | 
				
			||||||
		// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
 | 
							g.Sub(availableGas, g)
 | 
				
			||||||
		// is smaller than the requested amount. Therefor we return the new gas instead
 | 
					
 | 
				
			||||||
		// of returning an error.
 | 
							if g.Cmp(callCost) < 0 {
 | 
				
			||||||
		if callCost.BitLen() > 64 || gas < callCost.Uint64() {
 | 
								return g
 | 
				
			||||||
			return gas, nil
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if callCost.BitLen() > 64 {
 | 
						return callCost
 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// baseCheck checks for any stack error underflows
 | 
				
			||||||
 | 
					func baseCheck(op OpCode, stack *Stack, gas *big.Int) error {
 | 
				
			||||||
 | 
						// PUSH and DUP are a bit special. They all cost the same but we do want to have checking on stack push limit
 | 
				
			||||||
 | 
						// PUSH is also allowed to calculate the same price for all PUSHes
 | 
				
			||||||
 | 
						// DUP requirements are handled elsewhere (except for the stack limit check)
 | 
				
			||||||
 | 
						if op >= PUSH1 && op <= PUSH32 {
 | 
				
			||||||
 | 
							op = PUSH1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if op >= DUP1 && op <= DUP16 {
 | 
				
			||||||
 | 
							op = DUP1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return callCost.Uint64(), nil
 | 
						if r, ok := _baseCheck[op]; ok {
 | 
				
			||||||
 | 
							err := stack.require(r.stackPop)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if r.stackPush > 0 && stack.len()-r.stackPop+r.stackPush > int(params.StackLimit.Int64()) {
 | 
				
			||||||
 | 
								return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit.Int64())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gas.Add(gas, r.gas)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// casts a arbitrary number to the amount of words (sets of 32 bytes)
 | 
				
			||||||
 | 
					func toWordSize(size *big.Int) *big.Int {
 | 
				
			||||||
 | 
						tmp := new(big.Int)
 | 
				
			||||||
 | 
						tmp.Add(size, u256(31))
 | 
				
			||||||
 | 
						tmp.Div(tmp, u256(32))
 | 
				
			||||||
 | 
						return tmp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type req struct {
 | 
				
			||||||
 | 
						stackPop  int
 | 
				
			||||||
 | 
						gas       *big.Int
 | 
				
			||||||
 | 
						stackPush int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _baseCheck = map[OpCode]req{
 | 
				
			||||||
 | 
						// opcode  |  stack pop | gas price | stack push
 | 
				
			||||||
 | 
						ADD:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						LT:           {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						GT:           {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						SLT:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						SGT:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						EQ:           {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						ISZERO:       {1, GasFastestStep, 1},
 | 
				
			||||||
 | 
						SUB:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						AND:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						OR:           {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						XOR:          {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						NOT:          {1, GasFastestStep, 1},
 | 
				
			||||||
 | 
						BYTE:         {2, GasFastestStep, 1},
 | 
				
			||||||
 | 
						CALLDATALOAD: {1, GasFastestStep, 1},
 | 
				
			||||||
 | 
						CALLDATACOPY: {3, GasFastestStep, 1},
 | 
				
			||||||
 | 
						MLOAD:        {1, GasFastestStep, 1},
 | 
				
			||||||
 | 
						MSTORE:       {2, GasFastestStep, 0},
 | 
				
			||||||
 | 
						MSTORE8:      {2, GasFastestStep, 0},
 | 
				
			||||||
 | 
						CODECOPY:     {3, GasFastestStep, 0},
 | 
				
			||||||
 | 
						MUL:          {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						DIV:          {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						SDIV:         {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						MOD:          {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						SMOD:         {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						SIGNEXTEND:   {2, GasFastStep, 1},
 | 
				
			||||||
 | 
						ADDMOD:       {3, GasMidStep, 1},
 | 
				
			||||||
 | 
						MULMOD:       {3, GasMidStep, 1},
 | 
				
			||||||
 | 
						JUMP:         {1, GasMidStep, 0},
 | 
				
			||||||
 | 
						JUMPI:        {2, GasSlowStep, 0},
 | 
				
			||||||
 | 
						EXP:          {2, GasSlowStep, 1},
 | 
				
			||||||
 | 
						ADDRESS:      {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						ORIGIN:       {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						CALLER:       {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						CALLVALUE:    {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						CODESIZE:     {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						GASPRICE:     {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						COINBASE:     {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						TIMESTAMP:    {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						NUMBER:       {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						CALLDATASIZE: {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						DIFFICULTY:   {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						GASLIMIT:     {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						POP:          {1, GasQuickStep, 0},
 | 
				
			||||||
 | 
						PC:           {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						MSIZE:        {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						GAS:          {0, GasQuickStep, 1},
 | 
				
			||||||
 | 
						BLOCKHASH:    {1, GasExtStep, 1},
 | 
				
			||||||
 | 
						BALANCE:      {1, Zero, 1},
 | 
				
			||||||
 | 
						EXTCODESIZE:  {1, Zero, 1},
 | 
				
			||||||
 | 
						EXTCODECOPY:  {4, Zero, 0},
 | 
				
			||||||
 | 
						SLOAD:        {1, params.SloadGas, 1},
 | 
				
			||||||
 | 
						SSTORE:       {2, Zero, 0},
 | 
				
			||||||
 | 
						SHA3:         {2, params.Sha3Gas, 1},
 | 
				
			||||||
 | 
						CREATE:       {3, params.CreateGas, 1},
 | 
				
			||||||
 | 
						// Zero is calculated in the gasSwitch
 | 
				
			||||||
 | 
						CALL:         {7, Zero, 1},
 | 
				
			||||||
 | 
						CALLCODE:     {7, Zero, 1},
 | 
				
			||||||
 | 
						DELEGATECALL: {6, Zero, 1},
 | 
				
			||||||
 | 
						SELFDESTRUCT: {1, Zero, 0},
 | 
				
			||||||
 | 
						JUMPDEST:     {0, params.JumpdestGas, 0},
 | 
				
			||||||
 | 
						RETURN:       {2, Zero, 0},
 | 
				
			||||||
 | 
						PUSH1:        {0, GasFastestStep, 1},
 | 
				
			||||||
 | 
						DUP1:         {0, Zero, 1},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,80 +1,56 @@
 | 
				
			|||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	gmath "math"
 | 
					 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common/math"
 | 
					 | 
				
			||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// memoryGasCosts calculates the quadratic gas for memory expansion. It does so
 | 
					func memoryGasCost(mem *Memory, newMemSize *big.Int) *big.Int {
 | 
				
			||||||
// only for the memory region that is expanded, not the total memory.
 | 
						gas := new(big.Int)
 | 
				
			||||||
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
 | 
						if newMemSize.Cmp(common.Big0) > 0 {
 | 
				
			||||||
	// The maximum that will fit in a uint64 is max_word_count - 1
 | 
							newMemSizeWords := toWordSize(newMemSize)
 | 
				
			||||||
	// anything above that will result in an overflow.
 | 
					
 | 
				
			||||||
	if newMemSize > gmath.MaxUint64-32 {
 | 
							if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
								// be careful reusing variables here when changing.
 | 
				
			||||||
 | 
								// The order has been optimised to reduce allocation
 | 
				
			||||||
 | 
								oldSize := toWordSize(big.NewInt(int64(mem.Len())))
 | 
				
			||||||
 | 
								pow := new(big.Int).Exp(oldSize, common.Big2, Zero)
 | 
				
			||||||
 | 
								linCoef := oldSize.Mul(oldSize, params.MemoryGas)
 | 
				
			||||||
 | 
								quadCoef := new(big.Int).Div(pow, params.QuadCoeffDiv)
 | 
				
			||||||
 | 
								oldTotalFee := new(big.Int).Add(linCoef, quadCoef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								pow.Exp(newMemSizeWords, common.Big2, Zero)
 | 
				
			||||||
 | 
								linCoef = linCoef.Mul(newMemSizeWords, params.MemoryGas)
 | 
				
			||||||
 | 
								quadCoef = quadCoef.Div(pow, params.QuadCoeffDiv)
 | 
				
			||||||
 | 
								newTotalFee := linCoef.Add(linCoef, quadCoef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								fee := newTotalFee.Sub(newTotalFee, oldTotalFee)
 | 
				
			||||||
 | 
								gas.Add(gas, fee)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						return gas
 | 
				
			||||||
	if newMemSize == 0 {
 | 
					 | 
				
			||||||
		return 0, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	newMemSizeWords := toWordSize(newMemSize)
 | 
					 | 
				
			||||||
	newMemSize = newMemSizeWords * 32
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if newMemSize > uint64(mem.Len()) {
 | 
					 | 
				
			||||||
		square := newMemSizeWords * newMemSizeWords
 | 
					 | 
				
			||||||
		linCoef := newMemSizeWords * params.MemoryGas
 | 
					 | 
				
			||||||
		quadCoef := square / params.QuadCoeffDiv
 | 
					 | 
				
			||||||
		newTotalFee := linCoef + quadCoef
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fee := newTotalFee - mem.lastGasCost
 | 
					 | 
				
			||||||
		mem.lastGasCost = newTotalFee
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return fee, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func constGasFunc(gas uint64) gasFunc {
 | 
					func constGasFunc(gas *big.Int) gasFunc {
 | 
				
			||||||
	return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
						return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
		return gas, nil
 | 
							return gas
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasCalldataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasCalldataCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
						gas := memoryGasCost(mem, memorySize)
 | 
				
			||||||
	if err != nil {
 | 
						gas.Add(gas, GasFastestStep)
 | 
				
			||||||
		return 0, err
 | 
						words := toWordSize(stack.Back(2))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var overflow bool
 | 
						return gas.Add(gas, words.Mul(words, params.CopyGas))
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	words, overflow := bigUint64(stack.Back(2))
 | 
					 | 
				
			||||||
	if overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, words); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasSStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		y, x = stack.Back(1), stack.Back(0)
 | 
							y, x = stack.Back(1), stack.Back(0)
 | 
				
			||||||
		val  = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
 | 
							val  = env.StateDB.GetState(contract.Address(), common.BigToHash(x))
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// This checks for 3 scenario's and calculates gas accordingly
 | 
						// This checks for 3 scenario's and calculates gas accordingly
 | 
				
			||||||
	// 1. From a zero-value address to a non-zero value         (NEW VALUE)
 | 
						// 1. From a zero-value address to a non-zero value         (NEW VALUE)
 | 
				
			||||||
@@ -82,335 +58,189 @@ func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m
 | 
				
			|||||||
	// 3. From a non-zero to a non-zero                         (CHANGE)
 | 
						// 3. From a non-zero to a non-zero                         (CHANGE)
 | 
				
			||||||
	if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) {
 | 
						if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) {
 | 
				
			||||||
		// 0 => non 0
 | 
							// 0 => non 0
 | 
				
			||||||
		return params.SstoreSetGas, nil
 | 
							return new(big.Int).Set(params.SstoreSetGas)
 | 
				
			||||||
	} else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) {
 | 
						} else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) {
 | 
				
			||||||
		evm.StateDB.AddRefund(new(big.Int).SetUint64(params.SstoreRefundGas))
 | 
							env.StateDB.AddRefund(params.SstoreRefundGas)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return params.SstoreClearGas, nil
 | 
							return new(big.Int).Set(params.SstoreClearGas)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// non 0 => non 0 (or 0 => 0)
 | 
							// non 0 => non 0 (or 0 => 0)
 | 
				
			||||||
		return params.SstoreResetGas, nil
 | 
							return new(big.Int).Set(params.SstoreResetGas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeGasLog(n uint64) gasFunc {
 | 
					func makeGasLog(n uint) gasFunc {
 | 
				
			||||||
	return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
						return func(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
		requestedSize, overflow := bigUint64(stack.Back(1))
 | 
							mSize := stack.Back(1)
 | 
				
			||||||
		if overflow {
 | 
					 | 
				
			||||||
			return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gas, err := memoryGasCost(mem, memorySize)
 | 
							gas := new(big.Int).Add(memoryGasCost(mem, memorySize), params.LogGas)
 | 
				
			||||||
		if err != nil {
 | 
							gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), params.LogTopicGas))
 | 
				
			||||||
			return 0, err
 | 
							gas.Add(gas, new(big.Int).Mul(mSize, params.LogDataGas))
 | 
				
			||||||
		}
 | 
							return gas
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow {
 | 
					 | 
				
			||||||
			return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow {
 | 
					 | 
				
			||||||
			return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var memorySizeGas uint64
 | 
					 | 
				
			||||||
		if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow {
 | 
					 | 
				
			||||||
			return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow {
 | 
					 | 
				
			||||||
			return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return gas, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasSha3(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var overflow bool
 | 
						gas := memoryGasCost(mem, memorySize)
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
						gas.Add(gas, params.Sha3Gas)
 | 
				
			||||||
	if err != nil {
 | 
						words := toWordSize(stack.Back(1))
 | 
				
			||||||
		return 0, err
 | 
						return gas.Add(gas, words.Mul(words, params.Sha3WordGas))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wordGas, overflow := bigUint64(stack.Back(1))
 | 
					 | 
				
			||||||
	if overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Sha3WordGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
						gas := memoryGasCost(mem, memorySize)
 | 
				
			||||||
	if err != nil {
 | 
						gas.Add(gas, GasFastestStep)
 | 
				
			||||||
		return 0, err
 | 
						words := toWordSize(stack.Back(2))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var overflow bool
 | 
						return gas.Add(gas, words.Mul(words, params.CopyGas))
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wordGas, overflow := bigUint64(stack.Back(2))
 | 
					 | 
				
			||||||
	if overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasExtCodeCopy(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
						gas := memoryGasCost(mem, memorySize)
 | 
				
			||||||
	if err != nil {
 | 
						gas.Add(gas, gt.ExtcodeCopy)
 | 
				
			||||||
		return 0, err
 | 
						words := toWordSize(stack.Back(3))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var overflow bool
 | 
						return gas.Add(gas, words.Mul(words, params.CopyGas))
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wordGas, overflow := bigUint64(stack.Back(3))
 | 
					 | 
				
			||||||
	if overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasMLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var overflow bool
 | 
						return new(big.Int).Add(GasFastestStep, memoryGasCost(mem, memorySize))
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasMStore8(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var overflow bool
 | 
						return new(big.Int).Add(GasFastestStep, memoryGasCost(mem, memorySize))
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasMStore(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var overflow bool
 | 
						return new(big.Int).Add(GasFastestStep, memoryGasCost(mem, memorySize))
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasCreate(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var overflow bool
 | 
						return new(big.Int).Add(params.CreateGas, memoryGasCost(mem, memorySize))
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasBalance(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return gt.Balance, nil
 | 
						return gt.Balance
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasExtCodeSize(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return gt.ExtcodeSize, nil
 | 
						return gt.ExtcodeSize
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasSLoad(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return gt.SLoad, nil
 | 
						return gt.SLoad
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasExp(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
 | 
						expByteLen := int64((stack.data[stack.len()-2].BitLen() + 7) / 8)
 | 
				
			||||||
 | 
						gas := big.NewInt(expByteLen)
 | 
				
			||||||
 | 
						gas.Mul(gas, gt.ExpByte)
 | 
				
			||||||
 | 
						return gas.Add(gas, GasSlowStep)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func gasCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
 | 
						gas := new(big.Int).Set(gt.Calls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						transfersValue := stack.Back(2).BitLen() > 0
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		gas      = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas
 | 
							address = common.BigToAddress(stack.Back(1))
 | 
				
			||||||
		overflow bool
 | 
							eip158  = env.ChainConfig().IsEIP158(env.BlockNumber)
 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, GasSlowStep); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		gas            = gt.Calls
 | 
					 | 
				
			||||||
		transfersValue = stack.Back(2).BitLen() > 0
 | 
					 | 
				
			||||||
		address        = common.BigToAddress(stack.Back(1))
 | 
					 | 
				
			||||||
		eip158         = evm.ChainConfig().IsEIP158(evm.BlockNumber)
 | 
					 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if eip158 {
 | 
						if eip158 {
 | 
				
			||||||
		if evm.StateDB.Empty(address) && transfersValue {
 | 
							if env.StateDB.Empty(address) && transfersValue {
 | 
				
			||||||
			gas += params.CallNewAccountGas
 | 
								gas.Add(gas, params.CallNewAccountGas)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if !evm.StateDB.Exist(address) {
 | 
						} else if !env.StateDB.Exist(address) {
 | 
				
			||||||
		gas += params.CallNewAccountGas
 | 
							gas.Add(gas, params.CallNewAccountGas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if transfersValue {
 | 
						if transfersValue {
 | 
				
			||||||
		gas += params.CallValueTransferGas
 | 
							gas.Add(gas, params.CallValueTransferGas)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	memoryGas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var overflow bool
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						gas.Add(gas, memoryGasCost(mem, memorySize))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cg, err := callGas(gt, contract.Gas, gas, stack.Back(0))
 | 
						cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Replace the stack item with the new gas calculation. This means that
 | 
						// Replace the stack item with the new gas calculation. This means that
 | 
				
			||||||
	// either the original item is left on the stack or the item is replaced by:
 | 
						// either the original item is left on the stack or the item is replaced by:
 | 
				
			||||||
	// (availableGas - gas) * 63 / 64
 | 
						// (availableGas - gas) * 63 / 64
 | 
				
			||||||
	// We replace the stack item so that it's available when the opCall instruction is
 | 
						// We replace the stack item so that it's available when the opCall instruction is
 | 
				
			||||||
	// called. This information is otherwise lost due to the dependency on *current*
 | 
						// called. This information is otherwise lost due to the dependency on *current*
 | 
				
			||||||
	// available gas.
 | 
						// available gas.
 | 
				
			||||||
	stack.data[stack.len()-1] = new(big.Int).SetUint64(cg)
 | 
						stack.data[stack.len()-1] = cg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, cg); overflow {
 | 
						return gas.Add(gas, cg)
 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasCallCode(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	gas := gt.Calls
 | 
						gas := new(big.Int).Set(gt.Calls)
 | 
				
			||||||
	if stack.Back(2).BitLen() > 0 {
 | 
						if stack.Back(2).BitLen() > 0 {
 | 
				
			||||||
		gas += params.CallValueTransferGas
 | 
							gas.Add(gas, params.CallValueTransferGas)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	memoryGas, err := memoryGasCost(mem, memorySize)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var overflow bool
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						gas.Add(gas, memoryGasCost(mem, memorySize))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cg, err := callGas(gt, contract.Gas, gas, stack.Back(0))
 | 
						cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Replace the stack item with the new gas calculation. This means that
 | 
						// Replace the stack item with the new gas calculation. This means that
 | 
				
			||||||
	// either the original item is left on the stack or the item is replaced by:
 | 
						// either the original item is left on the stack or the item is replaced by:
 | 
				
			||||||
	// (availableGas - gas) * 63 / 64
 | 
						// (availableGas - gas) * 63 / 64
 | 
				
			||||||
	// We replace the stack item so that it's available when the opCall instruction is
 | 
						// We replace the stack item so that it's available when the opCall instruction is
 | 
				
			||||||
	// called. This information is otherwise lost due to the dependency on *current*
 | 
						// called. This information is otherwise lost due to the dependency on *current*
 | 
				
			||||||
	// available gas.
 | 
						// available gas.
 | 
				
			||||||
	stack.data[stack.len()-1] = new(big.Int).SetUint64(cg)
 | 
						stack.data[stack.len()-1] = cg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, cg); overflow {
 | 
						return gas.Add(gas, cg)
 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasReturn(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return memoryGasCost(mem, memorySize)
 | 
						return memoryGasCost(mem, memorySize)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasSuicide(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	var gas uint64
 | 
						gas := new(big.Int)
 | 
				
			||||||
	// EIP150 homestead gas reprice fork:
 | 
						// EIP150 homestead gas reprice fork:
 | 
				
			||||||
	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
 | 
						if env.ChainConfig().IsEIP150(env.BlockNumber) {
 | 
				
			||||||
		gas = gt.Suicide
 | 
							gas.Set(gt.Suicide)
 | 
				
			||||||
		var (
 | 
							var (
 | 
				
			||||||
			address = common.BigToAddress(stack.Back(0))
 | 
								address = common.BigToAddress(stack.Back(0))
 | 
				
			||||||
			eip158  = evm.ChainConfig().IsEIP158(evm.BlockNumber)
 | 
								eip158  = env.ChainConfig().IsEIP158(env.BlockNumber)
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if eip158 {
 | 
							if eip158 {
 | 
				
			||||||
			// if empty and transfers value
 | 
								// if empty and transfers value
 | 
				
			||||||
			if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).BitLen() > 0 {
 | 
								if env.StateDB.Empty(address) && env.StateDB.GetBalance(contract.Address()).BitLen() > 0 {
 | 
				
			||||||
				gas += gt.CreateBySuicide
 | 
									gas.Add(gas, gt.CreateBySuicide)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if !evm.StateDB.Exist(address) {
 | 
							} else if !env.StateDB.Exist(address) {
 | 
				
			||||||
			gas += gt.CreateBySuicide
 | 
								gas.Add(gas, gt.CreateBySuicide)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !evm.StateDB.HasSuicided(contract.Address()) {
 | 
						if !env.StateDB.HasSuicided(contract.Address()) {
 | 
				
			||||||
		evm.StateDB.AddRefund(new(big.Int).SetUint64(params.SuicideRefundGas))
 | 
							env.StateDB.AddRefund(params.SuicideRefundGas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return gas, nil
 | 
						return gas
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasDelegateCall(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	gas, err := memoryGasCost(mem, memorySize)
 | 
						gas := new(big.Int).Add(gt.Calls, memoryGasCost(mem, memorySize))
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var overflow bool
 | 
					 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
 | 
					 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cg, err := callGas(gt, contract.Gas, gas, stack.Back(0))
 | 
						cg := callGas(gt, contract.Gas, gas, stack.data[stack.len()-1])
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return 0, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Replace the stack item with the new gas calculation. This means that
 | 
						// Replace the stack item with the new gas calculation. This means that
 | 
				
			||||||
	// either the original item is left on the stack or the item is replaced by:
 | 
						// either the original item is left on the stack or the item is replaced by:
 | 
				
			||||||
	// (availableGas - gas) * 63 / 64
 | 
						// (availableGas - gas) * 63 / 64
 | 
				
			||||||
	// We replace the stack item so that it's available when the opCall instruction is
 | 
						// We replace the stack item so that it's available when the opCall instruction is
 | 
				
			||||||
	// called.
 | 
						// called.
 | 
				
			||||||
	stack.data[stack.len()-1] = new(big.Int).SetUint64(cg)
 | 
						stack.data[stack.len()-1] = cg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if gas, overflow = math.SafeAdd(gas, cg); overflow {
 | 
						return gas.Add(gas, cg)
 | 
				
			||||||
		return 0, errGasUintOverflow
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return gas, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasPush(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasPush(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return GasFastestStep, nil
 | 
						return GasFastestStep
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasSwap(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasSwap(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return GasFastestStep, nil
 | 
						return GasFastestStep
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func gasDup(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
 | 
					func gasDup(gt params.GasTable, env *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize *big.Int) *big.Int {
 | 
				
			||||||
	return GasFastestStep, nil
 | 
						return GasFastestStep
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
package vm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"math"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestMemoryGasCost(t *testing.T) {
 | 
					 | 
				
			||||||
	size := uint64(math.MaxUint64 - 64)
 | 
					 | 
				
			||||||
	_, err := memoryGasCost(&Memory{}, size)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Error("didn't expect error:", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err = memoryGasCost(&Memory{}, size+32)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Error("didn't expect error:", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err = memoryGasCost(&Memory{}, size+33)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		t.Error("expected error")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -27,56 +27,42 @@ import (
 | 
				
			|||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var bigZero = new(big.Int)
 | 
					func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(U256(x.Add(x, y)))
 | 
						stack.push(U256(x.Add(x, y)))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(U256(x.Sub(x, y)))
 | 
						stack.push(U256(x.Sub(x, y)))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(U256(x.Mul(x, y)))
 | 
						stack.push(U256(x.Mul(x, y)))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	if y.Cmp(common.Big0) != 0 {
 | 
						if y.Cmp(common.Big0) != 0 {
 | 
				
			||||||
		stack.push(U256(x.Div(x, y)))
 | 
							stack.push(U256(x.Div(x, y)))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := S256(stack.pop()), S256(stack.pop())
 | 
						x, y := S256(stack.pop()), S256(stack.pop())
 | 
				
			||||||
	if y.Cmp(common.Big0) == 0 {
 | 
						if y.Cmp(common.Big0) == 0 {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		n := new(big.Int)
 | 
							n := new(big.Int)
 | 
				
			||||||
		if evm.interpreter.intPool.get().Mul(x, y).Cmp(common.Big0) < 0 {
 | 
							if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 {
 | 
				
			||||||
			n.SetInt64(-1)
 | 
								n.SetInt64(-1)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			n.SetInt64(1)
 | 
								n.SetInt64(1)
 | 
				
			||||||
@@ -87,22 +73,20 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		stack.push(U256(res))
 | 
							stack.push(U256(res))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	if y.Cmp(common.Big0) == 0 {
 | 
						if y.Cmp(common.Big0) == 0 {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(U256(x.Mod(x, y)))
 | 
							stack.push(U256(x.Mod(x, y)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := S256(stack.pop()), S256(stack.pop())
 | 
						x, y := S256(stack.pop()), S256(stack.pop())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if y.Cmp(common.Big0) == 0 {
 | 
						if y.Cmp(common.Big0) == 0 {
 | 
				
			||||||
@@ -120,20 +104,16 @@ func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		stack.push(U256(res))
 | 
							stack.push(U256(res))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	base, exponent := stack.pop(), stack.pop()
 | 
						base, exponent := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(math.Exp(base, exponent))
 | 
						stack.push(math.Exp(base, exponent))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(base, exponent)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	back := stack.pop()
 | 
						back := stack.pop()
 | 
				
			||||||
	if back.Cmp(big.NewInt(31)) < 0 {
 | 
						if back.Cmp(big.NewInt(31)) < 0 {
 | 
				
			||||||
		bit := uint(back.Uint64()*8 + 7)
 | 
							bit := uint(back.Uint64()*8 + 7)
 | 
				
			||||||
@@ -148,231 +128,198 @@ func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		stack.push(U256(num))
 | 
							stack.push(U256(num))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(back)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x := stack.pop()
 | 
						x := stack.pop()
 | 
				
			||||||
	stack.push(U256(x.Not(x)))
 | 
						stack.push(U256(x.Not(x)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	if x.Cmp(y) < 0 {
 | 
						if x.Cmp(y) < 0 {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x, y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	if x.Cmp(y) > 0 {
 | 
						if x.Cmp(y) > 0 {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x, y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := S256(stack.pop()), S256(stack.pop())
 | 
						x, y := S256(stack.pop()), S256(stack.pop())
 | 
				
			||||||
	if x.Cmp(S256(y)) < 0 {
 | 
						if x.Cmp(S256(y)) < 0 {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x, y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := S256(stack.pop()), S256(stack.pop())
 | 
						x, y := S256(stack.pop()), S256(stack.pop())
 | 
				
			||||||
	if x.Cmp(y) > 0 {
 | 
						if x.Cmp(y) > 0 {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x, y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	if x.Cmp(y) == 0 {
 | 
						if x.Cmp(y) == 0 {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x, y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x := stack.pop()
 | 
						x := stack.pop()
 | 
				
			||||||
	if x.Cmp(common.Big0) > 0 {
 | 
						if x.Cmp(common.Big0) > 0 {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(x)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(x.And(x, y))
 | 
						stack.push(x.And(x, y))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(x.Or(x, y))
 | 
						stack.push(x.Or(x, y))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y := stack.pop(), stack.pop()
 | 
						x, y := stack.pop(), stack.pop()
 | 
				
			||||||
	stack.push(x.Xor(x, y))
 | 
						stack.push(x.Xor(x, y))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	th, val := stack.pop(), stack.pop()
 | 
						th, val := stack.pop(), stack.pop()
 | 
				
			||||||
	if th.Cmp(big.NewInt(32)) < 0 {
 | 
						if th.Cmp(big.NewInt(32)) < 0 {
 | 
				
			||||||
		byte := evm.interpreter.intPool.get().SetInt64(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
 | 
							byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
 | 
				
			||||||
		stack.push(byte)
 | 
							stack.push(byte)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(th, val)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y, z := stack.pop(), stack.pop(), stack.pop()
 | 
						x, y, z := stack.pop(), stack.pop(), stack.pop()
 | 
				
			||||||
	if z.Cmp(bigZero) > 0 {
 | 
						if z.Cmp(Zero) > 0 {
 | 
				
			||||||
		add := x.Add(x, y)
 | 
							add := x.Add(x, y)
 | 
				
			||||||
		add.Mod(add, z)
 | 
							add.Mod(add, z)
 | 
				
			||||||
		stack.push(U256(add))
 | 
							stack.push(U256(add))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y, z)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	x, y, z := stack.pop(), stack.pop(), stack.pop()
 | 
						x, y, z := stack.pop(), stack.pop(), stack.pop()
 | 
				
			||||||
	if z.Cmp(bigZero) > 0 {
 | 
						if z.Cmp(Zero) > 0 {
 | 
				
			||||||
		mul := x.Mul(x, y)
 | 
							mul := x.Mul(x, y)
 | 
				
			||||||
		mul.Mod(mul, z)
 | 
							mul.Mod(mul, z)
 | 
				
			||||||
		stack.push(U256(mul))
 | 
							stack.push(U256(mul))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(y, z)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	offset, size := stack.pop(), stack.pop()
 | 
						offset, size := stack.pop(), stack.pop()
 | 
				
			||||||
	data := memory.Get(offset.Int64(), size.Int64())
 | 
						data := memory.Get(offset.Int64(), size.Int64())
 | 
				
			||||||
	hash := crypto.Keccak256(data)
 | 
						hash := crypto.Keccak256(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if evm.vmConfig.EnablePreimageRecording {
 | 
						if env.vmConfig.EnablePreimageRecording {
 | 
				
			||||||
		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
 | 
							env.StateDB.AddPreimage(common.BytesToHash(hash), data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stack.push(common.BytesToBig(hash))
 | 
						stack.push(common.BytesToBig(hash))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(offset, size)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(common.Bytes2Big(contract.Address().Bytes()))
 | 
						stack.push(common.Bytes2Big(contract.Address().Bytes()))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	addr := common.BigToAddress(stack.pop())
 | 
						addr := common.BigToAddress(stack.pop())
 | 
				
			||||||
	balance := evm.StateDB.GetBalance(addr)
 | 
						balance := env.StateDB.GetBalance(addr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stack.push(new(big.Int).Set(balance))
 | 
						stack.push(new(big.Int).Set(balance))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.Origin.Big())
 | 
						stack.push(env.Origin.Big())
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(contract.Caller().Big())
 | 
						stack.push(contract.Caller().Big())
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().Set(contract.value))
 | 
						stack.push(new(big.Int).Set(contract.value))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
 | 
						stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
 | 
						stack.push(big.NewInt(int64(len(contract.Input))))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		mOff = stack.pop()
 | 
							mOff = stack.pop()
 | 
				
			||||||
		cOff = stack.pop()
 | 
							cOff = stack.pop()
 | 
				
			||||||
		l    = stack.pop()
 | 
							l    = stack.pop()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
 | 
						memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(mOff, cOff, l)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	a := stack.pop()
 | 
						addr := common.BigToAddress(stack.pop())
 | 
				
			||||||
 | 
						l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
 | 
				
			||||||
	addr := common.BigToAddress(a)
 | 
					 | 
				
			||||||
	a.SetInt64(int64(evm.StateDB.GetCodeSize(addr)))
 | 
					 | 
				
			||||||
	stack.push(a)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					 | 
				
			||||||
	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
 | 
					 | 
				
			||||||
	stack.push(l)
 | 
						stack.push(l)
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
 | 
						l := big.NewInt(int64(len(contract.Code)))
 | 
				
			||||||
 | 
						stack.push(l)
 | 
				
			||||||
 | 
						return nil, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		mOff = stack.pop()
 | 
							mOff = stack.pop()
 | 
				
			||||||
		cOff = stack.pop()
 | 
							cOff = stack.pop()
 | 
				
			||||||
@@ -381,129 +328,113 @@ func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
 | 
				
			|||||||
	codeCopy := getData(contract.Code, cOff, l)
 | 
						codeCopy := getData(contract.Code, cOff, l)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
 | 
						memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(mOff, cOff, l)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		addr = common.BigToAddress(stack.pop())
 | 
							addr = common.BigToAddress(stack.pop())
 | 
				
			||||||
		mOff = stack.pop()
 | 
							mOff = stack.pop()
 | 
				
			||||||
		cOff = stack.pop()
 | 
							cOff = stack.pop()
 | 
				
			||||||
		l    = stack.pop()
 | 
							l    = stack.pop()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	codeCopy := getData(evm.StateDB.GetCode(addr), cOff, l)
 | 
						codeCopy := getData(env.StateDB.GetCode(addr), cOff, l)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
 | 
						memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(mOff, cOff, l)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
 | 
						stack.push(new(big.Int).Set(env.GasPrice))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	num := stack.pop()
 | 
						num := stack.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
 | 
						n := new(big.Int).Sub(env.BlockNumber, common.Big257)
 | 
				
			||||||
	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
 | 
						if num.Cmp(n) > 0 && num.Cmp(env.BlockNumber) < 0 {
 | 
				
			||||||
		stack.push(evm.GetHash(num.Uint64()).Big())
 | 
							stack.push(env.GetHash(num.Uint64()).Big())
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(num, n)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.Coinbase.Big())
 | 
						stack.push(env.Coinbase.Big())
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(U256(new(big.Int).Set(evm.Time)))
 | 
						stack.push(U256(new(big.Int).Set(env.Time)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(U256(new(big.Int).Set(evm.BlockNumber)))
 | 
						stack.push(U256(new(big.Int).Set(env.BlockNumber)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(U256(new(big.Int).Set(evm.Difficulty)))
 | 
						stack.push(U256(new(big.Int).Set(env.Difficulty)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(U256(new(big.Int).Set(evm.GasLimit)))
 | 
						stack.push(U256(new(big.Int).Set(env.GasLimit)))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	evm.interpreter.intPool.put(stack.pop())
 | 
						stack.pop()
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	offset := stack.pop()
 | 
						offset := stack.pop()
 | 
				
			||||||
	val := common.BigD(memory.Get(offset.Int64(), 32))
 | 
						val := common.BigD(memory.Get(offset.Int64(), 32))
 | 
				
			||||||
	stack.push(val)
 | 
						stack.push(val)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(offset)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	// pop value of the stack
 | 
						// pop value of the stack
 | 
				
			||||||
	mStart, val := stack.pop(), stack.pop()
 | 
						mStart, val := stack.pop(), stack.pop()
 | 
				
			||||||
	memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
 | 
						memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(mStart, val)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	off, val := stack.pop().Int64(), stack.pop().Int64()
 | 
						off, val := stack.pop().Int64(), stack.pop().Int64()
 | 
				
			||||||
	memory.store[off] = byte(val & 0xff)
 | 
						memory.store[off] = byte(val & 0xff)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	loc := common.BigToHash(stack.pop())
 | 
						loc := common.BigToHash(stack.pop())
 | 
				
			||||||
	val := evm.StateDB.GetState(contract.Address(), loc).Big()
 | 
						val := env.StateDB.GetState(contract.Address(), loc).Big()
 | 
				
			||||||
	stack.push(val)
 | 
						stack.push(val)
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	loc := common.BigToHash(stack.pop())
 | 
						loc := common.BigToHash(stack.pop())
 | 
				
			||||||
	val := stack.pop()
 | 
						val := stack.pop()
 | 
				
			||||||
	evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
 | 
						env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(val)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	pos := stack.pop()
 | 
						pos := stack.pop()
 | 
				
			||||||
	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
 | 
						if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
 | 
				
			||||||
		nop := contract.GetOp(pos.Uint64())
 | 
							nop := contract.GetOp(pos.Uint64())
 | 
				
			||||||
		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
 | 
							return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	*pc = pos.Uint64()
 | 
						*pc = pos.Uint64()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(pos)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	pos, cond := stack.pop(), stack.pop()
 | 
						pos, cond := stack.pop(), stack.pop()
 | 
				
			||||||
	if cond.Cmp(common.BigTrue) >= 0 {
 | 
						if cond.Cmp(common.BigTrue) >= 0 {
 | 
				
			||||||
		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
 | 
							if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
 | 
				
			||||||
@@ -514,62 +445,57 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		*pc++
 | 
							*pc++
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(pos, cond)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
 | 
						stack.push(new(big.Int).SetUint64(*pc))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
 | 
						stack.push(big.NewInt(int64(memory.Len())))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
 | 
						stack.push(new(big.Int).Set(contract.Gas))
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		value        = stack.pop()
 | 
							value        = stack.pop()
 | 
				
			||||||
		offset, size = stack.pop(), stack.pop()
 | 
							offset, size = stack.pop(), stack.pop()
 | 
				
			||||||
		input        = memory.Get(offset.Int64(), size.Int64())
 | 
							input        = memory.Get(offset.Int64(), size.Int64())
 | 
				
			||||||
		gas          = contract.Gas
 | 
							gas          = new(big.Int).Set(contract.Gas)
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
 | 
						if env.ChainConfig().IsEIP150(env.BlockNumber) {
 | 
				
			||||||
		gas -= gas / 64
 | 
							gas.Div(gas, n64)
 | 
				
			||||||
 | 
							gas = gas.Sub(contract.Gas, gas)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	contract.UseGas(gas)
 | 
						contract.UseGas(gas)
 | 
				
			||||||
	_, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
 | 
						_, addr, suberr := env.Create(contract, input, gas, value)
 | 
				
			||||||
	// Push item on the stack based on the returned error. If the ruleset is
 | 
						// Push item on the stack based on the returned error. If the ruleset is
 | 
				
			||||||
	// homestead we must check for CodeStoreOutOfGasError (homestead only
 | 
						// homestead we must check for CodeStoreOutOfGasError (homestead only
 | 
				
			||||||
	// rule) and treat as an error, if the ruleset is frontier we must
 | 
						// rule) and treat as an error, if the ruleset is frontier we must
 | 
				
			||||||
	// ignore this error and pretend the operation was successful.
 | 
						// ignore this error and pretend the operation was successful.
 | 
				
			||||||
	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
 | 
						if env.ChainConfig().IsHomestead(env.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
 | 
						} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(addr.Big())
 | 
							stack.push(addr.Big())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contract.Gas += returnGas
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(value, offset, size)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	gas := stack.pop().Uint64()
 | 
						gas := stack.pop()
 | 
				
			||||||
	// pop gas and value of the stack.
 | 
						// pop gas and value of the stack.
 | 
				
			||||||
	addr, value := stack.pop(), stack.pop()
 | 
						addr, value := stack.pop(), stack.pop()
 | 
				
			||||||
	value = U256(value)
 | 
						value = U256(value)
 | 
				
			||||||
@@ -583,26 +509,25 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
 | 
				
			|||||||
	// Get the arguments from the memory
 | 
						// Get the arguments from the memory
 | 
				
			||||||
	args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
						args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if value.BitLen() > 0 {
 | 
						if len(value.Bytes()) > 0 {
 | 
				
			||||||
		gas += params.CallStipend
 | 
							gas.Add(gas, params.CallStipend)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, returnGas, err := evm.Call(contract, address, args, gas, value)
 | 
						ret, err := env.Call(contract, address, args, gas, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(big.NewInt(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 | 
							memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contract.Gas += returnGas
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	gas := stack.pop().Uint64()
 | 
						gas := stack.pop()
 | 
				
			||||||
	// pop gas and value of the stack.
 | 
						// pop gas and value of the stack.
 | 
				
			||||||
	addr, value := stack.pop(), stack.pop()
 | 
						addr, value := stack.pop(), stack.pop()
 | 
				
			||||||
	value = U256(value)
 | 
						value = U256(value)
 | 
				
			||||||
@@ -616,11 +541,12 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
 | 
				
			|||||||
	// Get the arguments from the memory
 | 
						// Get the arguments from the memory
 | 
				
			||||||
	args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
						args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if value.BitLen() > 0 {
 | 
						if len(value.Bytes()) > 0 {
 | 
				
			||||||
		gas += params.CallStipend
 | 
							gas.Add(gas, params.CallStipend)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret, returnGas, err := evm.CallCode(contract, address, args, gas, value)
 | 
						ret, err := env.CallCode(contract, address, args, gas, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -629,54 +555,46 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 | 
							memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contract.Gas += returnGas
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	// if not homestead return an error. DELEGATECALL is not supported
 | 
						// if not homestead return an error. DELEGATECALL is not supported
 | 
				
			||||||
	// during pre-homestead.
 | 
						// during pre-homestead.
 | 
				
			||||||
	if !evm.ChainConfig().IsHomestead(evm.BlockNumber) {
 | 
						if !env.ChainConfig().IsHomestead(env.BlockNumber) {
 | 
				
			||||||
		return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
 | 
							return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
 | 
						gas, to, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	toAddr := common.BigToAddress(to)
 | 
						toAddr := common.BigToAddress(to)
 | 
				
			||||||
	args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
						args := memory.Get(inOffset.Int64(), inSize.Int64())
 | 
				
			||||||
 | 
						ret, err := env.DelegateCall(contract, toAddr, args, gas)
 | 
				
			||||||
	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		stack.push(new(big.Int))
 | 
							stack.push(new(big.Int))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		stack.push(big.NewInt(1))
 | 
							stack.push(big.NewInt(1))
 | 
				
			||||||
		memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
 | 
							memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	contract.Gas += returnGas
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize)
 | 
					 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	offset, size := stack.pop(), stack.pop()
 | 
						offset, size := stack.pop(), stack.pop()
 | 
				
			||||||
	ret := memory.GetPtr(offset.Int64(), size.Int64())
 | 
						ret := memory.GetPtr(offset.Int64(), size.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	evm.interpreter.intPool.put(offset, size)
 | 
					 | 
				
			||||||
	return ret, nil
 | 
						return ret, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
					func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
	balance := evm.StateDB.GetBalance(contract.Address())
 | 
						balance := env.StateDB.GetBalance(contract.Address())
 | 
				
			||||||
	evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
 | 
						env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	evm.StateDB.Suicide(contract.Address())
 | 
						env.StateDB.Suicide(contract.Address())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil, nil
 | 
						return nil, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -685,7 +603,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// make log instruction function
 | 
					// make log instruction function
 | 
				
			||||||
func makeLog(size int) executionFunc {
 | 
					func makeLog(size int) executionFunc {
 | 
				
			||||||
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
						return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
		topics := make([]common.Hash, size)
 | 
							topics := make([]common.Hash, size)
 | 
				
			||||||
		mStart, mSize := stack.pop(), stack.pop()
 | 
							mStart, mSize := stack.pop(), stack.pop()
 | 
				
			||||||
		for i := 0; i < size; i++ {
 | 
							for i := 0; i < size; i++ {
 | 
				
			||||||
@@ -693,24 +611,22 @@ func makeLog(size int) executionFunc {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d := memory.Get(mStart.Int64(), mSize.Int64())
 | 
							d := memory.Get(mStart.Int64(), mSize.Int64())
 | 
				
			||||||
		evm.StateDB.AddLog(&types.Log{
 | 
							env.StateDB.AddLog(&types.Log{
 | 
				
			||||||
			Address: contract.Address(),
 | 
								Address: contract.Address(),
 | 
				
			||||||
			Topics:  topics,
 | 
								Topics:  topics,
 | 
				
			||||||
			Data:    d,
 | 
								Data:    d,
 | 
				
			||||||
			// This is a non-consensus field, but assigned here because
 | 
								// This is a non-consensus field, but assigned here because
 | 
				
			||||||
			// core/state doesn't know the current block number.
 | 
								// core/state doesn't know the current block number.
 | 
				
			||||||
			BlockNumber: evm.BlockNumber.Uint64(),
 | 
								BlockNumber: env.BlockNumber.Uint64(),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					 | 
				
			||||||
		evm.interpreter.intPool.put(mStart, mSize)
 | 
					 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// make push instruction function
 | 
					// make push instruction function
 | 
				
			||||||
func makePush(size uint64, bsize *big.Int) executionFunc {
 | 
					func makePush(size uint64, bsize *big.Int) executionFunc {
 | 
				
			||||||
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
						return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
		byts := getData(contract.Code, evm.interpreter.intPool.get().SetUint64(*pc+1), bsize)
 | 
							byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
 | 
				
			||||||
		stack.push(common.Bytes2Big(byts))
 | 
							stack.push(common.Bytes2Big(byts))
 | 
				
			||||||
		*pc += size
 | 
							*pc += size
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
@@ -719,7 +635,7 @@ func makePush(size uint64, bsize *big.Int) executionFunc {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// make push instruction function
 | 
					// make push instruction function
 | 
				
			||||||
func makeDup(size int64) executionFunc {
 | 
					func makeDup(size int64) executionFunc {
 | 
				
			||||||
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
						return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
		stack.dup(int(size))
 | 
							stack.dup(int(size))
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -729,7 +645,7 @@ func makeDup(size int64) executionFunc {
 | 
				
			|||||||
func makeSwap(size int64) executionFunc {
 | 
					func makeSwap(size int64) executionFunc {
 | 
				
			||||||
	// switch n + 1 otherwise n would be swapped with n
 | 
						// switch n + 1 otherwise n would be swapped with n
 | 
				
			||||||
	size += 1
 | 
						size += 1
 | 
				
			||||||
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
						return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
 | 
				
			||||||
		stack.swap(int(size))
 | 
							stack.swap(int(size))
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +0,0 @@
 | 
				
			|||||||
// +build VERIFY_EVM_INTEGER_POOL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package vm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "fmt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const verifyPool = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func verifyIntegerPool(ip *intPool) {
 | 
					 | 
				
			||||||
	for i, item := range ip.pool.data {
 | 
					 | 
				
			||||||
		if item.Cmp(checkVal) != 0 {
 | 
					 | 
				
			||||||
			panic(fmt.Sprintf("%d'th item failed aggressive pool check. Value was modified", i))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
// +build !VERIFY_EVM_INTEGER_POOL
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package vm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const verifyPool = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func verifyIntegerPool(ip *intPool) {}
 | 
					 | 
				
			||||||
@@ -17,7 +17,6 @@
 | 
				
			|||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
@@ -25,13 +24,11 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	executionFunc       func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
 | 
						executionFunc       func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
 | 
				
			||||||
	gasFunc             func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
 | 
						gasFunc             func(params.GasTable, *EVM, *Contract, *Stack, *Memory, *big.Int) *big.Int
 | 
				
			||||||
	stackValidationFunc func(*Stack) error
 | 
						stackValidationFunc func(*Stack) error
 | 
				
			||||||
	memorySizeFunc      func(*Stack) *big.Int
 | 
						memorySizeFunc      func(*Stack) *big.Int
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var errGasUintOverflow = errors.New("gas uint64 overflow")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type operation struct {
 | 
					type operation struct {
 | 
				
			||||||
	// op is the operation function
 | 
						// op is the operation function
 | 
				
			||||||
	execute executionFunc
 | 
						execute executionFunc
 | 
				
			||||||
@@ -55,142 +52,149 @@ var defaultJumpTable = NewJumpTable()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func NewJumpTable() [256]operation {
 | 
					func NewJumpTable() [256]operation {
 | 
				
			||||||
	return [256]operation{
 | 
						return [256]operation{
 | 
				
			||||||
 | 
							STOP: {
 | 
				
			||||||
 | 
								execute:       opStop,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(new(big.Int)),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(0, 0),
 | 
				
			||||||
 | 
								halts:         true,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		ADD: {
 | 
							ADD: {
 | 
				
			||||||
			execute:       opAdd,
 | 
								execute:       opAdd,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SUB: {
 | 
					 | 
				
			||||||
			execute:       opSub,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MUL: {
 | 
							MUL: {
 | 
				
			||||||
			execute:       opMul,
 | 
								execute:       opMul,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SUB: {
 | 
				
			||||||
 | 
								execute:       opSub,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DIV: {
 | 
							DIV: {
 | 
				
			||||||
			execute:       opDiv,
 | 
								execute:       opDiv,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SDIV: {
 | 
							SDIV: {
 | 
				
			||||||
			execute:       opSdiv,
 | 
								execute:       opSdiv,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MOD: {
 | 
							MOD: {
 | 
				
			||||||
			execute:       opMod,
 | 
								execute:       opMod,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SMOD: {
 | 
							SMOD: {
 | 
				
			||||||
			execute:       opSmod,
 | 
								execute:       opSmod,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		EXP: {
 | 
					 | 
				
			||||||
			execute:       opExp,
 | 
					 | 
				
			||||||
			gasCost:       gasExp,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SIGNEXTEND: {
 | 
					 | 
				
			||||||
			execute:       opSignExtend,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		NOT: {
 | 
					 | 
				
			||||||
			execute:       opNot,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LT: {
 | 
					 | 
				
			||||||
			execute:       opLt,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		GT: {
 | 
					 | 
				
			||||||
			execute:       opGt,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SLT: {
 | 
					 | 
				
			||||||
			execute:       opSlt,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SGT: {
 | 
					 | 
				
			||||||
			execute:       opSgt,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		EQ: {
 | 
					 | 
				
			||||||
			execute:       opEq,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		ISZERO: {
 | 
					 | 
				
			||||||
			execute:       opIszero,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		AND: {
 | 
					 | 
				
			||||||
			execute:       opAnd,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		OR: {
 | 
					 | 
				
			||||||
			execute:       opOr,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		XOR: {
 | 
					 | 
				
			||||||
			execute:       opXor,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		BYTE: {
 | 
					 | 
				
			||||||
			execute:       opByte,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ADDMOD: {
 | 
							ADDMOD: {
 | 
				
			||||||
			execute:       opAddmod,
 | 
								execute:       opAddmod,
 | 
				
			||||||
			gasCost:       constGasFunc(GasMidStep),
 | 
								gasCost:       constGasFunc(GasMidStep),
 | 
				
			||||||
			validateStack: makeStackFunc(3, 1),
 | 
								validateStack: makeStackFunc(3, -2),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MULMOD: {
 | 
							MULMOD: {
 | 
				
			||||||
			execute:       opMulmod,
 | 
								execute:       opMulmod,
 | 
				
			||||||
			gasCost:       constGasFunc(GasMidStep),
 | 
								gasCost:       constGasFunc(GasMidStep),
 | 
				
			||||||
			validateStack: makeStackFunc(3, 1),
 | 
								validateStack: makeStackFunc(3, -2),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							EXP: {
 | 
				
			||||||
 | 
								execute:       opExp,
 | 
				
			||||||
 | 
								gasCost:       gasExp,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SIGNEXTEND: {
 | 
				
			||||||
 | 
								execute:       opSignExtend,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LT: {
 | 
				
			||||||
 | 
								execute:       opLt,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							GT: {
 | 
				
			||||||
 | 
								execute:       opGt,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SLT: {
 | 
				
			||||||
 | 
								execute:       opSlt,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SGT: {
 | 
				
			||||||
 | 
								execute:       opSgt,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							EQ: {
 | 
				
			||||||
 | 
								execute:       opEq,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							ISZERO: {
 | 
				
			||||||
 | 
								execute:       opIszero,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							AND: {
 | 
				
			||||||
 | 
								execute:       opAnd,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							XOR: {
 | 
				
			||||||
 | 
								execute:       opXor,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							OR: {
 | 
				
			||||||
 | 
								execute:       opOr,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							NOT: {
 | 
				
			||||||
 | 
								execute:       opNot,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							BYTE: {
 | 
				
			||||||
 | 
								execute:       opByte,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SHA3: {
 | 
							SHA3: {
 | 
				
			||||||
			execute:       opSha3,
 | 
								execute:       opSha3,
 | 
				
			||||||
			gasCost:       gasSha3,
 | 
								gasCost:       gasSha3,
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeStackFunc(2, -1),
 | 
				
			||||||
			memorySize:    memorySha3,
 | 
								memorySize:    memorySha3,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -203,7 +207,7 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
		BALANCE: {
 | 
							BALANCE: {
 | 
				
			||||||
			execute:       opBalance,
 | 
								execute:       opBalance,
 | 
				
			||||||
			gasCost:       gasBalance,
 | 
								gasCost:       gasBalance,
 | 
				
			||||||
			validateStack: makeStackFunc(0, 1),
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		ORIGIN: {
 | 
							ORIGIN: {
 | 
				
			||||||
@@ -227,7 +231,7 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
		CALLDATALOAD: {
 | 
							CALLDATALOAD: {
 | 
				
			||||||
			execute:       opCalldataLoad,
 | 
								execute:       opCalldataLoad,
 | 
				
			||||||
			gasCost:       constGasFunc(GasFastestStep),
 | 
								gasCost:       constGasFunc(GasFastestStep),
 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		CALLDATASIZE: {
 | 
							CALLDATASIZE: {
 | 
				
			||||||
@@ -239,7 +243,7 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
		CALLDATACOPY: {
 | 
							CALLDATACOPY: {
 | 
				
			||||||
			execute:       opCalldataCopy,
 | 
								execute:       opCalldataCopy,
 | 
				
			||||||
			gasCost:       gasCalldataCopy,
 | 
								gasCost:       gasCalldataCopy,
 | 
				
			||||||
			validateStack: makeStackFunc(3, 1),
 | 
								validateStack: makeStackFunc(3, -3),
 | 
				
			||||||
			memorySize:    memoryCalldataCopy,
 | 
								memorySize:    memoryCalldataCopy,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -249,36 +253,36 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
			validateStack: makeStackFunc(0, 1),
 | 
								validateStack: makeStackFunc(0, 1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		EXTCODESIZE: {
 | 
					 | 
				
			||||||
			execute:       opExtCodeSize,
 | 
					 | 
				
			||||||
			gasCost:       gasExtCodeSize,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		CODECOPY: {
 | 
							CODECOPY: {
 | 
				
			||||||
			execute:       opCodeCopy,
 | 
								execute:       opCodeCopy,
 | 
				
			||||||
			gasCost:       gasCodeCopy,
 | 
								gasCost:       gasCodeCopy,
 | 
				
			||||||
			validateStack: makeStackFunc(3, 0),
 | 
								validateStack: makeStackFunc(3, -3),
 | 
				
			||||||
			memorySize:    memoryCodeCopy,
 | 
								memorySize:    memoryCodeCopy,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		EXTCODECOPY: {
 | 
					 | 
				
			||||||
			execute:       opExtCodeCopy,
 | 
					 | 
				
			||||||
			gasCost:       gasExtCodeCopy,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(4, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryExtCodeCopy,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		GASPRICE: {
 | 
							GASPRICE: {
 | 
				
			||||||
			execute:       opGasprice,
 | 
								execute:       opGasprice,
 | 
				
			||||||
			gasCost:       constGasFunc(GasQuickStep),
 | 
								gasCost:       constGasFunc(GasQuickStep),
 | 
				
			||||||
			validateStack: makeStackFunc(0, 1),
 | 
								validateStack: makeStackFunc(0, 1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							EXTCODESIZE: {
 | 
				
			||||||
 | 
								execute:       opExtCodeSize,
 | 
				
			||||||
 | 
								gasCost:       gasExtCodeSize,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							EXTCODECOPY: {
 | 
				
			||||||
 | 
								execute:       opExtCodeCopy,
 | 
				
			||||||
 | 
								gasCost:       gasExtCodeCopy,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(4, -4),
 | 
				
			||||||
 | 
								memorySize:    memoryExtCodeCopy,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		BLOCKHASH: {
 | 
							BLOCKHASH: {
 | 
				
			||||||
			execute:       opBlockhash,
 | 
								execute:       opBlockhash,
 | 
				
			||||||
			gasCost:       constGasFunc(GasExtStep),
 | 
								gasCost:       constGasFunc(GasExtStep),
 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		COINBASE: {
 | 
							COINBASE: {
 | 
				
			||||||
@@ -314,20 +318,20 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
		POP: {
 | 
							POP: {
 | 
				
			||||||
			execute:       opPop,
 | 
								execute:       opPop,
 | 
				
			||||||
			gasCost:       constGasFunc(GasQuickStep),
 | 
								gasCost:       constGasFunc(GasQuickStep),
 | 
				
			||||||
			validateStack: makeStackFunc(1, 0),
 | 
								validateStack: makeStackFunc(1, -1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MLOAD: {
 | 
							MLOAD: {
 | 
				
			||||||
			execute:       opMload,
 | 
								execute:       opMload,
 | 
				
			||||||
			gasCost:       gasMLoad,
 | 
								gasCost:       gasMLoad,
 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
			memorySize:    memoryMLoad,
 | 
								memorySize:    memoryMLoad,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		MSTORE: {
 | 
							MSTORE: {
 | 
				
			||||||
			execute:       opMstore,
 | 
								execute:       opMstore,
 | 
				
			||||||
			gasCost:       gasMStore,
 | 
								gasCost:       gasMStore,
 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
			memorySize:    memoryMStore,
 | 
								memorySize:    memoryMStore,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -335,26 +339,34 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
			execute:       opMstore8,
 | 
								execute:       opMstore8,
 | 
				
			||||||
			gasCost:       gasMStore8,
 | 
								gasCost:       gasMStore8,
 | 
				
			||||||
			memorySize:    memoryMStore8,
 | 
								memorySize:    memoryMStore8,
 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			valid: true,
 | 
								valid: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SLOAD: {
 | 
							SLOAD: {
 | 
				
			||||||
			execute:       opSload,
 | 
								execute:       opSload,
 | 
				
			||||||
			gasCost:       gasSLoad,
 | 
								gasCost:       gasSLoad,
 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
								validateStack: makeStackFunc(1, 0),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		SSTORE: {
 | 
							SSTORE: {
 | 
				
			||||||
			execute:       opSstore,
 | 
								execute:       opSstore,
 | 
				
			||||||
			gasCost:       gasSStore,
 | 
								gasCost:       gasSStore,
 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		JUMPDEST: {
 | 
							JUMP: {
 | 
				
			||||||
			execute:       opJumpdest,
 | 
								execute:       opJump,
 | 
				
			||||||
			gasCost:       constGasFunc(params.JumpdestGas),
 | 
								gasCost:       constGasFunc(GasMidStep),
 | 
				
			||||||
			validateStack: makeStackFunc(0, 0),
 | 
								validateStack: makeStackFunc(1, -1),
 | 
				
			||||||
 | 
								jumps:         true,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							JUMPI: {
 | 
				
			||||||
 | 
								execute:       opJumpi,
 | 
				
			||||||
 | 
								gasCost:       constGasFunc(GasSlowStep),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
 | 
								jumps:         true,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PC: {
 | 
							PC: {
 | 
				
			||||||
@@ -375,199 +387,10 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
			validateStack: makeStackFunc(0, 1),
 | 
								validateStack: makeStackFunc(0, 1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		CREATE: {
 | 
							JUMPDEST: {
 | 
				
			||||||
			execute:       opCreate,
 | 
								execute:       opJumpdest,
 | 
				
			||||||
			gasCost:       gasCreate,
 | 
								gasCost:       constGasFunc(params.JumpdestGas),
 | 
				
			||||||
			validateStack: makeStackFunc(3, 1),
 | 
					 | 
				
			||||||
			memorySize:    memoryCreate,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		CALL: {
 | 
					 | 
				
			||||||
			execute:       opCall,
 | 
					 | 
				
			||||||
			gasCost:       gasCall,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(7, 1),
 | 
					 | 
				
			||||||
			memorySize:    memoryCall,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		CALLCODE: {
 | 
					 | 
				
			||||||
			execute:       opCallCode,
 | 
					 | 
				
			||||||
			gasCost:       gasCallCode,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(7, 1),
 | 
					 | 
				
			||||||
			memorySize:    memoryCall,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		DELEGATECALL: {
 | 
					 | 
				
			||||||
			execute:       opDelegateCall,
 | 
					 | 
				
			||||||
			gasCost:       gasDelegateCall,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(6, 1),
 | 
					 | 
				
			||||||
			memorySize:    memoryDelegateCall,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		RETURN: {
 | 
					 | 
				
			||||||
			execute:       opReturn,
 | 
					 | 
				
			||||||
			gasCost:       gasReturn,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryReturn,
 | 
					 | 
				
			||||||
			halts:         true,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SUICIDE: {
 | 
					 | 
				
			||||||
			execute:       opSuicide,
 | 
					 | 
				
			||||||
			gasCost:       gasSuicide,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(1, 0),
 | 
					 | 
				
			||||||
			halts:         true,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		JUMP: {
 | 
					 | 
				
			||||||
			execute:       opJump,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasMidStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(1, 0),
 | 
					 | 
				
			||||||
			jumps:         true,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		JUMPI: {
 | 
					 | 
				
			||||||
			execute:       opJumpi,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(GasSlowStep),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
					 | 
				
			||||||
			jumps:         true,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		STOP: {
 | 
					 | 
				
			||||||
			execute:       opStop,
 | 
					 | 
				
			||||||
			gasCost:       constGasFunc(0),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(0, 0),
 | 
								validateStack: makeStackFunc(0, 0),
 | 
				
			||||||
			halts:         true,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LOG0: {
 | 
					 | 
				
			||||||
			execute:       makeLog(0),
 | 
					 | 
				
			||||||
			gasCost:       makeGasLog(0),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryLog,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LOG1: {
 | 
					 | 
				
			||||||
			execute:       makeLog(1),
 | 
					 | 
				
			||||||
			gasCost:       makeGasLog(1),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(3, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryLog,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LOG2: {
 | 
					 | 
				
			||||||
			execute:       makeLog(2),
 | 
					 | 
				
			||||||
			gasCost:       makeGasLog(2),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(4, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryLog,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LOG3: {
 | 
					 | 
				
			||||||
			execute:       makeLog(3),
 | 
					 | 
				
			||||||
			gasCost:       makeGasLog(3),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(5, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryLog,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		LOG4: {
 | 
					 | 
				
			||||||
			execute:       makeLog(4),
 | 
					 | 
				
			||||||
			gasCost:       makeGasLog(4),
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(6, 0),
 | 
					 | 
				
			||||||
			memorySize:    memoryLog,
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP1: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(1),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(2, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP2: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(2),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(3, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP3: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(3),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(4, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP4: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(4),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(5, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP5: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(5),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(6, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP6: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(6),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(7, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP7: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(7),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(8, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP8: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(8),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(9, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP9: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(9),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(10, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP10: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(10),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(11, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP11: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(11),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(12, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP12: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(12),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(13, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP13: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(13),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(14, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP14: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(14),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(15, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP15: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(15),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(16, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		SWAP16: {
 | 
					 | 
				
			||||||
			execute:       makeSwap(16),
 | 
					 | 
				
			||||||
			gasCost:       gasSwap,
 | 
					 | 
				
			||||||
			validateStack: makeStackFunc(17, 0),
 | 
					 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		PUSH1: {
 | 
							PUSH1: {
 | 
				
			||||||
@@ -765,97 +588,271 @@ func NewJumpTable() [256]operation {
 | 
				
			|||||||
		DUP1: {
 | 
							DUP1: {
 | 
				
			||||||
			execute:       makeDup(1),
 | 
								execute:       makeDup(1),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(1, 1),
 | 
								validateStack: makeDupStackFunc(1),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP2: {
 | 
							DUP2: {
 | 
				
			||||||
			execute:       makeDup(2),
 | 
								execute:       makeDup(2),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(2, 1),
 | 
								validateStack: makeDupStackFunc(2),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP3: {
 | 
							DUP3: {
 | 
				
			||||||
			execute:       makeDup(3),
 | 
								execute:       makeDup(3),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(3, 1),
 | 
								validateStack: makeDupStackFunc(3),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP4: {
 | 
							DUP4: {
 | 
				
			||||||
			execute:       makeDup(4),
 | 
								execute:       makeDup(4),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(4, 1),
 | 
								validateStack: makeDupStackFunc(4),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP5: {
 | 
							DUP5: {
 | 
				
			||||||
			execute:       makeDup(5),
 | 
								execute:       makeDup(5),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(5, 1),
 | 
								validateStack: makeDupStackFunc(5),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP6: {
 | 
							DUP6: {
 | 
				
			||||||
			execute:       makeDup(6),
 | 
								execute:       makeDup(6),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(6, 1),
 | 
								validateStack: makeDupStackFunc(6),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP7: {
 | 
							DUP7: {
 | 
				
			||||||
			execute:       makeDup(7),
 | 
								execute:       makeDup(7),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(7, 1),
 | 
								validateStack: makeDupStackFunc(7),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP8: {
 | 
							DUP8: {
 | 
				
			||||||
			execute:       makeDup(8),
 | 
								execute:       makeDup(8),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(8, 1),
 | 
								validateStack: makeDupStackFunc(8),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP9: {
 | 
							DUP9: {
 | 
				
			||||||
			execute:       makeDup(9),
 | 
								execute:       makeDup(9),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(9, 1),
 | 
								validateStack: makeDupStackFunc(9),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP10: {
 | 
							DUP10: {
 | 
				
			||||||
			execute:       makeDup(10),
 | 
								execute:       makeDup(10),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(10, 1),
 | 
								validateStack: makeDupStackFunc(10),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP11: {
 | 
							DUP11: {
 | 
				
			||||||
			execute:       makeDup(11),
 | 
								execute:       makeDup(11),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(11, 1),
 | 
								validateStack: makeDupStackFunc(11),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP12: {
 | 
							DUP12: {
 | 
				
			||||||
			execute:       makeDup(12),
 | 
								execute:       makeDup(12),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(12, 1),
 | 
								validateStack: makeDupStackFunc(12),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP13: {
 | 
							DUP13: {
 | 
				
			||||||
			execute:       makeDup(13),
 | 
								execute:       makeDup(13),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(13, 1),
 | 
								validateStack: makeDupStackFunc(13),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP14: {
 | 
							DUP14: {
 | 
				
			||||||
			execute:       makeDup(14),
 | 
								execute:       makeDup(14),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(14, 1),
 | 
								validateStack: makeDupStackFunc(14),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP15: {
 | 
							DUP15: {
 | 
				
			||||||
			execute:       makeDup(15),
 | 
								execute:       makeDup(15),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(15, 1),
 | 
								validateStack: makeDupStackFunc(15),
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		DUP16: {
 | 
							DUP16: {
 | 
				
			||||||
			execute:       makeDup(16),
 | 
								execute:       makeDup(16),
 | 
				
			||||||
			gasCost:       gasDup,
 | 
								gasCost:       gasDup,
 | 
				
			||||||
			validateStack: makeStackFunc(16, 1),
 | 
								validateStack: makeDupStackFunc(16),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP1: {
 | 
				
			||||||
 | 
								execute:       makeSwap(1),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(2),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP2: {
 | 
				
			||||||
 | 
								execute:       makeSwap(2),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(3),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP3: {
 | 
				
			||||||
 | 
								execute:       makeSwap(3),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(4),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP4: {
 | 
				
			||||||
 | 
								execute:       makeSwap(4),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(5),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP5: {
 | 
				
			||||||
 | 
								execute:       makeSwap(5),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(6),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP6: {
 | 
				
			||||||
 | 
								execute:       makeSwap(6),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(7),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP7: {
 | 
				
			||||||
 | 
								execute:       makeSwap(7),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(8),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP8: {
 | 
				
			||||||
 | 
								execute:       makeSwap(8),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(9),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP9: {
 | 
				
			||||||
 | 
								execute:       makeSwap(9),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(10),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP10: {
 | 
				
			||||||
 | 
								execute:       makeSwap(10),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(11),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP11: {
 | 
				
			||||||
 | 
								execute:       makeSwap(11),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(12),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP12: {
 | 
				
			||||||
 | 
								execute:       makeSwap(12),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(13),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP13: {
 | 
				
			||||||
 | 
								execute:       makeSwap(13),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(14),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP14: {
 | 
				
			||||||
 | 
								execute:       makeSwap(14),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(15),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP15: {
 | 
				
			||||||
 | 
								execute:       makeSwap(15),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(16),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SWAP16: {
 | 
				
			||||||
 | 
								execute:       makeSwap(16),
 | 
				
			||||||
 | 
								gasCost:       gasSwap,
 | 
				
			||||||
 | 
								validateStack: makeSwapStackFunc(17),
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LOG0: {
 | 
				
			||||||
 | 
								execute:       makeLog(0),
 | 
				
			||||||
 | 
								gasCost:       makeGasLog(0),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
 | 
								memorySize:    memoryLog,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LOG1: {
 | 
				
			||||||
 | 
								execute:       makeLog(1),
 | 
				
			||||||
 | 
								gasCost:       makeGasLog(1),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(3, -3),
 | 
				
			||||||
 | 
								memorySize:    memoryLog,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LOG2: {
 | 
				
			||||||
 | 
								execute:       makeLog(2),
 | 
				
			||||||
 | 
								gasCost:       makeGasLog(2),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(4, -4),
 | 
				
			||||||
 | 
								memorySize:    memoryLog,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LOG3: {
 | 
				
			||||||
 | 
								execute:       makeLog(3),
 | 
				
			||||||
 | 
								gasCost:       makeGasLog(3),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(5, -5),
 | 
				
			||||||
 | 
								memorySize:    memoryLog,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							LOG4: {
 | 
				
			||||||
 | 
								execute:       makeLog(4),
 | 
				
			||||||
 | 
								gasCost:       makeGasLog(4),
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(6, -6),
 | 
				
			||||||
 | 
								memorySize:    memoryLog,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							CREATE: {
 | 
				
			||||||
 | 
								execute:       opCreate,
 | 
				
			||||||
 | 
								gasCost:       gasCreate,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(3, -2),
 | 
				
			||||||
 | 
								memorySize:    memoryCreate,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							CALL: {
 | 
				
			||||||
 | 
								execute:       opCall,
 | 
				
			||||||
 | 
								gasCost:       gasCall,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(7, -6),
 | 
				
			||||||
 | 
								memorySize:    memoryCall,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							CALLCODE: {
 | 
				
			||||||
 | 
								execute:       opCallCode,
 | 
				
			||||||
 | 
								gasCost:       gasCallCode,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(7, -6),
 | 
				
			||||||
 | 
								memorySize:    memoryCall,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							RETURN: {
 | 
				
			||||||
 | 
								execute:       opReturn,
 | 
				
			||||||
 | 
								gasCost:       gasReturn,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(2, -2),
 | 
				
			||||||
 | 
								memorySize:    memoryReturn,
 | 
				
			||||||
 | 
								halts:         true,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							DELEGATECALL: {
 | 
				
			||||||
 | 
								execute:       opDelegateCall,
 | 
				
			||||||
 | 
								gasCost:       gasDelegateCall,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(6, -5),
 | 
				
			||||||
 | 
								memorySize:    memoryDelegateCall,
 | 
				
			||||||
 | 
								valid:         true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							SELFDESTRUCT: {
 | 
				
			||||||
 | 
								execute:       opSuicide,
 | 
				
			||||||
 | 
								gasCost:       gasSuicide,
 | 
				
			||||||
 | 
								validateStack: makeStackFunc(1, -1),
 | 
				
			||||||
 | 
								halts:         true,
 | 
				
			||||||
			valid:         true,
 | 
								valid:         true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ func TestStoreCapture(t *testing.T) {
 | 
				
			|||||||
		logger   = NewStructLogger(nil)
 | 
							logger   = NewStructLogger(nil)
 | 
				
			||||||
		mem      = NewMemory()
 | 
							mem      = NewMemory()
 | 
				
			||||||
		stack    = newstack()
 | 
							stack    = newstack()
 | 
				
			||||||
		contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 0)
 | 
							contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), new(big.Int))
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	stack.push(big.NewInt(1))
 | 
						stack.push(big.NewInt(1))
 | 
				
			||||||
	stack.push(big.NewInt(0))
 | 
						stack.push(big.NewInt(0))
 | 
				
			||||||
@@ -78,7 +78,7 @@ func TestStorageCapture(t *testing.T) {
 | 
				
			|||||||
	t.Skip("implementing this function is difficult. it requires all sort of interfaces to be implemented which isn't trivial. The value (the actual test) isn't worth it")
 | 
						t.Skip("implementing this function is difficult. it requires all sort of interfaces to be implemented which isn't trivial. The value (the actual test) isn't worth it")
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		ref      = &dummyContractRef{}
 | 
							ref      = &dummyContractRef{}
 | 
				
			||||||
		contract = NewContract(ref, ref, new(big.Int), 0)
 | 
							contract = NewContract(ref, ref, new(big.Int), new(big.Int))
 | 
				
			||||||
		env      = NewEVM(Context{}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
 | 
							env      = NewEVM(Context{}, dummyStateDB{ref: ref}, params.TestChainConfig, Config{EnableJit: false, ForceJit: false})
 | 
				
			||||||
		logger   = NewStructLogger(nil)
 | 
							logger   = NewStructLogger(nil)
 | 
				
			||||||
		mem      = NewMemory()
 | 
							mem      = NewMemory()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,12 +20,11 @@ import "fmt"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Memory implements a simple memory model for the ethereum virtual machine.
 | 
					// Memory implements a simple memory model for the ethereum virtual machine.
 | 
				
			||||||
type Memory struct {
 | 
					type Memory struct {
 | 
				
			||||||
	store       []byte
 | 
						store []byte
 | 
				
			||||||
	lastGasCost uint64
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewMemory() *Memory {
 | 
					func NewMemory() *Memory {
 | 
				
			||||||
	return &Memory{}
 | 
						return &Memory{nil}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set sets offset + size to value
 | 
					// Set sets offset + size to value
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -202,7 +202,7 @@ const (
 | 
				
			|||||||
	RETURN
 | 
						RETURN
 | 
				
			||||||
	DELEGATECALL
 | 
						DELEGATECALL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SUICIDE = 0xff
 | 
						SELFDESTRUCT = 0xff
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Since the opcodes aren't all in order we can't use a regular slice
 | 
					// Since the opcodes aren't all in order we can't use a regular slice
 | 
				
			||||||
@@ -355,7 +355,7 @@ var opCodeToString = map[OpCode]string{
 | 
				
			|||||||
	RETURN:       "RETURN",
 | 
						RETURN:       "RETURN",
 | 
				
			||||||
	CALLCODE:     "CALLCODE",
 | 
						CALLCODE:     "CALLCODE",
 | 
				
			||||||
	DELEGATECALL: "DELEGATECALL",
 | 
						DELEGATECALL: "DELEGATECALL",
 | 
				
			||||||
	SUICIDE:      "SUICIDE",
 | 
						SELFDESTRUCT: "SELFDESTRUCT",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PUSH: "PUSH",
 | 
						PUSH: "PUSH",
 | 
				
			||||||
	DUP:  "DUP",
 | 
						DUP:  "DUP",
 | 
				
			||||||
@@ -501,7 +501,7 @@ var stringToOp = map[string]OpCode{
 | 
				
			|||||||
	"CALL":         CALL,
 | 
						"CALL":         CALL,
 | 
				
			||||||
	"RETURN":       RETURN,
 | 
						"RETURN":       RETURN,
 | 
				
			||||||
	"CALLCODE":     CALLCODE,
 | 
						"CALLCODE":     CALLCODE,
 | 
				
			||||||
	"SUICIDE":      SUICIDE,
 | 
						"SELFDESTRUCT": SELFDESTRUCT,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func StringToOp(str string) OpCode {
 | 
					func StringToOp(str string) OpCode {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ func NewEnv(cfg *Config, state *state.StateDB) *vm.EVM {
 | 
				
			|||||||
		BlockNumber: cfg.BlockNumber,
 | 
							BlockNumber: cfg.BlockNumber,
 | 
				
			||||||
		Time:        cfg.Time,
 | 
							Time:        cfg.Time,
 | 
				
			||||||
		Difficulty:  cfg.Difficulty,
 | 
							Difficulty:  cfg.Difficulty,
 | 
				
			||||||
		GasLimit:    new(big.Int).SetUint64(cfg.GasLimit),
 | 
							GasLimit:    cfg.GasLimit,
 | 
				
			||||||
		GasPrice:    new(big.Int),
 | 
							GasPrice:    new(big.Int),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@
 | 
				
			|||||||
package runtime
 | 
					package runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"math"
 | 
					 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +37,7 @@ type Config struct {
 | 
				
			|||||||
	Coinbase    common.Address
 | 
						Coinbase    common.Address
 | 
				
			||||||
	BlockNumber *big.Int
 | 
						BlockNumber *big.Int
 | 
				
			||||||
	Time        *big.Int
 | 
						Time        *big.Int
 | 
				
			||||||
	GasLimit    uint64
 | 
						GasLimit    *big.Int
 | 
				
			||||||
	GasPrice    *big.Int
 | 
						GasPrice    *big.Int
 | 
				
			||||||
	Value       *big.Int
 | 
						Value       *big.Int
 | 
				
			||||||
	DisableJit  bool // "disable" so it's enabled by default
 | 
						DisableJit  bool // "disable" so it's enabled by default
 | 
				
			||||||
@@ -69,8 +68,8 @@ func setDefaults(cfg *Config) {
 | 
				
			|||||||
	if cfg.Time == nil {
 | 
						if cfg.Time == nil {
 | 
				
			||||||
		cfg.Time = big.NewInt(time.Now().Unix())
 | 
							cfg.Time = big.NewInt(time.Now().Unix())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cfg.GasLimit == 0 {
 | 
						if cfg.GasLimit == nil {
 | 
				
			||||||
		cfg.GasLimit = math.MaxUint64
 | 
							cfg.GasLimit = new(big.Int).Set(common.MaxBig)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cfg.GasPrice == nil {
 | 
						if cfg.GasPrice == nil {
 | 
				
			||||||
		cfg.GasPrice = new(big.Int)
 | 
							cfg.GasPrice = new(big.Int)
 | 
				
			||||||
@@ -113,7 +112,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
 | 
				
			|||||||
	receiver.SetCode(crypto.Keccak256Hash(code), code)
 | 
						receiver.SetCode(crypto.Keccak256Hash(code), code)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Call the code with the given configuration.
 | 
						// Call the code with the given configuration.
 | 
				
			||||||
	ret, _, err := vmenv.Call(
 | 
						ret, err := vmenv.Call(
 | 
				
			||||||
		sender,
 | 
							sender,
 | 
				
			||||||
		receiver.Address(),
 | 
							receiver.Address(),
 | 
				
			||||||
		input,
 | 
							input,
 | 
				
			||||||
@@ -141,13 +140,12 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, error) {
 | 
				
			|||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Call the code with the given configuration.
 | 
						// Call the code with the given configuration.
 | 
				
			||||||
	code, address, _, err := vmenv.Create(
 | 
						return vmenv.Create(
 | 
				
			||||||
		sender,
 | 
							sender,
 | 
				
			||||||
		input,
 | 
							input,
 | 
				
			||||||
		cfg.GasLimit,
 | 
							cfg.GasLimit,
 | 
				
			||||||
		cfg.Value,
 | 
							cfg.Value,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return code, address, err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Call executes the code given by the contract's address. It will return the
 | 
					// Call executes the code given by the contract's address. It will return the
 | 
				
			||||||
@@ -162,7 +160,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	sender := cfg.State.GetOrNewStateObject(cfg.Origin)
 | 
						sender := cfg.State.GetOrNewStateObject(cfg.Origin)
 | 
				
			||||||
	// Call the code with the given configuration.
 | 
						// Call the code with the given configuration.
 | 
				
			||||||
	ret, _, err := vmenv.Call(
 | 
						ret, err := vmenv.Call(
 | 
				
			||||||
		sender,
 | 
							sender,
 | 
				
			||||||
		address,
 | 
							address,
 | 
				
			||||||
		input,
 | 
							input,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,8 @@ func TestDefaults(t *testing.T) {
 | 
				
			|||||||
	if cfg.Time == nil {
 | 
						if cfg.Time == nil {
 | 
				
			||||||
		t.Error("expected time to be non nil")
 | 
							t.Error("expected time to be non nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cfg.GasLimit == 0 {
 | 
						if cfg.GasLimit == nil {
 | 
				
			||||||
		t.Error("didn't expect gaslimit to be zero")
 | 
							t.Error("expected time to be non nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cfg.GasPrice == nil {
 | 
						if cfg.GasPrice == nil {
 | 
				
			||||||
		t.Error("expected time to be non nil")
 | 
							t.Error("expected time to be non nil")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,15 +6,23 @@ import (
 | 
				
			|||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeStackFunc(pop, push int) stackValidationFunc {
 | 
					func makeStackFunc(pop, diff int) stackValidationFunc {
 | 
				
			||||||
	return func(stack *Stack) error {
 | 
						return func(stack *Stack) error {
 | 
				
			||||||
		if err := stack.require(pop); err != nil {
 | 
							if err := stack.require(pop); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if push > 0 && stack.len()-pop+push > int(params.StackLimit) {
 | 
							if int64(stack.len()+diff) > params.StackLimit.Int64() {
 | 
				
			||||||
			return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit)
 | 
								return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func makeDupStackFunc(n int) stackValidationFunc {
 | 
				
			||||||
 | 
						return makeStackFunc(n, 1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func makeSwapStackFunc(n int) stackValidationFunc {
 | 
				
			||||||
 | 
						return makeStackFunc(n, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
// Copyright 2017 The go-ethereum Authors
 | 
					// Copyright 2014 The go-ethereum Authors
 | 
				
			||||||
// This file is part of the go-ethereum library.
 | 
					// This file is part of the go-ethereum library.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
 | 
					// The go-ethereum library is free software: you can redistribute it and/or modify
 | 
				
			||||||
@@ -16,34 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package vm
 | 
					package vm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "math/big"
 | 
					// VirtualMachine is an EVM interface
 | 
				
			||||||
 | 
					type VirtualMachine interface {
 | 
				
			||||||
var checkVal = big.NewInt(-42)
 | 
						Run(*Contract, []byte) ([]byte, error)
 | 
				
			||||||
 | 
					 | 
				
			||||||
// intPool is a pool of big integers that
 | 
					 | 
				
			||||||
// can be reused for all big.Int operations.
 | 
					 | 
				
			||||||
type intPool struct {
 | 
					 | 
				
			||||||
	pool *Stack
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newIntPool() *intPool {
 | 
					 | 
				
			||||||
	return &intPool{pool: newstack()}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (p *intPool) get() *big.Int {
 | 
					 | 
				
			||||||
	if p.pool.len() > 0 {
 | 
					 | 
				
			||||||
		return p.pool.pop()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return new(big.Int)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
func (p *intPool) put(is ...*big.Int) {
 | 
					 | 
				
			||||||
	for _, i := range is {
 | 
					 | 
				
			||||||
		// verifyPool is a build flag. Pool verification makes sure the integrity
 | 
					 | 
				
			||||||
		// of the integer pool by comparing values to a default value.
 | 
					 | 
				
			||||||
		if verifyPool {
 | 
					 | 
				
			||||||
			i.Set(checkVal)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		p.pool.push(i)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -23,7 +23,6 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common/math"
 | 
					 | 
				
			||||||
	"github.com/ethereum/go-ethereum/crypto"
 | 
						"github.com/ethereum/go-ethereum/crypto"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/logger"
 | 
						"github.com/ethereum/go-ethereum/logger"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/logger/glog"
 | 
						"github.com/ethereum/go-ethereum/logger/glog"
 | 
				
			||||||
@@ -61,7 +60,6 @@ type Interpreter struct {
 | 
				
			|||||||
	env      *EVM
 | 
						env      *EVM
 | 
				
			||||||
	cfg      Config
 | 
						cfg      Config
 | 
				
			||||||
	gasTable params.GasTable
 | 
						gasTable params.GasTable
 | 
				
			||||||
	intPool  *intPool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewInterpreter returns a new instance of the Interpreter.
 | 
					// NewInterpreter returns a new instance of the Interpreter.
 | 
				
			||||||
@@ -77,7 +75,6 @@ func NewInterpreter(env *EVM, cfg Config) *Interpreter {
 | 
				
			|||||||
		env:      env,
 | 
							env:      env,
 | 
				
			||||||
		cfg:      cfg,
 | 
							cfg:      cfg,
 | 
				
			||||||
		gasTable: env.ChainConfig().GasTable(env.BlockNumber),
 | 
							gasTable: env.ChainConfig().GasTable(env.BlockNumber),
 | 
				
			||||||
		intPool:  newIntPool(),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -109,18 +106,14 @@ func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err e
 | 
				
			|||||||
		// For optimisation reason we're using uint64 as the program counter.
 | 
							// For optimisation reason we're using uint64 as the program counter.
 | 
				
			||||||
		// It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Practically much less so feasible.
 | 
							// It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Practically much less so feasible.
 | 
				
			||||||
		pc   = uint64(0) // program counter
 | 
							pc   = uint64(0) // program counter
 | 
				
			||||||
		cost uint64
 | 
							cost *big.Int
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	contract.Input = input
 | 
						contract.Input = input
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
 | 
						// User defer pattern to check for an error and, based on the error being nil or not, use all gas and return.
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if err != nil && evm.cfg.Debug {
 | 
							if err != nil && evm.cfg.Debug {
 | 
				
			||||||
			// XXX For debugging
 | 
								evm.cfg.Tracer.CaptureState(evm.env, pc, op, contract.Gas, cost, mem, stack, contract, evm.env.depth, err)
 | 
				
			||||||
			//fmt.Printf("%04d: %8v    cost = %-8d stack = %-8d ERR = %v\n", pc, op, cost, stack.len(), err)
 | 
					 | 
				
			||||||
			// TODO update the tracer
 | 
					 | 
				
			||||||
			g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
 | 
					 | 
				
			||||||
			evm.cfg.Tracer.CaptureState(evm.env, pc, op, g, c, mem, stack, contract, evm.env.depth, err)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,7 +126,7 @@ func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err e
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The Interpreter main run loop (contextual). This loop runs until either an
 | 
						// The Interpreter main run loop (contextual). This loop runs until either an
 | 
				
			||||||
	// explicit STOP, RETURN or SUICIDE is executed, an error occurred during
 | 
						// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
 | 
				
			||||||
	// the execution of one of the operations or until the evm.done is set by
 | 
						// the execution of one of the operations or until the evm.done is set by
 | 
				
			||||||
	// the parent context.Context.
 | 
						// the parent context.Context.
 | 
				
			||||||
	for atomic.LoadInt32(&evm.env.abort) == 0 {
 | 
						for atomic.LoadInt32(&evm.env.abort) == 0 {
 | 
				
			||||||
@@ -154,47 +147,34 @@ func (evm *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err e
 | 
				
			|||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var memorySize uint64
 | 
							var memorySize *big.Int
 | 
				
			||||||
		// calculate the new memory size and expand the memory to fit
 | 
							// calculate the new memory size and expand the memory to fit
 | 
				
			||||||
		// the operation
 | 
							// the operation
 | 
				
			||||||
		if operation.memorySize != nil {
 | 
							if operation.memorySize != nil {
 | 
				
			||||||
			memSize, overflow := bigUint64(operation.memorySize(stack))
 | 
								memorySize = operation.memorySize(stack)
 | 
				
			||||||
			if overflow {
 | 
					 | 
				
			||||||
				return nil, errGasUintOverflow
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// memory is expanded in words of 32 bytes. Gas
 | 
								// memory is expanded in words of 32 bytes. Gas
 | 
				
			||||||
			// is also calculated in words.
 | 
								// is also calculated in words.
 | 
				
			||||||
			if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow {
 | 
								memorySize.Mul(toWordSize(memorySize), big.NewInt(32))
 | 
				
			||||||
				return nil, errGasUintOverflow
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !evm.cfg.DisableGasMetering {
 | 
							if !evm.cfg.DisableGasMetering {
 | 
				
			||||||
			// consume the gas and return an error if not enough gas is available.
 | 
								// consume the gas and return an error if not enough gas is available.
 | 
				
			||||||
			// cost is explicitly set so that the capture state defer method cas get the proper cost
 | 
								// cost is explicitly set so that the capture state defer method cas get the proper cost
 | 
				
			||||||
			cost, err = operation.gasCost(evm.gasTable, evm.env, contract, stack, mem, memorySize)
 | 
								cost = operation.gasCost(evm.gasTable, evm.env, contract, stack, mem, memorySize)
 | 
				
			||||||
			if err != nil || !contract.UseGas(cost) {
 | 
								if !contract.UseGas(cost) {
 | 
				
			||||||
				return nil, ErrOutOfGas
 | 
									return nil, ErrOutOfGas
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if memorySize > 0 {
 | 
							if memorySize != nil {
 | 
				
			||||||
			mem.Resize(memorySize)
 | 
								mem.Resize(memorySize.Uint64())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if evm.cfg.Debug {
 | 
							if evm.cfg.Debug {
 | 
				
			||||||
			g, c := new(big.Int).SetUint64(contract.Gas), new(big.Int).SetUint64(cost)
 | 
								evm.cfg.Tracer.CaptureState(evm.env, pc, op, contract.Gas, cost, mem, stack, contract, evm.env.depth, err)
 | 
				
			||||||
			evm.cfg.Tracer.CaptureState(evm.env, pc, op, g, c, mem, stack, contract, evm.env.depth, err)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// XXX For debugging
 | 
					 | 
				
			||||||
		//fmt.Printf("%04d: %8v    cost = %-8d stack = %-8d\n", pc, op, cost, stack.len())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// execute the operation
 | 
							// execute the operation
 | 
				
			||||||
		res, err := operation.execute(&pc, evm.env, contract, mem, stack)
 | 
							res, err := operation.execute(&pc, evm.env, contract, mem, stack)
 | 
				
			||||||
		// verifyPool is a build flag. Pool verification makes sure the integrity
 | 
					 | 
				
			||||||
		// of the integer pool by comparing values to a default value.
 | 
					 | 
				
			||||||
		if verifyPool {
 | 
					 | 
				
			||||||
			verifyIntegerPool(evm.intPool)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case err != nil:
 | 
							case err != nil:
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
@@ -106,14 +106,14 @@ func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int {
 | 
				
			|||||||
	return b.eth.blockchain.GetTdByHash(blockHash)
 | 
						return b.eth.blockchain.GetTdByHash(blockHash)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *EthApiBackend) GetEVM(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
 | 
					func (b *EthApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
 | 
				
			||||||
	statedb := state.(EthApiState).state
 | 
						statedb := state.(EthApiState).state
 | 
				
			||||||
	from := statedb.GetOrNewStateObject(msg.From())
 | 
						from := statedb.GetOrNewStateObject(msg.From())
 | 
				
			||||||
	from.SetBalance(common.MaxBig)
 | 
						from.SetBalance(common.MaxBig)
 | 
				
			||||||
	vmError := func() error { return nil }
 | 
						vmError := func() error { return nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context := core.NewEVMContext(msg, header, b.eth.BlockChain())
 | 
						context := core.NewEVMContext(msg, header, b.eth.BlockChain())
 | 
				
			||||||
	return vm.NewEVM(context, statedb, b.eth.chainConfig, vmCfg), vmError, nil
 | 
						return vm.NewEVM(context, statedb, b.eth.chainConfig, vm.Config{}), vmError, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
 | 
					func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,7 @@ func (b *ContractBackend) PendingCodeAt(ctx context.Context, contract common.Add
 | 
				
			|||||||
// against the pending block, not the stable head of the chain.
 | 
					// against the pending block, not the stable head of the chain.
 | 
				
			||||||
func (b *ContractBackend) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNum *big.Int) ([]byte, error) {
 | 
					func (b *ContractBackend) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNum *big.Int) ([]byte, error) {
 | 
				
			||||||
	out, err := b.bcapi.Call(ctx, toCallArgs(msg), toBlockNumber(blockNum))
 | 
						out, err := b.bcapi.Call(ctx, toCallArgs(msg), toBlockNumber(blockNum))
 | 
				
			||||||
	return out, err
 | 
						return common.FromHex(out), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ContractCall implements bind.ContractCaller executing an Ethereum contract
 | 
					// ContractCall implements bind.ContractCaller executing an Ethereum contract
 | 
				
			||||||
@@ -77,7 +77,7 @@ func (b *ContractBackend) CallContract(ctx context.Context, msg ethereum.CallMsg
 | 
				
			|||||||
// against the pending block, not the stable head of the chain.
 | 
					// against the pending block, not the stable head of the chain.
 | 
				
			||||||
func (b *ContractBackend) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) {
 | 
					func (b *ContractBackend) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) {
 | 
				
			||||||
	out, err := b.bcapi.Call(ctx, toCallArgs(msg), rpc.PendingBlockNumber)
 | 
						out, err := b.bcapi.Call(ctx, toCallArgs(msg), rpc.PendingBlockNumber)
 | 
				
			||||||
	return out, err
 | 
						return common.FromHex(out), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs {
 | 
					func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,12 +49,12 @@ var (
 | 
				
			|||||||
	MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request
 | 
						MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request
 | 
				
			||||||
	MaxStateFetch   = 384 // Amount of node state values to allow fetching per request
 | 
						MaxStateFetch   = 384 // Amount of node state values to allow fetching per request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MaxForkAncestry  = 3 * params.EpochDuration // Maximum chain reorganisation
 | 
						MaxForkAncestry  = 3 * params.EpochDuration.Uint64() // Maximum chain reorganisation
 | 
				
			||||||
	rttMinEstimate   = 2 * time.Second          // Minimum round-trip time to target for download requests
 | 
						rttMinEstimate   = 2 * time.Second                   // Minimum round-trip time to target for download requests
 | 
				
			||||||
	rttMaxEstimate   = 20 * time.Second         // Maximum rount-trip time to target for download requests
 | 
						rttMaxEstimate   = 20 * time.Second                  // Maximum rount-trip time to target for download requests
 | 
				
			||||||
	rttMinConfidence = 0.1                      // Worse confidence factor in our estimated RTT value
 | 
						rttMinConfidence = 0.1                               // Worse confidence factor in our estimated RTT value
 | 
				
			||||||
	ttlScaling       = 3                        // Constant scaling factor for RTT -> TTL conversion
 | 
						ttlScaling       = 3                                 // Constant scaling factor for RTT -> TTL conversion
 | 
				
			||||||
	ttlLimit         = time.Minute              // Maximum TTL allowance to prevent reaching crazy timeouts
 | 
						ttlLimit         = time.Minute                       // Maximum TTL allowance to prevent reaching crazy timeouts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qosTuningPeers   = 5    // Number of peers to tune based on (best peers)
 | 
						qosTuningPeers   = 5    // Number of peers to tune based on (best peers)
 | 
				
			||||||
	qosConfidenceCap = 10   // Number of peers above which not to modify RTT confidence
 | 
						qosConfidenceCap = 10   // Number of peers above which not to modify RTT confidence
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,7 +119,7 @@ func (dl *downloadTester) makeChain(n int, seed byte, parent *types.Block, paren
 | 
				
			|||||||
		// If the block number is multiple of 3, send a bonus transaction to the miner
 | 
							// If the block number is multiple of 3, send a bonus transaction to the miner
 | 
				
			||||||
		if parent == dl.genesis && i%3 == 0 {
 | 
							if parent == dl.genesis && i%3 == 0 {
 | 
				
			||||||
			signer := types.MakeSigner(params.TestChainConfig, block.Number())
 | 
								signer := types.MakeSigner(params.TestChainConfig, block.Number())
 | 
				
			||||||
			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), new(big.Int).SetUint64(params.TxGas), nil, nil), signer, testKey)
 | 
								tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				panic(err)
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common
 | 
				
			|||||||
		// If the block number is multiple of 3, send a bonus transaction to the miner
 | 
							// If the block number is multiple of 3, send a bonus transaction to the miner
 | 
				
			||||||
		if parent == genesis && i%3 == 0 {
 | 
							if parent == genesis && i%3 == 0 {
 | 
				
			||||||
			signer := types.MakeSigner(params.TestChainConfig, block.Number())
 | 
								signer := types.MakeSigner(params.TestChainConfig, block.Number())
 | 
				
			||||||
			tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), new(big.Int).SetUint64(params.TxGas), nil, nil), signer, testKey)
 | 
								tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, nil, nil), signer, testKey)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				panic(err)
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,8 +36,6 @@ import (
 | 
				
			|||||||
	"github.com/ethereum/go-ethereum/params"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Tests that protocol versions and modes of operations are matched up properly.
 | 
					// Tests that protocol versions and modes of operations are matched up properly.
 | 
				
			||||||
func TestProtocolCompatibility(t *testing.T) {
 | 
					func TestProtocolCompatibility(t *testing.T) {
 | 
				
			||||||
	// Define the compatibility chart
 | 
						// Define the compatibility chart
 | 
				
			||||||
@@ -314,13 +312,13 @@ func testGetNodeData(t *testing.T, protocol int) {
 | 
				
			|||||||
		switch i {
 | 
							switch i {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			// In block 1, the test bank sends account #1 some ether.
 | 
								// In block 1, the test bank sends account #1 some ether.
 | 
				
			||||||
			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey)
 | 
								tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
			block.AddTx(tx)
 | 
								block.AddTx(tx)
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
			// In block 2, the test bank sends some more ether to account #1.
 | 
								// In block 2, the test bank sends some more ether to account #1.
 | 
				
			||||||
			// acc1Addr passes it on to account #2.
 | 
								// acc1Addr passes it on to account #2.
 | 
				
			||||||
			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey)
 | 
								tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key)
 | 
								tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
 | 
				
			||||||
			block.AddTx(tx1)
 | 
								block.AddTx(tx1)
 | 
				
			||||||
			block.AddTx(tx2)
 | 
								block.AddTx(tx2)
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
@@ -406,13 +404,13 @@ func testGetReceipt(t *testing.T, protocol int) {
 | 
				
			|||||||
		switch i {
 | 
							switch i {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			// In block 1, the test bank sends account #1 some ether.
 | 
								// In block 1, the test bank sends account #1 some ether.
 | 
				
			||||||
			tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey)
 | 
								tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
			block.AddTx(tx)
 | 
								block.AddTx(tx)
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
			// In block 2, the test bank sends some more ether to account #1.
 | 
								// In block 2, the test bank sends some more ether to account #1.
 | 
				
			||||||
			// acc1Addr passes it on to account #2.
 | 
								// acc1Addr passes it on to account #2.
 | 
				
			||||||
			tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey)
 | 
								tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBank.Address), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
			tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key)
 | 
								tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
 | 
				
			||||||
			block.AddTx(tx1)
 | 
								block.AddTx(tx1)
 | 
				
			||||||
			block.AddTx(tx2)
 | 
								block.AddTx(tx2)
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,8 +48,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const defaultGas = 90000
 | 
					const defaultGas = 90000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var emptyHex = "0x"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PublicEthereumAPI provides an API to access Ethereum related information.
 | 
					// PublicEthereumAPI provides an API to access Ethereum related information.
 | 
				
			||||||
// It offers only methods that operate on public data that is freely available to anyone.
 | 
					// It offers only methods that operate on public data that is freely available to anyone.
 | 
				
			||||||
type PublicEthereumAPI struct {
 | 
					type PublicEthereumAPI struct {
 | 
				
			||||||
@@ -576,12 +574,12 @@ type CallArgs struct {
 | 
				
			|||||||
	Data     hexutil.Bytes   `json:"data"`
 | 
						Data     hexutil.Bytes   `json:"data"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, *big.Int, error) {
 | 
					func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, *big.Int, error) {
 | 
				
			||||||
	defer func(start time.Time) { glog.V(logger.Debug).Infof("call took %v", time.Since(start)) }(time.Now())
 | 
						defer func(start time.Time) { glog.V(logger.Debug).Infof("call took %v", time.Since(start)) }(time.Now())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
 | 
						state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
 | 
				
			||||||
	if state == nil || err != nil {
 | 
						if state == nil || err != nil {
 | 
				
			||||||
		return nil, common.Big0, err
 | 
							return "0x", common.Big0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Set sender address or use a default if none specified
 | 
						// Set sender address or use a default if none specified
 | 
				
			||||||
	addr := args.From
 | 
						addr := args.From
 | 
				
			||||||
@@ -591,59 +589,40 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
 | 
				
			|||||||
				addr = accounts[0].Address
 | 
									addr = accounts[0].Address
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							addr = args.From
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Set default gas & gas price if none were set
 | 
						// Set default gas & gas price if none were set
 | 
				
			||||||
	gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt()
 | 
						gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt()
 | 
				
			||||||
	if gas.BitLen() == 0 {
 | 
						if gas.Cmp(common.Big0) == 0 {
 | 
				
			||||||
		gas = big.NewInt(50000000)
 | 
							gas = big.NewInt(50000000)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if gasPrice.BitLen() == 0 {
 | 
						if gasPrice.Cmp(common.Big0) == 0 {
 | 
				
			||||||
		gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
 | 
							gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Create new call message
 | 
					 | 
				
			||||||
	msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false)
 | 
						msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup context so it may be cancelled the call has completed
 | 
						// Execute the call and return
 | 
				
			||||||
	// or, in case of unmetered gas, setup a context with a timeout.
 | 
						vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header)
 | 
				
			||||||
	var cancel context.CancelFunc
 | 
					 | 
				
			||||||
	if vmCfg.DisableGasMetering {
 | 
					 | 
				
			||||||
		ctx, cancel = context.WithTimeout(ctx, time.Second*5)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		ctx, cancel = context.WithCancel(ctx)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Make sure the context is cancelled when the call has completed
 | 
					 | 
				
			||||||
	// this makes sure resources are cleaned up.
 | 
					 | 
				
			||||||
	defer func() { cancel() }()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get a new instance of the EVM.
 | 
					 | 
				
			||||||
	evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, common.Big0, err
 | 
							return "0x", common.Big0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Wait for the context to be done and cancel the evm. Even if the
 | 
					 | 
				
			||||||
	// EVM has finished, cancelling may be done (repeatedly)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		select {
 | 
					 | 
				
			||||||
		case <-ctx.Done():
 | 
					 | 
				
			||||||
			evm.Cancel()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Setup the gas pool (also for unmetered requests)
 | 
					 | 
				
			||||||
	// and apply the message.
 | 
					 | 
				
			||||||
	gp := new(core.GasPool).AddGas(common.MaxBig)
 | 
						gp := new(core.GasPool).AddGas(common.MaxBig)
 | 
				
			||||||
	res, gas, err := core.ApplyMessage(evm, msg, gp)
 | 
						res, gas, err := core.ApplyMessage(vmenv, msg, gp)
 | 
				
			||||||
	if err := vmError(); err != nil {
 | 
						if err := vmError(); err != nil {
 | 
				
			||||||
		return nil, common.Big0, err
 | 
							return "0x", common.Big0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return res, gas, err
 | 
						if len(res) == 0 { // backwards compatibility
 | 
				
			||||||
 | 
							return "0x", gas, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return common.ToHex(res), gas, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Call executes the given transaction on the state for the given block number.
 | 
					// Call executes the given transaction on the state for the given block number.
 | 
				
			||||||
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
 | 
					// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
 | 
				
			||||||
func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
 | 
					func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, error) {
 | 
				
			||||||
	result, _, err := s.doCall(ctx, args, blockNr, vm.Config{DisableGasMetering: true})
 | 
						result, _, err := s.doCall(ctx, args, blockNr)
 | 
				
			||||||
	return (hexutil.Bytes)(result), err
 | 
						return result, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EstimateGas returns an estimate of the amount of gas needed to execute the given transaction.
 | 
					// EstimateGas returns an estimate of the amount of gas needed to execute the given transaction.
 | 
				
			||||||
@@ -665,7 +644,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*
 | 
				
			|||||||
		mid := (hi + lo) / 2
 | 
							mid := (hi + lo) / 2
 | 
				
			||||||
		(*big.Int)(&args.Gas).SetUint64(mid)
 | 
							(*big.Int)(&args.Gas).SetUint64(mid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{})
 | 
							_, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If the transaction became invalid or used all the gas (failed), raise the gas limit
 | 
							// If the transaction became invalid or used all the gas (failed), raise the gas limit
 | 
				
			||||||
		if err != nil || gas.Cmp((*big.Int)(&args.Gas)) == 0 {
 | 
							if err != nil || gas.Cmp((*big.Int)(&args.Gas)) == 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ type Backend interface {
 | 
				
			|||||||
	GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
 | 
						GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
 | 
				
			||||||
	GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
 | 
						GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
 | 
				
			||||||
	GetTd(blockHash common.Hash) *big.Int
 | 
						GetTd(blockHash common.Hash) *big.Int
 | 
				
			||||||
	GetEVM(ctx context.Context, msg core.Message, state State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error)
 | 
						GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.EVM, func() error, error)
 | 
				
			||||||
	// TxPool API
 | 
						// TxPool API
 | 
				
			||||||
	SendTx(ctx context.Context, signedTx *types.Transaction) error
 | 
						SendTx(ctx context.Context, signedTx *types.Transaction) error
 | 
				
			||||||
	RemoveTx(txHash common.Hash)
 | 
						RemoveTx(txHash common.Hash)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,7 @@ func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
 | 
				
			|||||||
func runTrace(tracer *JavascriptTracer) (interface{}, error) {
 | 
					func runTrace(tracer *JavascriptTracer) (interface{}, error) {
 | 
				
			||||||
	env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
 | 
						env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000)
 | 
						contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000))
 | 
				
			||||||
	contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
 | 
						contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := env.Interpreter().Run(contract, []byte{})
 | 
						_, err := env.Interpreter().Run(contract, []byte{})
 | 
				
			||||||
@@ -134,7 +134,7 @@ func TestHaltBetweenSteps(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
 | 
						env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer})
 | 
				
			||||||
	contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0)
 | 
						contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil)
 | 
						tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil)
 | 
				
			||||||
	timeout := errors.New("stahp")
 | 
						timeout := errors.New("stahp")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,7 +88,7 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int {
 | 
				
			|||||||
	return b.eth.blockchain.GetTdByHash(blockHash)
 | 
						return b.eth.blockchain.GetTdByHash(blockHash)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) {
 | 
					func (b *LesApiBackend) GetVMEnv(ctx context.Context, msg core.Message, state ethapi.State, header *types.Header) (*vm.EVM, func() error, error) {
 | 
				
			||||||
	stateDb := state.(*light.LightState).Copy()
 | 
						stateDb := state.(*light.LightState).Copy()
 | 
				
			||||||
	addr := msg.From()
 | 
						addr := msg.From()
 | 
				
			||||||
	from, err := stateDb.GetOrNewStateObject(ctx, addr)
 | 
						from, err := stateDb.GetOrNewStateObject(ctx, addr)
 | 
				
			||||||
@@ -99,7 +99,7 @@ func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state etha
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	vmstate := light.NewVMState(ctx, stateDb)
 | 
						vmstate := light.NewVMState(ctx, stateDb)
 | 
				
			||||||
	context := core.NewEVMContext(msg, header, b.eth.blockchain)
 | 
						context := core.NewEVMContext(msg, header, b.eth.blockchain)
 | 
				
			||||||
	return vm.NewEVM(context, vmstate, b.eth.chainConfig, vmCfg), vmstate.Error, nil
 | 
						return vm.NewEVM(context, vmstate, b.eth.chainConfig, vm.Config{}), vmstate.Error, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
 | 
					func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,8 +57,6 @@ var (
 | 
				
			|||||||
	testContractDeployed     = uint64(2)
 | 
						testContractDeployed     = uint64(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testBufLimit = uint64(100)
 | 
						testBufLimit = uint64(100)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	bigTxGas = new(big.Int).SetUint64(params.TxGas)
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -82,15 +80,15 @@ func testChainGen(i int, block *core.BlockGen) {
 | 
				
			|||||||
	switch i {
 | 
						switch i {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		// In block 1, the test bank sends account #1 some ether.
 | 
							// In block 1, the test bank sends account #1 some ether.
 | 
				
			||||||
		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey)
 | 
							tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
		block.AddTx(tx)
 | 
							block.AddTx(tx)
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		// In block 2, the test bank sends some more ether to account #1.
 | 
							// In block 2, the test bank sends some more ether to account #1.
 | 
				
			||||||
		// acc1Addr passes it on to account #2.
 | 
							// acc1Addr passes it on to account #2.
 | 
				
			||||||
		// acc1Addr creates a test contract.
 | 
							// acc1Addr creates a test contract.
 | 
				
			||||||
		tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey)
 | 
							tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
		nonce := block.TxNonce(acc1Addr)
 | 
							nonce := block.TxNonce(acc1Addr)
 | 
				
			||||||
		tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key)
 | 
							tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
 | 
				
			||||||
		nonce++
 | 
							nonce++
 | 
				
			||||||
		tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(200000), big.NewInt(0), testContractCode), signer, acc1Key)
 | 
							tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(200000), big.NewInt(0), testContractCode), signer, acc1Key)
 | 
				
			||||||
		testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
 | 
							testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,8 +49,6 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	testContractCode = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056")
 | 
						testContractCode = common.Hex2Bytes("606060405260cc8060106000396000f360606040526000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146041578063c16431b914606b57603f565b005b6055600480803590602001909190505060a9565b6040518082815260200191505060405180910390f35b60886004808035906020019091908035906020019091905050608a565b005b80600060005083606481101560025790900160005b50819055505b5050565b6000600060005082606481101560025790900160005b5054905060c7565b91905056")
 | 
				
			||||||
	testContractAddr common.Address
 | 
						testContractAddr common.Address
 | 
				
			||||||
 | 
					 | 
				
			||||||
	bigTxGas = new(big.Int).SetUint64(params.TxGas)
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type testOdr struct {
 | 
					type testOdr struct {
 | 
				
			||||||
@@ -207,15 +205,15 @@ func testChainGen(i int, block *core.BlockGen) {
 | 
				
			|||||||
	switch i {
 | 
						switch i {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		// In block 1, the test bank sends account #1 some ether.
 | 
							// In block 1, the test bank sends account #1 some ether.
 | 
				
			||||||
		tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), signer, testBankKey)
 | 
							tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
		block.AddTx(tx)
 | 
							block.AddTx(tx)
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		// In block 2, the test bank sends some more ether to account #1.
 | 
							// In block 2, the test bank sends some more ether to account #1.
 | 
				
			||||||
		// acc1Addr passes it on to account #2.
 | 
							// acc1Addr passes it on to account #2.
 | 
				
			||||||
		// acc1Addr creates a test contract.
 | 
							// acc1Addr creates a test contract.
 | 
				
			||||||
		tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, testBankKey)
 | 
							tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testBankAddress), acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, testBankKey)
 | 
				
			||||||
		nonce := block.TxNonce(acc1Addr)
 | 
							nonce := block.TxNonce(acc1Addr)
 | 
				
			||||||
		tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), bigTxGas, nil, nil), signer, acc1Key)
 | 
							tx2, _ := types.SignTx(types.NewTransaction(nonce, acc2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, acc1Key)
 | 
				
			||||||
		nonce++
 | 
							nonce++
 | 
				
			||||||
		tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(1000000), big.NewInt(0), testContractCode), signer, acc1Key)
 | 
							tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), big.NewInt(1000000), big.NewInt(0), testContractCode), signer, acc1Key)
 | 
				
			||||||
		testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
 | 
							testContractAddr = crypto.CreateAddress(acc1Addr, nonce)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,7 +77,7 @@ func txPoolTestChainGen(i int, block *core.BlockGen) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestTxPool(t *testing.T) {
 | 
					func TestTxPool(t *testing.T) {
 | 
				
			||||||
	for i := range testTx {
 | 
						for i := range testTx {
 | 
				
			||||||
		testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), bigTxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
 | 
							testTx[i], _ = types.SignTx(types.NewTransaction(uint64(i), acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -171,7 +171,7 @@ func (self *Miner) HashRate() (tot int64) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (self *Miner) SetExtra(extra []byte) error {
 | 
					func (self *Miner) SetExtra(extra []byte) error {
 | 
				
			||||||
	if uint64(len(extra)) > params.MaximumExtraDataSize {
 | 
						if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
 | 
				
			||||||
		return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
 | 
							return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	self.worker.setExtra(extra)
 | 
						self.worker.setExtra(extra)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,35 +16,41 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package params
 | 
					package params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type GasTable struct {
 | 
					import "math/big"
 | 
				
			||||||
	ExtcodeSize uint64
 | 
					 | 
				
			||||||
	ExtcodeCopy uint64
 | 
					 | 
				
			||||||
	Balance     uint64
 | 
					 | 
				
			||||||
	SLoad       uint64
 | 
					 | 
				
			||||||
	Calls       uint64
 | 
					 | 
				
			||||||
	Suicide     uint64
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ExpByte uint64
 | 
					type GasTable struct {
 | 
				
			||||||
 | 
						ExtcodeSize *big.Int
 | 
				
			||||||
 | 
						ExtcodeCopy *big.Int
 | 
				
			||||||
 | 
						Balance     *big.Int
 | 
				
			||||||
 | 
						SLoad       *big.Int
 | 
				
			||||||
 | 
						Calls       *big.Int
 | 
				
			||||||
 | 
						Suicide     *big.Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ExpByte *big.Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// CreateBySuicide occurs when the
 | 
						// CreateBySuicide occurs when the
 | 
				
			||||||
	// refunded account is one that does
 | 
						// refunded account is one that does
 | 
				
			||||||
	// not exist. This logic is similar
 | 
						// not exist. This logic is similar
 | 
				
			||||||
	// to call. May be left nil. Nil means
 | 
						// to call. May be left nil. Nil means
 | 
				
			||||||
	// not charged.
 | 
						// not charged.
 | 
				
			||||||
	CreateBySuicide uint64
 | 
						CreateBySuicide *big.Int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// GasTableHomestead contain the gas prices for
 | 
						// GasTableHomestead contain the gas prices for
 | 
				
			||||||
	// the homestead phase.
 | 
						// the homestead phase.
 | 
				
			||||||
	GasTableHomestead = GasTable{
 | 
						GasTableHomestead = GasTable{
 | 
				
			||||||
		ExtcodeSize: 20,
 | 
							ExtcodeSize: big.NewInt(20),
 | 
				
			||||||
		ExtcodeCopy: 20,
 | 
							ExtcodeCopy: big.NewInt(20),
 | 
				
			||||||
		Balance:     20,
 | 
							Balance:     big.NewInt(20),
 | 
				
			||||||
		SLoad:       50,
 | 
							SLoad:       big.NewInt(50),
 | 
				
			||||||
		Calls:       40,
 | 
							Calls:       big.NewInt(40),
 | 
				
			||||||
		Suicide:     0,
 | 
							Suicide:     big.NewInt(0),
 | 
				
			||||||
		ExpByte:     10,
 | 
							ExpByte:     big.NewInt(10),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// explicitly set to nil to indicate
 | 
				
			||||||
 | 
							// this rule does not apply to homestead.
 | 
				
			||||||
 | 
							CreateBySuicide: nil,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// GasTableHomestead contain the gas re-prices for
 | 
						// GasTableHomestead contain the gas re-prices for
 | 
				
			||||||
@@ -52,26 +58,26 @@ var (
 | 
				
			|||||||
	//
 | 
						//
 | 
				
			||||||
	// TODO rename to GasTableEIP150
 | 
						// TODO rename to GasTableEIP150
 | 
				
			||||||
	GasTableHomesteadGasRepriceFork = GasTable{
 | 
						GasTableHomesteadGasRepriceFork = GasTable{
 | 
				
			||||||
		ExtcodeSize: 700,
 | 
							ExtcodeSize: big.NewInt(700),
 | 
				
			||||||
		ExtcodeCopy: 700,
 | 
							ExtcodeCopy: big.NewInt(700),
 | 
				
			||||||
		Balance:     400,
 | 
							Balance:     big.NewInt(400),
 | 
				
			||||||
		SLoad:       200,
 | 
							SLoad:       big.NewInt(200),
 | 
				
			||||||
		Calls:       700,
 | 
							Calls:       big.NewInt(700),
 | 
				
			||||||
		Suicide:     5000,
 | 
							Suicide:     big.NewInt(5000),
 | 
				
			||||||
		ExpByte:     10,
 | 
							ExpByte:     big.NewInt(10),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CreateBySuicide: 25000,
 | 
							CreateBySuicide: big.NewInt(25000),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GasTableEIP158 = GasTable{
 | 
						GasTableEIP158 = GasTable{
 | 
				
			||||||
		ExtcodeSize: 700,
 | 
							ExtcodeSize: big.NewInt(700),
 | 
				
			||||||
		ExtcodeCopy: 700,
 | 
							ExtcodeCopy: big.NewInt(700),
 | 
				
			||||||
		Balance:     400,
 | 
							Balance:     big.NewInt(400),
 | 
				
			||||||
		SLoad:       200,
 | 
							SLoad:       big.NewInt(200),
 | 
				
			||||||
		Calls:       700,
 | 
							Calls:       big.NewInt(700),
 | 
				
			||||||
		Suicide:     5000,
 | 
							Suicide:     big.NewInt(5000),
 | 
				
			||||||
		ExpByte:     50,
 | 
							ExpByte:     big.NewInt(50),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CreateBySuicide: 25000,
 | 
							CreateBySuicide: big.NewInt(25000),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,58 +18,56 @@ package params
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "math/big"
 | 
					import "math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					var (
 | 
				
			||||||
	MaximumExtraDataSize  uint64 = 32    // Maximum size extra data may be after Genesis.
 | 
						MaximumExtraDataSize   = big.NewInt(32)     // Maximum size extra data may be after Genesis.
 | 
				
			||||||
	ExpByteGas            uint64 = 10    // Times ceil(log256(exponent)) for the EXP instruction.
 | 
						ExpByteGas             = big.NewInt(10)     // Times ceil(log256(exponent)) for the EXP instruction.
 | 
				
			||||||
	SloadGas              uint64 = 50    // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
 | 
						SloadGas               = big.NewInt(50)     // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added.
 | 
				
			||||||
	CallValueTransferGas  uint64 = 9000  // Paid for CALL when the value transfer is non-zero.
 | 
						CallValueTransferGas   = big.NewInt(9000)   // Paid for CALL when the value transfer is non-zero.
 | 
				
			||||||
	CallNewAccountGas     uint64 = 25000 // Paid for CALL when the destination address didn't exist prior.
 | 
						CallNewAccountGas      = big.NewInt(25000)  // Paid for CALL when the destination address didn't exist prior.
 | 
				
			||||||
	TxGas                 uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions.
 | 
						TxGas                  = big.NewInt(21000)  // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions.
 | 
				
			||||||
	TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions.
 | 
						TxGasContractCreation  = big.NewInt(53000)  // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions.
 | 
				
			||||||
	TxDataZeroGas         uint64 = 4     // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
 | 
						TxDataZeroGas          = big.NewInt(4)      // Per byte of data attached to a transaction that equals zero. NOTE: Not payable on data of calls between transactions.
 | 
				
			||||||
	QuadCoeffDiv          uint64 = 512   // Divisor for the quadratic particle of the memory cost equation.
 | 
						DifficultyBoundDivisor = big.NewInt(2048)   // The bound divisor of the difficulty, used in the update calculations.
 | 
				
			||||||
	SstoreSetGas          uint64 = 20000 // Once per SLOAD operation.
 | 
						QuadCoeffDiv           = big.NewInt(512)    // Divisor for the quadratic particle of the memory cost equation.
 | 
				
			||||||
	LogDataGas            uint64 = 8     // Per byte in a LOG* operation's data.
 | 
						GenesisDifficulty      = big.NewInt(131072) // Difficulty of the Genesis block.
 | 
				
			||||||
	CallStipend           uint64 = 2300  // Free gas given at beginning of call.
 | 
						DurationLimit          = big.NewInt(13)     // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
 | 
				
			||||||
	EcrecoverGas          uint64 = 3000  //
 | 
						SstoreSetGas           = big.NewInt(20000)  // Once per SLOAD operation.
 | 
				
			||||||
	Sha256WordGas         uint64 = 12    //
 | 
						LogDataGas             = big.NewInt(8)      // Per byte in a LOG* operation's data.
 | 
				
			||||||
 | 
						CallStipend            = big.NewInt(2300)   // Free gas given at beginning of call.
 | 
				
			||||||
 | 
						EcrecoverGas           = big.NewInt(3000)   //
 | 
				
			||||||
 | 
						Sha256WordGas          = big.NewInt(12)     //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Sha3Gas          uint64 = 30    // Once per SHA3 operation.
 | 
						MinGasLimit     = big.NewInt(5000)                  // Minimum the gas limit may ever be.
 | 
				
			||||||
	Sha256Gas        uint64 = 60    //
 | 
						GenesisGasLimit = big.NewInt(4712388)               // Gas limit of the Genesis block.
 | 
				
			||||||
	IdentityWordGas  uint64 = 3     //
 | 
						TargetGasLimit  = new(big.Int).Set(GenesisGasLimit) // The artificial target
 | 
				
			||||||
	Sha3WordGas      uint64 = 6     // Once per word of the SHA3 operation's data.
 | 
					
 | 
				
			||||||
	SstoreResetGas   uint64 = 5000  // Once per SSTORE operation if the zeroness changes from zero.
 | 
						Sha3Gas              = big.NewInt(30)     // Once per SHA3 operation.
 | 
				
			||||||
	SstoreClearGas   uint64 = 5000  // Once per SSTORE operation if the zeroness doesn't change.
 | 
						Sha256Gas            = big.NewInt(60)     //
 | 
				
			||||||
	SstoreRefundGas  uint64 = 15000 // Once per SSTORE operation if the zeroness changes to zero.
 | 
						IdentityWordGas      = big.NewInt(3)      //
 | 
				
			||||||
	JumpdestGas      uint64 = 1     // Refunded gas, once per SSTORE operation if the zeroness changes to zero.
 | 
						Sha3WordGas          = big.NewInt(6)      // Once per word of the SHA3 operation's data.
 | 
				
			||||||
	IdentityGas      uint64 = 15    //
 | 
						SstoreResetGas       = big.NewInt(5000)   // Once per SSTORE operation if the zeroness changes from zero.
 | 
				
			||||||
	EpochDuration    uint64 = 30000 // Duration between proof-of-work epochs.
 | 
						SstoreClearGas       = big.NewInt(5000)   // Once per SSTORE operation if the zeroness doesn't change.
 | 
				
			||||||
	CallGas          uint64 = 40    // Once per CALL operation & message call transaction.
 | 
						SstoreRefundGas      = big.NewInt(15000)  // Once per SSTORE operation if the zeroness changes to zero.
 | 
				
			||||||
	CreateDataGas    uint64 = 200   //
 | 
						JumpdestGas          = big.NewInt(1)      // Refunded gas, once per SSTORE operation if the zeroness changes to zero.
 | 
				
			||||||
	Ripemd160Gas     uint64 = 600   //
 | 
						IdentityGas          = big.NewInt(15)     //
 | 
				
			||||||
	Ripemd160WordGas uint64 = 120   //
 | 
						GasLimitBoundDivisor = big.NewInt(1024)   // The bound divisor of the gas limit, used in update calculations.
 | 
				
			||||||
	CallCreateDepth  uint64 = 1024  // Maximum depth of call/create stack.
 | 
						EpochDuration        = big.NewInt(30000)  // Duration between proof-of-work epochs.
 | 
				
			||||||
	ExpGas           uint64 = 10    // Once per EXP instruction
 | 
						CallGas              = big.NewInt(40)     // Once per CALL operation & message call transaction.
 | 
				
			||||||
	LogGas           uint64 = 375   // Per LOG* operation.
 | 
						CreateDataGas        = big.NewInt(200)    //
 | 
				
			||||||
	CopyGas          uint64 = 3     //
 | 
						Ripemd160Gas         = big.NewInt(600)    //
 | 
				
			||||||
	StackLimit       uint64 = 1024  // Maximum size of VM stack allowed.
 | 
						Ripemd160WordGas     = big.NewInt(120)    //
 | 
				
			||||||
	TierStepGas      uint64 = 0     // Once per operation, for a selection of them.
 | 
						MinimumDifficulty    = big.NewInt(131072) // The minimum that the difficulty may ever be.
 | 
				
			||||||
	LogTopicGas      uint64 = 375   // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
 | 
						CallCreateDepth      = big.NewInt(1024)   // Maximum depth of call/create stack.
 | 
				
			||||||
	CreateGas        uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
 | 
						ExpGas               = big.NewInt(10)     // Once per EXP instruction.
 | 
				
			||||||
	SuicideRefundGas uint64 = 24000 // Refunded following a suicide operation.
 | 
						LogGas               = big.NewInt(375)    // Per LOG* operation.
 | 
				
			||||||
	MemoryGas        uint64 = 3     // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
 | 
						CopyGas              = big.NewInt(3)      //
 | 
				
			||||||
	TxDataNonZeroGas uint64 = 68    // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
 | 
						StackLimit           = big.NewInt(1024)   // Maximum size of VM stack allowed.
 | 
				
			||||||
 | 
						TierStepGas          = big.NewInt(0)      // Once per operation, for a selection of them.
 | 
				
			||||||
 | 
						LogTopicGas          = big.NewInt(375)    // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
 | 
				
			||||||
 | 
						CreateGas            = big.NewInt(32000)  // Once per CREATE operation & contract-creation transaction.
 | 
				
			||||||
 | 
						SuicideRefundGas     = big.NewInt(24000)  // Refunded following a suicide operation.
 | 
				
			||||||
 | 
						MemoryGas            = big.NewInt(3)      // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
 | 
				
			||||||
 | 
						TxDataNonZeroGas     = big.NewInt(68)     // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MaxCodeSize = 24576
 | 
						MaxCodeSize = 24576
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	GasLimitBoundDivisor   = big.NewInt(1024)                  // The bound divisor of the gas limit, used in update calculations.
 | 
					 | 
				
			||||||
	MinGasLimit            = big.NewInt(5000)                  // Minimum the gas limit may ever be.
 | 
					 | 
				
			||||||
	GenesisGasLimit        = big.NewInt(4712388)               // Gas limit of the Genesis block.
 | 
					 | 
				
			||||||
	TargetGasLimit         = new(big.Int).Set(GenesisGasLimit) // The artificial target
 | 
					 | 
				
			||||||
	DifficultyBoundDivisor = big.NewInt(2048)                  // The bound divisor of the difficulty, used in the update calculations.
 | 
					 | 
				
			||||||
	GenesisDifficulty      = big.NewInt(131072)                // Difficulty of the Genesis block.
 | 
					 | 
				
			||||||
	MinimumDifficulty      = big.NewInt(131072)                // The minimum that the difficulty may ever be.
 | 
					 | 
				
			||||||
	DurationLimit          = big.NewInt(13)                    // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,7 +146,7 @@ func runBlockTests(homesteadBlock, daoForkBlock, gasPriceFork *big.Int, bt map[s
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for name, test := range bt {
 | 
						for name, test := range bt {
 | 
				
			||||||
		if skipTest[name] /*|| name != "CallingCanonicalContractFromFork_CALLCODE"*/ {
 | 
							if skipTest[name] {
 | 
				
			||||||
			glog.Infoln("Skipping block test", name)
 | 
								glog.Infoln("Skipping block test", name)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -237,13 +237,13 @@ func TestWallet(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestStateTestsRandom(t *testing.T) {
 | 
					func TestStateTestsRandom(t *testing.T) {
 | 
				
			||||||
	t.Skip()
 | 
					 | 
				
			||||||
	chainConfig := ¶ms.ChainConfig{
 | 
						chainConfig := ¶ms.ChainConfig{
 | 
				
			||||||
		HomesteadBlock: big.NewInt(1150000),
 | 
							HomesteadBlock: big.NewInt(1150000),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
 | 
						fns, _ := filepath.Glob("./files/StateTests/RandomTests/*")
 | 
				
			||||||
	for _, fn := range fns {
 | 
						for _, fn := range fns {
 | 
				
			||||||
 | 
							t.Log("running:", fn)
 | 
				
			||||||
		if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
 | 
							if err := RunStateTest(chainConfig, fn, StateSkipTests); err != nil {
 | 
				
			||||||
			t.Error(fn, err)
 | 
								t.Error(fn, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -108,7 +108,7 @@ func runStateTests(chainConfig *params.ChainConfig, tests map[string]VmTest, ski
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for name, test := range tests {
 | 
						for name, test := range tests {
 | 
				
			||||||
		if skipTest[name] /*|| name != "JUMPDEST_Attack"*/ {
 | 
							if skipTest[name] {
 | 
				
			||||||
			glog.Infoln("Skipping state test", name)
 | 
								glog.Infoln("Skipping state test", name)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -129,7 +129,7 @@ func runVmTests(tests map[string]VmTest, skipTests []string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for name, test := range tests {
 | 
						for name, test := range tests {
 | 
				
			||||||
		if skipTest[name] /*|| name != "exp0"*/ {
 | 
							if skipTest[name] /*|| name != "loop_stacklimit_1021"*/ {
 | 
				
			||||||
			glog.Infoln("Skipping VM test", name)
 | 
								glog.Infoln("Skipping VM test", name)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -229,6 +229,6 @@ func RunVm(statedb *state.StateDB, env, exec map[string]string) ([]byte, []*type
 | 
				
			|||||||
	vm.PrecompiledContracts = make(map[common.Address]vm.PrecompiledContract)
 | 
						vm.PrecompiledContracts = make(map[common.Address]vm.PrecompiledContract)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	environment, _ := NewEVMEnvironment(true, chainConfig, statedb, env, exec)
 | 
						environment, _ := NewEVMEnvironment(true, chainConfig, statedb, env, exec)
 | 
				
			||||||
	ret, g, err := environment.Call(caller, to, data, gas.Uint64(), value)
 | 
						ret, err := environment.Call(caller, to, data, gas, value)
 | 
				
			||||||
	return ret, statedb.Logs(), new(big.Int).SetUint64(g), err
 | 
						return ret, statedb.Logs(), gas, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user