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)
|
st.data = append(st.data, d)
|
||||||
}
|
}
|
||||||
func (st *Stack) Print() {
|
func (st *Stack) Print() {
|
||||||
fmt.Println("### STACK ###")
|
fmt.Println("### stack ###")
|
||||||
if len(st.data) > 0 {
|
if len(st.data) > 0 {
|
||||||
for i, val := range st.data {
|
for i, val := range st.data {
|
||||||
fmt.Printf("%-3d %v\n", i, val)
|
fmt.Printf("%-3d %v\n", i, val)
|
||||||
@ -242,15 +242,15 @@ func (m *Memory) Len() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Memory) Print() {
|
func (m *Memory) Print() {
|
||||||
fmt.Println("### MEM ###")
|
fmt.Printf("### mem %d bytes ###\n", len(m.store))
|
||||||
if len(m.store) > 0 {
|
if len(m.store) > 0 {
|
||||||
addr := 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])
|
fmt.Printf("%03d %v\n", addr, m.store[i:i+32])
|
||||||
addr++
|
addr++
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("-- empty --")
|
fmt.Println("-- empty --")
|
||||||
}
|
}
|
||||||
fmt.Println("###########")
|
fmt.Println("####################")
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,17 @@ import (
|
|||||||
"math/big"
|
"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 {
|
type Vm struct {
|
||||||
txPool *TxPool
|
txPool *TxPool
|
||||||
// Stack for processing contracts
|
// Stack for processing contracts
|
||||||
@ -70,10 +81,41 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO Get each instruction cost properly
|
// TODO Get each instruction cost properly
|
||||||
fee := new(big.Int)
|
gas := new(big.Int)
|
||||||
fee.Add(fee, big.NewInt(1000))
|
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)
|
return closure.Return(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,113 +2,15 @@ package ethchain
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethdb"
|
"github.com/ethereum/eth-go/ethdb"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
|
"github.com/obscuren/mutan"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strings"
|
||||||
"testing"
|
"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) {
|
func TestRun3(t *testing.T) {
|
||||||
ethutil.ReadConfig("")
|
ethutil.ReadConfig("")
|
||||||
|
|
||||||
@ -132,7 +34,7 @@ func TestRun3(t *testing.T) {
|
|||||||
contract := MakeContract(tx, state)
|
contract := MakeContract(tx, state)
|
||||||
state.UpdateContract(contract)
|
state.UpdateContract(contract)
|
||||||
|
|
||||||
callerScript := ethutil.Compile(
|
callerScript := ethutil.Assemble(
|
||||||
"PUSH", 1337, // Argument
|
"PUSH", 1337, // Argument
|
||||||
"PUSH", 65, // argument mem offset
|
"PUSH", 65, // argument mem offset
|
||||||
"MSTORE",
|
"MSTORE",
|
||||||
@ -172,3 +74,44 @@ func TestRun3(t *testing.T) {
|
|||||||
t.Errorf("expected return value to be %v, got %v", exp, ret)
|
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 (
|
var (
|
||||||
Big1 = big.NewInt(1)
|
Big1 = big.NewInt(1)
|
||||||
|
Big2 = big.NewInt(1)
|
||||||
Big0 = big.NewInt(0)
|
Big0 = big.NewInt(0)
|
||||||
Big256 = big.NewInt(0xff)
|
Big256 = big.NewInt(0xff)
|
||||||
)
|
)
|
||||||
|
@ -131,7 +131,7 @@ func Instr(instr string) (int, []string, error) {
|
|||||||
|
|
||||||
// Script compilation functions
|
// Script compilation functions
|
||||||
// Compiles strings to machine code
|
// Compiles strings to machine code
|
||||||
func Compile(instructions ...interface{}) (script []string) {
|
func Assemble(instructions ...interface{}) (script []string) {
|
||||||
script = make([]string, len(instructions))
|
script = make([]string, len(instructions))
|
||||||
|
|
||||||
for i, val := range instructions {
|
for i, val := range instructions {
|
||||||
|
@ -2,6 +2,7 @@ package ethutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"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) {
|
func BenchmarkEncodeDecode(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
bytes := Encode([]interface{}{"dog", "god", "cat"})
|
bytes := Encode([]interface{}{"dog", "god", "cat"})
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package ethutil
|
package ethutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
_ "fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user