block/state: add CallTx type

This commit is contained in:
Ethan Buchman
2015-03-18 01:27:16 -07:00
committed by Jae Kwon
parent 3efd63e08d
commit 7a33aba6e5
2 changed files with 84 additions and 10 deletions

View File

@ -128,16 +128,8 @@ func (s *State) GetOrMakeAccounts(ins []*blk.TxInput, outs []*blk.TxOutput) (map
return nil, blk.ErrTxInvalidAddress
}
// PubKey should be present in either "account" or "in"
if _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
return nil, blk.ErrTxUnknownPubKey
}
if !bytes.Equal(in.PubKey.Address(), acc.Address) {
return nil, blk.ErrTxInvalidPubKey
}
acc.PubKey = in.PubKey
} else {
in.PubKey = account.PubKeyNil{}
if err := checkInputPubKey(acc, in); err != nil {
return nil, err
}
accounts[string(in.Address)] = acc
}
@ -161,6 +153,21 @@ func (s *State) GetOrMakeAccounts(ins []*blk.TxInput, outs []*blk.TxOutput) (map
return accounts, nil
}
func checkInputPubKey(acc *account.Account, in *blk.TxInput) error {
if _, isNil := acc.PubKey.(account.PubKeyNil); isNil {
if _, isNil := in.PubKey.(account.PubKeyNil); isNil {
return blk.ErrTxUnknownPubKey
}
if !bytes.Equal(in.PubKey.Address(), acc.Address) {
return blk.ErrTxInvalidPubKey
}
acc.PubKey = in.PubKey
} else {
in.PubKey = account.PubKeyNil{}
}
return nil
}
func (s *State) ValidateInputs(accounts map[string]*account.Account, signBytes []byte, ins []*blk.TxInput) (total uint64, err error) {
for _, in := range ins {
acc := accounts[string(in.Address)]
@ -261,6 +268,46 @@ func (s *State) ExecTx(tx_ blk.Tx) error {
s.UpdateAccounts(accounts)
return nil
case *blk.CallTx:
tx := tx_.(*blk.CallTx)
accounts := map[string]*account.Account{}
inAcc := s.GetAccount(tx.Input.Address)
if inAcc == nil {
return blk.ErrTxInvalidAddress
}
// PubKey should be present in either "inAcc" or "tx.Input"
if err := checkInputPubKey(inAcc, tx.Input); err != nil {
return err
}
accounts[string(tx.Input.Address)] = inAcc
signBytes := account.SignBytes(tx)
inTotal, err := s.ValidateInputs(accounts, signBytes, []*blk.TxInput{tx.Input})
if err != nil {
return err
}
// validate output address
if len(tx.Address) != 20 {
return blk.ErrTxInvalidAddress
}
outAcc := s.GetAccount(tx.Address)
if outAcc == nil {
return blk.ErrTxInvalidAddress
}
accounts[string(tx.Address)] = outAcc
// TODO: fees
// inTotal -= fees
// Good! Adjust accounts
s.AdjustByInputs(accounts, []*blk.TxInput{tx.Input})
outAcc.Balance += inTotal
s.UpdateAccounts(accounts)
// TODO: Run the contract call!
return nil
case *blk.BondTx:
tx := tx_.(*blk.BondTx)
valInfo := s.GetValidatorInfo(tx.PubKey.Address())