Address is generated with VMAppState, and it increments the nonce too.

This commit is contained in:
Jae Kwon
2015-03-20 20:03:37 -07:00
parent 36dca3981b
commit b7553e2bfe
5 changed files with 65 additions and 35 deletions
+30 -11
View File
@@ -277,8 +277,10 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
return nil
case *blk.CallTx:
var inAcc, outAcc *account.Account
// Validate input
inAcc := s.GetAccount(tx.Input.Address)
inAcc = s.GetAccount(tx.Input.Address)
if inAcc == nil {
return blk.ErrTxInvalidAddress
}
@@ -295,13 +297,16 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
return blk.ErrTxInsufficientFunds
}
// Validate output
if len(tx.Address) != 20 {
return blk.ErrTxInvalidAddress
}
outAcc := s.GetAccount(tx.Address)
if outAcc == nil {
return blk.ErrTxInvalidAddress
createAccount := len(tx.Address) == 0
if !createAccount {
// Validate output
if len(tx.Address) != 20 {
return blk.ErrTxInvalidAddress
}
outAcc = s.GetAccount(tx.Address)
if outAcc == nil {
return blk.ErrTxInvalidAddress
}
}
// Good!
@@ -316,9 +321,18 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
BlockTime: s.LastBlockTime.Unix(),
GasLimit: 10000000,
}
caller := toVMAccount(inAcc)
callee := toVMAccount(outAcc)
appState.AddAccount(caller) // because we adjusted by input above.
var caller, callee *vm.Account
var err error
caller = toVMAccount(inAcc)
if outAcc == nil {
callee = toVMAccount(outAcc)
} else {
callee, err = appState.CreateAccount(caller)
if err != nil {
return err
}
}
appState.AddAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
appState.AddAccount(callee) // because we adjusted by input above.
vmach := vm.NewVM(appState, params, caller.Address)
gas := tx.GasLimit
@@ -330,6 +344,9 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
// Throw away 'appState' which holds incomplete updates.
} else {
// Success
if createAccount {
callee.Code = ret
}
appState.Sync()
}
// Create a receipt from the ret and whether errored.
@@ -339,6 +356,8 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
// the proposer determines the order of txs.
// So mempool will skip the actual .Call(),
// and only deduct from the caller's balance.
inAcc.Balance -= value
s.UpdateAccount(inAcc)
}
return nil
+15 -2
View File
@@ -8,6 +8,7 @@ import (
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/merkle"
"github.com/tendermint/tendermint/vm"
"github.com/tendermint/tendermint/vm/sha3"
)
// Converts state.Account to vm.Account struct.
@@ -115,7 +116,18 @@ func (vas *VMAppState) DeleteAccount(account *vm.Account) error {
}
}
func (vas *VMAppState) CreateAccount(addr vm.Word) (*vm.Account, error) {
// Creates a 20 byte address and bumps the creator's nonce.
func (vas *VMAppState) CreateAccount(creator *vm.Account) (*vm.Account, error) {
// Generate an address
nonce := creator.Nonce
creator.Nonce += 1
temp := make([]byte, 32+8)
copy(temp, creator.Address[:])
vm.PutUint64(temp[32:], nonce)
addr := vm.RightPadWord(sha3.Sha3(temp)[:20])
// Create account from address.
account, deleted := unpack(vas.accounts[addr.String()])
if deleted || account == nil {
account = &vm.Account{
@@ -128,7 +140,8 @@ func (vas *VMAppState) CreateAccount(addr vm.Word) (*vm.Account, error) {
vas.accounts[addr.String()] = AccountInfo{account, false}
return account, nil
} else {
return nil, Errorf("Account already exists: %X", addr)
panic(Fmt("Could not create account, address already exists: %X", addr))
// return nil, Errorf("Account already exists: %X", addr)
}
}