tendermint/rpc/core/txs.go

117 lines
3.9 KiB
Go
Raw Normal View History

package core
import (
"fmt"
2015-07-19 09:40:55 -07:00
acm "github.com/tendermint/tendermint/account"
2015-04-01 17:30:16 -07:00
. "github.com/tendermint/tendermint/common"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
2015-04-01 17:30:16 -07:00
"github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/vm"
)
2015-07-19 09:40:55 -07:00
func toVMAccount(acc *acm.Account) *vm.Account {
return &vm.Account{
2015-07-28 12:39:10 -07:00
Address: LeftPadWord256(acc.Address),
Balance: acc.Balance,
Code: acc.Code, // This is crazy.
Nonce: int64(acc.Sequence),
Other: acc.PubKey,
}
}
//-----------------------------------------------------------------------------
// Run a contract's code on an isolated and unpersisted state
// Cannot be used to create new contracts
func Call(fromAddress, toAddress, data []byte) (*ctypes.ResultCall, error) {
st := consensusState.GetState() // performs a copy
2015-04-17 17:43:45 -07:00
cache := state.NewBlockCache(st)
outAcc := cache.GetAccount(toAddress)
if outAcc == nil {
return nil, fmt.Errorf("Account %x does not exist", toAddress)
}
callee := toVMAccount(outAcc)
caller := &vm.Account{Address: LeftPadWord256(fromAddress)}
txCache := state.NewTxCache(cache)
params := vm.Params{
BlockHeight: int64(st.LastBlockHeight),
2015-04-17 17:39:50 -07:00
BlockHash: LeftPadWord256(st.LastBlockHash),
BlockTime: st.LastBlockTime.Unix(),
GasLimit: st.GetGasLimit(),
}
vmach := vm.NewVM(txCache, params, caller.Address, nil)
gas := st.GetGasLimit()
ret, err := vmach.Call(caller, callee, callee.Code, data, 0, &gas)
if err != nil {
return nil, err
}
return &ctypes.ResultCall{Return: ret}, nil
}
2015-04-02 19:15:23 -07:00
// Run the given code on an isolated and unpersisted state
// Cannot be used to create new contracts
func CallCode(fromAddress, code, data []byte) (*ctypes.ResultCall, error) {
2015-04-02 19:15:23 -07:00
st := consensusState.GetState() // performs a copy
cache := mempoolReactor.Mempool.GetCache()
callee := &vm.Account{Address: LeftPadWord256(fromAddress)}
caller := &vm.Account{Address: LeftPadWord256(fromAddress)}
2015-04-02 19:15:23 -07:00
txCache := state.NewTxCache(cache)
params := vm.Params{
BlockHeight: int64(st.LastBlockHeight),
2015-04-17 17:39:50 -07:00
BlockHash: LeftPadWord256(st.LastBlockHash),
2015-04-02 19:15:23 -07:00
BlockTime: st.LastBlockTime.Unix(),
GasLimit: st.GetGasLimit(),
2015-04-02 19:15:23 -07:00
}
vmach := vm.NewVM(txCache, params, caller.Address, nil)
gas := st.GetGasLimit()
2015-04-02 19:15:23 -07:00
ret, err := vmach.Call(caller, callee, code, data, 0, &gas)
if err != nil {
return nil, err
}
return &ctypes.ResultCall{Return: ret}, nil
2015-04-02 19:15:23 -07:00
}
//-----------------------------------------------------------------------------
func SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) {
// more checks?
for i, privAccount := range privAccounts {
if privAccount == nil || privAccount.PrivKey == nil {
return nil, fmt.Errorf("Invalid (empty) privAccount @%v", i)
}
}
switch tx.(type) {
case *types.SendTx:
sendTx := tx.(*types.SendTx)
for i, input := range sendTx.Inputs {
input.PubKey = privAccounts[i].PubKey
2015-05-29 14:53:57 -07:00
input.Signature = privAccounts[i].Sign(config.GetString("chain_id"), sendTx)
}
case *types.CallTx:
callTx := tx.(*types.CallTx)
callTx.Input.PubKey = privAccounts[0].PubKey
2015-05-29 14:53:57 -07:00
callTx.Input.Signature = privAccounts[0].Sign(config.GetString("chain_id"), callTx)
case *types.BondTx:
bondTx := tx.(*types.BondTx)
2015-05-20 16:36:55 -07:00
// the first privaccount corresponds to the BondTx pub key.
// the rest to the inputs
2015-07-19 09:40:55 -07:00
bondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), bondTx).(acm.SignatureEd25519)
for i, input := range bondTx.Inputs {
2015-05-20 16:36:55 -07:00
input.PubKey = privAccounts[i+1].PubKey
2015-05-29 14:53:57 -07:00
input.Signature = privAccounts[i+1].Sign(config.GetString("chain_id"), bondTx)
}
case *types.UnbondTx:
unbondTx := tx.(*types.UnbondTx)
2015-07-19 09:40:55 -07:00
unbondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), unbondTx).(acm.SignatureEd25519)
case *types.RebondTx:
rebondTx := tx.(*types.RebondTx)
2015-07-19 09:40:55 -07:00
rebondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), rebondTx).(acm.SignatureEd25519)
}
return &ctypes.ResultSignTx{tx}, nil
}