Skip to content
Snippets Groups Projects
Commit 50f28ac5 authored by Benjamin Bollen's avatar Benjamin Bollen Committed by GitHub
Browse files

Merge pull request #182 from eris-ltd/create_fix

fixes #164 on develop
parents 809a7eab 69416338
No related branches found
No related tags found
Loading
......@@ -735,6 +735,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
// TODO charge for gas to create account _ the code length * GasCreateByte
newAccount := vm.appState.CreateAccount(callee)
// Run the input to get the contract code.
// NOTE: no need to copy 'input' as per Call contract.
ret, err_ := vm.Call(callee, newAccount, input, input, contractValue, gas)
......@@ -800,19 +801,16 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
}
ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
} else {
// nil account means we're sending funds to a new account
if acc == nil {
// nil account means we're sending funds to a new account
if !HasPermission(vm.appState, caller, ptypes.CreateAccount) {
return nil, ErrPermission{"create_account"}
}
acc = &Account{Address: addr}
vm.appState.UpdateAccount(acc)
// send funds to new account
ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
} else {
// call standard contract
ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
}
// add account to the tx cache
vm.appState.UpdateAccount(acc)
ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
}
}
......
......@@ -513,7 +513,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
// and only deduct from the caller's balance.
inAcc.Balance -= value
if createContract {
inAcc.Sequence += 1
inAcc.Sequence += 1 // XXX ?!
}
blockCache.UpdateAccount(inAcc)
}
......
......@@ -2,13 +2,16 @@ package state
import (
"bytes"
"encoding/hex"
"testing"
//"time"
"github.com/tendermint/go-common"
"github.com/tendermint/tendermint/config/tendermint_test"
// tmtypes "github.com/tendermint/tendermint/types"
core_types "github.com/eris-ltd/eris-db/core/types"
//evm "github.com/eris-ltd/eris-db/manager/eris-mint/evm"
"github.com/eris-ltd/eris-db/txs"
)
......@@ -382,6 +385,156 @@ func TestNameTxs(t *testing.T) {
}
}
// Test creating a contract from futher down the call stack
/*
contract Factory {
address a;
function create() returns (address){
a = new PreFactory();
return a;
}
}
contract PreFactory{
address a;
function create(Factory c) returns (address) {
a = c.create();
return a;
}
}
*/
// run-time byte code for each of the above
var preFactoryCode, _ = hex.DecodeString("60606040526000357C0100000000000000000000000000000000000000000000000000000000900480639ED933181461003957610037565B005B61004F600480803590602001909190505061007B565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60008173FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1663EFC81A8C604051817C01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161DA5A03F1156100025750505060405180519060200150600060006101000A81548173FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02191690830217905550600060009054906101000A900473FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16905061013C565B91905056")
var factoryCode, _ = hex.DecodeString("60606040526000357C010000000000000000000000000000000000000000000000000000000090048063EFC81A8C146037576035565B005B60426004805050606E565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B6000604051610153806100E0833901809050604051809103906000F0600060006101000A81548173FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02191690830217905550600060009054906101000A900473FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16905060DD565B90566060604052610141806100126000396000F360606040526000357C0100000000000000000000000000000000000000000000000000000000900480639ED933181461003957610037565B005B61004F600480803590602001909190505061007B565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60008173FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1663EFC81A8C604051817C01000000000000000000000000000000000000000000000000000000000281526004018090506020604051808303816000876161DA5A03F1156100025750505060405180519060200150600060006101000A81548173FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02191690830217905550600060009054906101000A900473FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16905061013C565B91905056")
var createData, _ = hex.DecodeString("9ed93318")
func TestCreates(t *testing.T) {
//evm.SetDebug(true)
state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
//val0 := state.GetValidatorInfo(privValidators[0].Address)
acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
acc0PubKey := privAccounts[0].PubKey
acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
acc2 := state.GetAccount(privAccounts[2].PubKey.Address())
state = state.Copy()
newAcc1 := state.GetAccount(acc1.Address)
newAcc1.Code = preFactoryCode
newAcc2 := state.GetAccount(acc2.Address)
newAcc2.Code = factoryCode
state.UpdateAccount(newAcc1)
state.UpdateAccount(newAcc2)
createData = append(createData, common.LeftPadBytes(acc2.Address, 32)...)
// call the pre-factory, triggering the factory to run a create
tx := &txs.CallTx{
Input: &txs.TxInput{
Address: acc0.Address,
Amount: 1,
Sequence: acc0.Sequence + 1,
PubKey: acc0PubKey,
},
Address: acc1.Address,
GasLimit: 10000,
Data: createData,
}
tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx)
err := execTxWithState(state, tx, true)
if err != nil {
t.Errorf("Got error in executing call transaction, %v", err)
}
acc1 = state.GetAccount(acc1.Address)
storage := state.LoadStorage(acc1.StorageRoot)
_, firstCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32))
acc0 = state.GetAccount(acc0.Address)
// call the pre-factory, triggering the factory to run a create
tx = &txs.CallTx{
Input: &txs.TxInput{
Address: acc0.Address,
Amount: 1,
Sequence: acc0.Sequence + 1,
PubKey: acc0PubKey,
},
Address: acc1.Address,
GasLimit: 10000,
Data: createData,
}
tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx)
err = execTxWithState(state, tx, true)
if err != nil {
t.Errorf("Got error in executing call transaction, %v", err)
}
acc1 = state.GetAccount(acc1.Address)
storage = state.LoadStorage(acc1.StorageRoot)
_, secondCreatedAddress, _ := storage.Get(common.LeftPadBytes([]byte{0}, 32))
if bytes.Equal(firstCreatedAddress, secondCreatedAddress) {
t.Errorf("Multiple contracts created with the same address!")
}
}
/*
contract Caller {
function send(address x){
x.send(msg.value);
}
}
*/
var callerCode, _ = hex.DecodeString("60606040526000357c0100000000000000000000000000000000000000000000000000000000900480633e58c58c146037576035565b005b604b6004808035906020019091905050604d565b005b8073ffffffffffffffffffffffffffffffffffffffff16600034604051809050600060405180830381858888f19350505050505b5056")
var sendData, _ = hex.DecodeString("3e58c58c")
func TestContractSend(t *testing.T) {
state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000)
//val0 := state.GetValidatorInfo(privValidators[0].Address)
acc0 := state.GetAccount(privAccounts[0].PubKey.Address())
acc0PubKey := privAccounts[0].PubKey
acc1 := state.GetAccount(privAccounts[1].PubKey.Address())
acc2 := state.GetAccount(privAccounts[2].PubKey.Address())
state = state.Copy()
newAcc1 := state.GetAccount(acc1.Address)
newAcc1.Code = callerCode
state.UpdateAccount(newAcc1)
sendData = append(sendData, common.LeftPadBytes(acc2.Address, 32)...)
sendAmt := int64(10)
acc2Balance := acc2.Balance
// call the contract, triggering the send
tx := &txs.CallTx{
Input: &txs.TxInput{
Address: acc0.Address,
Amount: sendAmt,
Sequence: acc0.Sequence + 1,
PubKey: acc0PubKey,
},
Address: acc1.Address,
GasLimit: 1000,
Data: sendData,
}
tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx)
err := execTxWithState(state, tx, true)
if err != nil {
t.Errorf("Got error in executing call transaction, %v", err)
}
acc2 = state.GetAccount(acc2.Address)
if acc2.Balance != sendAmt+acc2Balance {
t.Errorf("Value transfer from contract failed! Got %d, expected %d", acc2.Balance, sendAmt+acc2Balance)
}
}
// TODO: test overflows.
// TODO: test for unbonding validators.
func TestTxs(t *testing.T) {
......
......@@ -120,7 +120,6 @@ func (cache *TxCache) SetStorage(addr Word256, key Word256, value Word256) {
// These updates do not have to be in deterministic order,
// the backend is responsible for ordering updates.
func (cache *TxCache) Sync() {
// Remove or update storage
for addrKey, value := range cache.storages {
addr, key := Tuple256Split(addrKey)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment