diff --git a/cmd/daemon.go b/cmd/daemon.go index f8d45003..4246006f 100644 --- a/cmd/daemon.go +++ b/cmd/daemon.go @@ -22,6 +22,7 @@ type Node struct { pexReactor *p2p.PEXReactor mempoolReactor *mempool_.MempoolReactor consensusReactor *consensus.ConsensusReactor + state *state_.State privValidator *state_.PrivValidator } @@ -66,6 +67,7 @@ func NewNode() *Node { pexReactor: pexReactor, mempoolReactor: mempoolReactor, consensusReactor: consensusReactor, + state: state, privValidator: privValidator, } } @@ -136,6 +138,8 @@ func daemon() { // Run the RPC server. if config.Config.RPC.HTTPPort != 0 { + rpc.SetRPCState(n.state) + rpc.SetRPCMempoolReactor(n.mempoolReactor) rpc.StartHTTPServer() } diff --git a/rpc/blocks.go b/rpc/blocks.go index 65334758..14aa4095 100644 --- a/rpc/blocks.go +++ b/rpc/blocks.go @@ -1,4 +1,3 @@ -// Maybe move this to blocks/handler.go package rpc import ( diff --git a/rpc/http_params.go b/rpc/http_params.go index dfd192da..e091abad 100644 --- a/rpc/http_params.go +++ b/rpc/http_params.go @@ -1,6 +1,7 @@ package rpc import ( + "encoding/hex" "net/http" "regexp" "strconv" @@ -34,7 +35,12 @@ func GetParam(r *http.Request, param string) string { return s } -func GetParamInt64Safe(r *http.Request, param string) (int64, error) { +func GetParamByteSlice(r *http.Request, param string) ([]byte, error) { + s := GetParam(r, param) + return hex.DecodeString(s) +} + +func GetParamInt64(r *http.Request, param string) (int64, error) { s := GetParam(r, param) i, err := strconv.ParseInt(s, 10, 64) if err != nil { @@ -42,15 +48,8 @@ func GetParamInt64Safe(r *http.Request, param string) (int64, error) { } return i, nil } -func GetParamInt64(r *http.Request, param string) int64 { - i, err := GetParamInt64Safe(r, param) - if err != nil { - panicAPI(err) - } - return i -} -func GetParamInt32Safe(r *http.Request, param string) (int32, error) { +func GetParamInt32(r *http.Request, param string) (int32, error) { s := GetParam(r, param) i, err := strconv.ParseInt(s, 10, 32) if err != nil { @@ -58,15 +57,8 @@ func GetParamInt32Safe(r *http.Request, param string) (int32, error) { } return int32(i), nil } -func GetParamInt32(r *http.Request, param string) int32 { - i, err := GetParamInt32Safe(r, param) - if err != nil { - panicAPI(err) - } - return i -} -func GetParamUint64Safe(r *http.Request, param string) (uint64, error) { +func GetParamUint64(r *http.Request, param string) (uint64, error) { s := GetParam(r, param) i, err := strconv.ParseUint(s, 10, 64) if err != nil { @@ -74,30 +66,16 @@ func GetParamUint64Safe(r *http.Request, param string) (uint64, error) { } return i, nil } -func GetParamUint64(r *http.Request, param string) uint64 { - i, err := GetParamUint64Safe(r, param) - if err != nil { - panicAPI(err) - } - return i -} -func GetParamRegexpSafe(r *http.Request, param string, re *regexp.Regexp) (string, error) { +func GetParamRegexp(r *http.Request, param string, re *regexp.Regexp) (string, error) { s := GetParam(r, param) if !re.MatchString(s) { return "", Errorf(param, "Did not match regular expression %v", re.String()) } return s, nil } -func GetParamRegexp(r *http.Request, param string, re *regexp.Regexp, required bool) string { - s, err := GetParamRegexpSafe(r, param, re) - if (required || s != "") && err != nil { - panicAPI(err) - } - return s -} -func GetParamFloat64Safe(r *http.Request, param string) (float64, error) { +func GetParamFloat64(r *http.Request, param string) (float64, error) { s := GetParam(r, param) f, err := strconv.ParseFloat(s, 64) if err != nil { @@ -105,10 +83,3 @@ func GetParamFloat64Safe(r *http.Request, param string) (float64, error) { } return f, nil } -func GetParamFloat64(r *http.Request, param string) float64 { - f, err := GetParamFloat64Safe(r, param) - if err != nil { - panicAPI(err) - } - return f -} diff --git a/rpc/http_server.go b/rpc/http_server.go index 630faeba..aecb36b2 100644 --- a/rpc/http_server.go +++ b/rpc/http_server.go @@ -11,6 +11,7 @@ import ( func StartHTTPServer() { http.HandleFunc("/block", BlockHandler) + http.HandleFunc("/mempool", MempoolHandler) // Serve HTTP on localhost only. // Let something like Nginx handle HTTPS connections. diff --git a/rpc/mempool.go b/rpc/mempool.go new file mode 100644 index 00000000..6b6ce6c8 --- /dev/null +++ b/rpc/mempool.go @@ -0,0 +1,36 @@ +package rpc + +import ( + "bytes" + "net/http" + + "github.com/tendermint/tendermint/block" + . "github.com/tendermint/tendermint/common" +) + +func MempoolHandler(w http.ResponseWriter, r *http.Request) { + //height, _ := GetParamUint64Safe(r, "height") + //count, _ := GetParamUint64Safe(r, "count") + txBytes, err := GetParamByteSlice(r, "tx_bytes") + if err != nil { + ReturnJSON(API_INVALID_PARAM, Fmt("Invalid tx_bytes: %v", err)) + } + + reader, n := bytes.NewReader(txBytes), new(int64) + tx := block.TxDecoder(reader, n, &err).(block.Tx) + if err != nil { + ReturnJSON(API_INVALID_PARAM, Fmt("Invalid tx_bytes: %v", err)) + } + + err = mempoolReactor.BroadcastTx(tx) + if err != nil { + ReturnJSON(API_ERROR, Fmt("Error broadcasting transaction: %v", err)) + } + + ReturnJSON(API_OK, Fmt("Broadcasted tx: %X", tx)) +} + +/* +curl --data 'tx_bytes=0101146070FF17C39B2B0A64CA2BC431328037FA0F476064000000000000000001407D28F5CEE2065FCB2952CA9B99E9F9855E992B0FA5862442F582F2A84C3B3B31154A86D54DD548AFF080697BDC15AF26E68416AA678EF29449BB8D273B73320502206BD490C212E701A2136EEEA04F06FA4F287EE47E2B7A9B5D62EDD84CD6AD975301146070FF17C39B2B0A64CA2BC431328037FA0F47606400000000000000' -H 'content-type: text/plain;' http://127.0.0.1:8888/mempool +tx: 0101146070FF17C39B2B0A64CA2BC431328037FA0F476064000000000000000001407D28F5CEE2065FCB2952CA9B99E9F9855E992B0FA5862442F582F2A84C3B3B31154A86D54DD548AFF080697BDC15AF26E68416AA678EF29449BB8D273B73320502206BD490C212E701A2136EEEA04F06FA4F287EE47E2B7A9B5D62EDD84CD6AD975301146070FF17C39B2B0A64CA2BC431328037FA0F47606400000000000000 +*/ diff --git a/rpc/rpc.go b/rpc/rpc.go new file mode 100644 index 00000000..5a3b70c6 --- /dev/null +++ b/rpc/rpc.go @@ -0,0 +1,17 @@ +package rpc + +import ( + mempool_ "github.com/tendermint/tendermint/mempool" + state_ "github.com/tendermint/tendermint/state" +) + +var state *state_.State +var mempoolReactor *mempool_.MempoolReactor + +func SetRPCState(state__ *state_.State) { + state = state__ +} + +func SetRPCMempoolReactor(mempoolReactor_ *mempool_.MempoolReactor) { + mempoolReactor = mempoolReactor_ +}