Test fixes and removed old code. Added VM gas fees
This commit is contained in:
parent
6a86c517c4
commit
e0b6091d7e
@ -202,7 +202,7 @@ func (st *Stack) Push(d *big.Int) {
|
||||
st.data = append(st.data, d)
|
||||
}
|
||||
func (st *Stack) Print() {
|
||||
fmt.Println("### STACK ###")
|
||||
fmt.Println("### stack ###")
|
||||
if len(st.data) > 0 {
|
||||
for i, val := range st.data {
|
||||
fmt.Printf("%-3d %v\n", i, val)
|
||||
@ -242,15 +242,15 @@ func (m *Memory) Len() int {
|
||||
}
|
||||
|
||||
func (m *Memory) Print() {
|
||||
fmt.Println("### MEM ###")
|
||||
fmt.Printf("### mem %d bytes ###\n", len(m.store))
|
||||
if len(m.store) > 0 {
|
||||
addr := 0
|
||||
for i := 0; i+32 < len(m.store); i += 32 {
|
||||
for i := 0; i+32 <= len(m.store); i += 32 {
|
||||
fmt.Printf("%03d %v\n", addr, m.store[i:i+32])
|
||||
addr++
|
||||
}
|
||||
} else {
|
||||
fmt.Println("-- empty --")
|
||||
}
|
||||
fmt.Println("###########")
|
||||
fmt.Println("####################")
|
||||
}
|
||||
|
@ -10,6 +10,17 @@ import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var (
|
||||
GasStep = big.NewInt(1)
|
||||
GasSha = big.NewInt(20)
|
||||
GasSLoad = big.NewInt(20)
|
||||
GasSStore = big.NewInt(100)
|
||||
GasBalance = big.NewInt(20)
|
||||
GasCreate = big.NewInt(100)
|
||||
GasCall = big.NewInt(20)
|
||||
GasMemory = big.NewInt(1)
|
||||
)
|
||||
|
||||
type Vm struct {
|
||||
txPool *TxPool
|
||||
// Stack for processing contracts
|
||||
@ -70,10 +81,41 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
|
||||
}
|
||||
|
||||
// TODO Get each instruction cost properly
|
||||
fee := new(big.Int)
|
||||
fee.Add(fee, big.NewInt(1000))
|
||||
gas := new(big.Int)
|
||||
useGas := func(amount *big.Int) {
|
||||
gas.Add(gas, amount)
|
||||
}
|
||||
|
||||
if closure.Gas.Cmp(fee) < 0 {
|
||||
switch op {
|
||||
case oSHA3:
|
||||
useGas(GasSha)
|
||||
case oSLOAD:
|
||||
useGas(GasSLoad)
|
||||
case oSSTORE:
|
||||
var mult *big.Int
|
||||
y, x := stack.Peekn()
|
||||
val := closure.GetMem(x)
|
||||
if val.IsEmpty() && len(y.Bytes()) > 0 {
|
||||
mult = ethutil.Big2
|
||||
} else if !val.IsEmpty() && len(y.Bytes()) == 0 {
|
||||
mult = ethutil.Big0
|
||||
} else {
|
||||
mult = ethutil.Big1
|
||||
}
|
||||
useGas(base.Mul(mult, GasSStore))
|
||||
case oBALANCE:
|
||||
useGas(GasBalance)
|
||||
case oCREATE:
|
||||
useGas(GasCreate)
|
||||
case oCALL:
|
||||
useGas(GasCall)
|
||||
case oMLOAD, oMSIZE, oMSTORE8, oMSTORE:
|
||||
useGas(GasMemory)
|
||||
default:
|
||||
useGas(GasStep)
|
||||
}
|
||||
|
||||
if closure.Gas.Cmp(gas) < 0 {
|
||||
return closure.Return(nil)
|
||||
}
|
||||
|
||||
|
@ -2,113 +2,15 @@ package ethchain
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go/ethdb"
|
||||
"github.com/ethereum/eth-go/ethutil"
|
||||
"github.com/obscuren/mutan"
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
InitFees()
|
||||
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
state := NewState(ethutil.NewTrie(db, ""))
|
||||
|
||||
script := Compile([]string{
|
||||
"TXSENDER",
|
||||
"SUICIDE",
|
||||
})
|
||||
|
||||
tx := NewTransaction(ContractAddr, big.NewInt(1e17), script)
|
||||
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
|
||||
contract := MakeContract(tx, state)
|
||||
vm := &Vm{}
|
||||
|
||||
vm.Process(contract, state, RuntimeVars{
|
||||
address: tx.Hash()[12:],
|
||||
blockNumber: 1,
|
||||
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
|
||||
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
time: 1,
|
||||
diff: big.NewInt(256),
|
||||
txValue: tx.Value,
|
||||
txData: tx.Data,
|
||||
})
|
||||
}
|
||||
|
||||
func TestRun1(t *testing.T) {
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
state := NewState(ethutil.NewTrie(db, ""))
|
||||
|
||||
script := Compile([]string{
|
||||
"PUSH", "0",
|
||||
"PUSH", "0",
|
||||
"TXSENDER",
|
||||
"PUSH", "10000000",
|
||||
"MKTX",
|
||||
})
|
||||
fmt.Println(ethutil.NewValue(script))
|
||||
|
||||
tx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), script)
|
||||
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
|
||||
contract := MakeContract(tx, state)
|
||||
vm := &Vm{}
|
||||
|
||||
vm.Process(contract, state, RuntimeVars{
|
||||
address: tx.Hash()[12:],
|
||||
blockNumber: 1,
|
||||
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
|
||||
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
time: 1,
|
||||
diff: big.NewInt(256),
|
||||
txValue: tx.Value,
|
||||
txData: tx.Data,
|
||||
})
|
||||
}
|
||||
|
||||
func TestRun2(t *testing.T) {
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
state := NewState(ethutil.NewTrie(db, ""))
|
||||
|
||||
script := Compile([]string{
|
||||
"PUSH", "0",
|
||||
"PUSH", "0",
|
||||
"TXSENDER",
|
||||
"PUSH", "10000000",
|
||||
"MKTX",
|
||||
})
|
||||
fmt.Println(ethutil.NewValue(script))
|
||||
|
||||
tx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), script)
|
||||
fmt.Printf("contract addr %x\n", tx.Hash()[12:])
|
||||
contract := MakeContract(tx, state)
|
||||
vm := &Vm{}
|
||||
|
||||
vm.Process(contract, state, RuntimeVars{
|
||||
address: tx.Hash()[12:],
|
||||
blockNumber: 1,
|
||||
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
|
||||
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
time: 1,
|
||||
diff: big.NewInt(256),
|
||||
txValue: tx.Value,
|
||||
txData: tx.Data,
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
// XXX Full stack test
|
||||
func TestRun3(t *testing.T) {
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
@ -132,7 +34,7 @@ func TestRun3(t *testing.T) {
|
||||
contract := MakeContract(tx, state)
|
||||
state.UpdateContract(contract)
|
||||
|
||||
callerScript := ethutil.Compile(
|
||||
callerScript := ethutil.Assemble(
|
||||
"PUSH", 1337, // Argument
|
||||
"PUSH", 65, // argument mem offset
|
||||
"MSTORE",
|
||||
@ -172,3 +74,44 @@ func TestRun3(t *testing.T) {
|
||||
t.Errorf("expected return value to be %v, got %v", exp, ret)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRun4(t *testing.T) {
|
||||
ethutil.ReadConfig("")
|
||||
|
||||
db, _ := ethdb.NewMemDatabase()
|
||||
state := NewState(ethutil.NewTrie(db, ""))
|
||||
|
||||
mutan.NewCompiler().Compile(strings.NewReader(`
|
||||
a = 1337
|
||||
c = 1
|
||||
[0] = 50
|
||||
d = [0]
|
||||
`))
|
||||
|
||||
asm := mutan.NewCompiler().Compile(strings.NewReader(`
|
||||
a = 3 + 3
|
||||
[1000] = a
|
||||
[1000]
|
||||
`))
|
||||
asm = append(asm, "LOG")
|
||||
fmt.Println(asm)
|
||||
|
||||
callerScript := ethutil.Assemble(asm...)
|
||||
callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript)
|
||||
|
||||
// Contract addr as test address
|
||||
account := NewAccount(ContractAddr, big.NewInt(10000000))
|
||||
callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
|
||||
|
||||
vm := NewVm(state, RuntimeVars{
|
||||
origin: account.Address(),
|
||||
blockNumber: 1,
|
||||
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
|
||||
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
|
||||
time: 1,
|
||||
diff: big.NewInt(256),
|
||||
// XXX Tx data? Could be just an argument to the closure instead
|
||||
txData: nil,
|
||||
})
|
||||
callerClosure.Call(vm, nil)
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ func CurrencyToString(num *big.Int) string {
|
||||
|
||||
var (
|
||||
Big1 = big.NewInt(1)
|
||||
Big2 = big.NewInt(1)
|
||||
Big0 = big.NewInt(0)
|
||||
Big256 = big.NewInt(0xff)
|
||||
)
|
||||
|
@ -131,7 +131,7 @@ func Instr(instr string) (int, []string, error) {
|
||||
|
||||
// Script compilation functions
|
||||
// Compiles strings to machine code
|
||||
func Compile(instructions ...interface{}) (script []string) {
|
||||
func Assemble(instructions ...interface{}) (script []string) {
|
||||
script = make([]string, len(instructions))
|
||||
|
||||
for i, val := range instructions {
|
||||
|
@ -2,6 +2,7 @@ package ethutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
@ -119,6 +120,11 @@ func TestEncodeDecodeBytes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeZero(t *testing.T) {
|
||||
b := NewValue(0).Encode()
|
||||
fmt.Println(b)
|
||||
}
|
||||
|
||||
func BenchmarkEncodeDecode(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
bytes := Encode([]interface{}{"dog", "god", "cat"})
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ethutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user