rpc: separate out golang API into rpc/core

This commit is contained in:
Ethan Buchman 2015-03-26 21:30:42 -07:00
parent d2724c9731
commit 1fb1163721
8 changed files with 264 additions and 0 deletions

32
rpc/core/accounts.go Normal file
View File

@ -0,0 +1,32 @@
package core
import (
"github.com/tendermint/tendermint/account"
)
//-----------------------------------------------------------------------------
func GenPrivAccount() *account.PrivAccount {
return account.GenPrivAccount()
}
//-----------------------------------------------------------------------------
func GetAccount(address []byte) *account.Account {
state := consensusState.GetState()
return state.GetAccount(address)
}
//-----------------------------------------------------------------------------
func ListAccounts() (uint, []*account.Account) {
var blockHeight uint
var accounts []*account.Account
state := consensusState.GetState()
blockHeight = state.LastBlockHeight
state.GetAccounts().Iterate(func(key interface{}, value interface{}) bool {
accounts = append(accounts, value.(*account.Account))
return false
})
return blockHeight, accounts
}

44
rpc/core/blocks.go Normal file
View File

@ -0,0 +1,44 @@
package core
import (
"fmt"
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
func BlockchainInfoHandler(minHeight, maxHeight uint) (uint, []*types.BlockMeta) {
if maxHeight == 0 {
maxHeight = blockStore.Height()
} else {
maxHeight = MinUint(blockStore.Height(), maxHeight)
}
if minHeight == 0 {
minHeight = uint(MaxInt(1, int(maxHeight)-20))
}
log.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)
blockMetas := []*types.BlockMeta{}
for height := maxHeight; height >= minHeight; height-- {
blockMeta := blockStore.LoadBlockMeta(height)
blockMetas = append(blockMetas, blockMeta)
}
return blockStore.Height(), blockMetas
}
//-----------------------------------------------------------------------------
func GetBlockHandler(height uint) (*types.BlockMeta, *types.Block, error) {
if height == 0 {
return nil, nil, fmt.Errorf("height must be greater than 1")
}
if height > blockStore.Height() {
return nil, nil, fmt.Errorf("height must be less than the current blockchain height")
}
blockMeta := blockStore.LoadBlockMeta(height)
block := blockStore.LoadBlock(height)
return blockMeta, block, nil
}

7
rpc/core/log.go Normal file
View File

@ -0,0 +1,7 @@
package core
import (
"github.com/tendermint/log15"
)
var log = log15.New("module", "rpc")

42
rpc/core/mempool.go Normal file
View File

@ -0,0 +1,42 @@
package core
import (
"fmt"
. "github.com/tendermint/tendermint/common"
"github.com/tendermint/tendermint/merkle"
"github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
type Receipt struct {
TxHash []byte
CreatesContract bool
ContractAddr []byte
}
// pass pointer?
// Note: tx must be signed
func BroadcastTx(tx types.Tx) (*Receipt, error) {
err := mempoolReactor.BroadcastTx(tx)
if err != nil {
return nil, fmt.Errorf("Error broadcasting transaction: %v", err)
}
txHash := merkle.HashFromBinary(tx)
var createsContract bool
var contractAddr []byte
// check if creates new contract
if callTx, ok := tx.(*types.CallTx); ok {
if callTx.Address == nil {
createsContract = true
contractAddr = state.NewContractAddress(callTx.Input.Address, uint64(callTx.Input.Sequence))
}
}
return &Receipt{txHash, createsContract, contractAddr}, nil
}
/*
curl -H 'content-type: text/plain;' http://127.0.0.1:8888/submit_tx?tx=...
*/

39
rpc/core/net.go Normal file
View File

@ -0,0 +1,39 @@
package core
import (
"github.com/tendermint/tendermint/config"
dbm "github.com/tendermint/tendermint/db"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
func Status() ([]byte, string, []byte, uint, int64) {
db := dbm.NewMemDB()
genesisState := sm.MakeGenesisStateFromFile(db, config.App().GetString("GenesisFile"))
genesisHash := genesisState.Hash()
latestHeight := blockStore.Height()
var (
latestBlockMeta *types.BlockMeta
latestBlockHash []byte
latestBlockTime int64
)
if latestHeight != 0 {
latestBlockMeta = blockStore.LoadBlockMeta(latestHeight)
latestBlockHash = latestBlockMeta.Hash
latestBlockTime = latestBlockMeta.Header.Time.UnixNano()
}
return genesisHash, config.App().GetString("Network"), latestBlockHash, latestHeight, latestBlockTime
}
//-----------------------------------------------------------------------------
func NetInfo() (int, bool, string) {
o, i, _ := p2pSwitch.NumPeers()
numPeers := o + i
listening := p2pSwitch.IsListening()
network := config.App().GetString("Network")
return numPeers, listening, network
}

29
rpc/core/pipe.go Normal file
View File

@ -0,0 +1,29 @@
package core
import (
"github.com/tendermint/tendermint/consensus"
mempl "github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
)
var blockStore *types.BlockStore
var consensusState *consensus.ConsensusState
var mempoolReactor *mempl.MempoolReactor
var p2pSwitch *p2p.Switch
func SetPipeBlockStore(bs *types.BlockStore) {
blockStore = bs
}
func SetPipeConsensusState(cs *consensus.ConsensusState) {
consensusState = cs
}
func SetPipeMempoolReactor(mr *mempl.MempoolReactor) {
mempoolReactor = mr
}
func SetPipeSwitch(sw *p2p.Switch) {
p2pSwitch = sw
}

45
rpc/core/txs.go Normal file
View File

@ -0,0 +1,45 @@
package core
import (
"fmt"
"github.com/tendermint/tendermint/account"
"github.com/tendermint/tendermint/types"
)
//-----------------------------------------------------------------------------
func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (types.Tx, 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
input.Signature = privAccounts[i].Sign(sendTx)
}
case *types.CallTx:
callTx := tx.(*types.CallTx)
callTx.Input.PubKey = privAccounts[0].PubKey
callTx.Input.Signature = privAccounts[0].Sign(callTx)
case *types.BondTx:
bondTx := tx.(*types.BondTx)
for i, input := range bondTx.Inputs {
input.PubKey = privAccounts[i].PubKey
input.Signature = privAccounts[i].Sign(bondTx)
}
case *types.UnbondTx:
unbondTx := tx.(*types.UnbondTx)
unbondTx.Signature = privAccounts[0].Sign(unbondTx).(account.SignatureEd25519)
case *types.RebondTx:
rebondTx := tx.(*types.RebondTx)
rebondTx.Signature = privAccounts[0].Sign(rebondTx).(account.SignatureEd25519)
}
return tx, nil
}

26
rpc/core/validators.go Normal file
View File

@ -0,0 +1,26 @@
package core
import (
sm "github.com/tendermint/tendermint/state"
)
//-----------------------------------------------------------------------------
func ListValidators() (uint, []*sm.Validator, []*sm.Validator) {
var blockHeight uint
var bondedValidators []*sm.Validator
var unbondingValidators []*sm.Validator
state := consensusState.GetState()
blockHeight = state.LastBlockHeight
state.BondedValidators.Iterate(func(index uint, val *sm.Validator) bool {
bondedValidators = append(bondedValidators, val)
return false
})
state.UnbondingValidators.Iterate(func(index uint, val *sm.Validator) bool {
unbondingValidators = append(unbondingValidators, val)
return false
})
return blockHeight, bondedValidators, unbondingValidators
}