Removed caller from tx and added "callership" to account.

Transactions can no longer serve as callers. Accounts are now the
initial callee of closures. Transactions now serve as transport to call
closures.
This commit is contained in:
obscuren 2014-03-20 23:17:53 +01:00
parent f3d27bf5d8
commit 7705b23f24
7 changed files with 31 additions and 29 deletions

@ -6,19 +6,20 @@ import (
) )
type Account struct { type Account struct {
Address []byte
Amount *big.Int Amount *big.Int
Nonce uint64 Nonce uint64
} }
func NewAccount(amount *big.Int) *Account { func NewAccount(address []byte, amount *big.Int) *Account {
return &Account{Amount: amount, Nonce: 0} return &Account{address, amount, 0}
} }
func NewAccountFromData(data []byte) *Account { func NewAccountFromData(address, data []byte) *Account {
address := &Account{} account := &Account{Address: address}
address.RlpDecode(data) account.RlpDecode(data)
return address return account
} }
func (a *Account) AddFee(fee *big.Int) { func (a *Account) AddFee(fee *big.Int) {
@ -29,6 +30,13 @@ func (a *Account) AddFunds(funds *big.Int) {
a.Amount.Add(a.Amount, funds) a.Amount.Add(a.Amount, funds)
} }
// Implements Callee
func (a *Account) ReturnGas(value *big.Int, state *State) {
// Return the value back to the sender
a.AddFunds(value)
state.UpdateAccount(a.Address, a)
}
func (a *Account) RlpEncode() []byte { func (a *Account) RlpEncode() []byte {
return ethutil.Encode([]interface{}{a.Amount, a.Nonce}) return ethutil.Encode([]interface{}{a.Amount, a.Nonce})
} }

@ -142,7 +142,7 @@ func (block *Block) PayFee(addr []byte, fee *big.Int) bool {
data := block.state.trie.Get(string(block.Coinbase)) data := block.state.trie.Get(string(block.Coinbase))
// Get the ether (Coinbase) and add the fee (gief fee to miner) // Get the ether (Coinbase) and add the fee (gief fee to miner)
ether := NewAccountFromData([]byte(data)) ether := NewAccountFromData(block.Coinbase, []byte(data))
base = new(big.Int) base = new(big.Int)
ether.Amount = base.Add(ether.Amount, fee) ether.Amount = base.Add(ether.Amount, fee)

@ -26,7 +26,7 @@ type Closure struct {
gas *big.Int gas *big.Int
val *big.Int val *big.Int
args []byte Args []byte
} }
// Create a new closure for the given data items // Create a new closure for the given data items
@ -45,7 +45,7 @@ func (c *Closure) GetMem(x int64) *ethutil.Value {
} }
func (c *Closure) Call(vm *Vm, args []byte) []byte { func (c *Closure) Call(vm *Vm, args []byte) []byte {
c.args = args c.Args = args
return vm.RunClosure(c) return vm.RunClosure(c)
} }

@ -86,9 +86,9 @@ func (s *State) UpdateContract(addr []byte, contract *Contract) {
func (s *State) GetAccount(addr []byte) (account *Account) { func (s *State) GetAccount(addr []byte) (account *Account) {
data := s.trie.Get(string(addr)) data := s.trie.Get(string(addr))
if data == "" { if data == "" {
account = NewAccount(big.NewInt(0)) account = NewAccount(addr, big.NewInt(0))
} else { } else {
account = NewAccountFromData([]byte(data)) account = NewAccountFromData(addr, []byte(data))
} }
return return

@ -29,15 +29,6 @@ func NewTransaction(to []byte, value *big.Int, data []string) *Transaction {
return &tx return &tx
} }
// Implements Callee
func (tx *Transaction) ReturnGas(value *big.Int, state *State) {
// Return the value back to the sender
sender := tx.Sender()
account := state.GetAccount(sender)
account.AddFunds(value)
state.UpdateAccount(sender, account)
}
// XXX Deprecated // XXX Deprecated
func NewTransactionFromData(data []byte) *Transaction { func NewTransactionFromData(data []byte) *Transaction {
return NewTransactionFromBytes(data) return NewTransactionFromBytes(data)

@ -87,6 +87,10 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// Pop value of the stack // Pop value of the stack
val, mStart := stack.Popn() val, mStart := stack.Popn()
mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256)) mem.Set(mStart.Int64(), 32, ethutil.BigToBytes(val, 256))
case oCALLDATA:
offset := stack.Pop()
mem.Set(offset.Int64(), int64(len(closure.Args)), closure.Args)
case oCALL: case oCALL:
// Pop return size and offset // Pop return size and offset
retSize, retOffset := stack.Popn() retSize, retOffset := stack.Popn()

@ -133,10 +133,10 @@ func TestRun3(t *testing.T) {
state.UpdateContract(addr, contract) state.UpdateContract(addr, contract)
callerScript := Compile([]string{ callerScript := Compile([]string{
"PUSH", "62", // REND "PUSH", "62", // ret size
"PUSH", "0", // RSTART "PUSH", "0", // ret offset
"PUSH", "22", // MEND "PUSH", "32", // arg size
"PUSH", "15", // MSTART "PUSH", "63", // arg offset
"PUSH", "1000", /// Gas "PUSH", "1000", /// Gas
"PUSH", "0", /// value "PUSH", "0", /// value
"PUSH", string(addr), // Sender "PUSH", string(addr), // Sender
@ -144,10 +144,9 @@ func TestRun3(t *testing.T) {
}) })
callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript) callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript)
callerAddr := callerTx.Hash()[12:] callerAddr := callerTx.Hash()[12:]
executer := NewTransaction(ContractAddr, ethutil.Big("10000"), nil)
executer.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) account := NewAccount(ContractAddr, big.NewInt(10000000))
callerClosure := NewClosure(executer, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int)) callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
vm := NewVm(state, RuntimeVars{ vm := NewVm(state, RuntimeVars{
address: callerAddr, address: callerAddr,