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

View File

@ -6,19 +6,20 @@ import (
) )
type Account struct { type Account struct {
Amount *big.Int Address []byte
Nonce uint64 Amount *big.Int
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})
} }

View File

@ -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)

View File

@ -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)
} }

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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,