From b25b61438d7a641c5e02905aa1e514da3358caba Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Wed, 7 Jan 2015 01:15:39 -0800 Subject: [PATCH] blockchain & block rpc handlers --- block/store.go | 24 ++++++++++++++++++++---- rpc/blocks.go | 22 +++++++++++++++++++++- rpc/http_handler.go | 2 +- rpc/http_server.go | 5 +++-- rpc/mempool.go | 27 +++++++-------------------- 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/block/store.go b/block/store.go index dd7881d83..a453895ce 100644 --- a/block/store.go +++ b/block/store.go @@ -51,7 +51,11 @@ func (bs *BlockStore) GetReader(key []byte) Unreader { func (bs *BlockStore) LoadBlock(height uint) *Block { var n int64 var err error - meta := ReadBinary(&BlockMeta{}, bs.GetReader(calcBlockMetaKey(height)), &n, &err).(*BlockMeta) + r := bs.GetReader(calcBlockMetaKey(height)) + if r == nil { + panic(Fmt("Block does not exist at height %v", height)) + } + meta := ReadBinary(&BlockMeta{}, r, &n, &err).(*BlockMeta) if err != nil { panic(Fmt("Error reading block meta: %v", err)) } @@ -70,7 +74,11 @@ func (bs *BlockStore) LoadBlock(height uint) *Block { func (bs *BlockStore) LoadBlockPart(height uint, index uint) *Part { var n int64 var err error - part := ReadBinary(&Part{}, bs.GetReader(calcBlockPartKey(height, index)), &n, &err).(*Part) + r := bs.GetReader(calcBlockPartKey(height, index)) + if r == nil { + panic(Fmt("BlockPart does not exist for height %v index %v", height, index)) + } + part := ReadBinary(&Part{}, r, &n, &err).(*Part) if err != nil { panic(Fmt("Error reading block part: %v", err)) } @@ -80,7 +88,11 @@ func (bs *BlockStore) LoadBlockPart(height uint, index uint) *Part { func (bs *BlockStore) LoadBlockMeta(height uint) *BlockMeta { var n int64 var err error - meta := ReadBinary(&BlockMeta{}, bs.GetReader(calcBlockMetaKey(height)), &n, &err).(*BlockMeta) + r := bs.GetReader(calcBlockMetaKey(height)) + if r == nil { + panic(Fmt("BlockMeta does not exist for height %v", height)) + } + meta := ReadBinary(&BlockMeta{}, r, &n, &err).(*BlockMeta) if err != nil { panic(Fmt("Error reading block meta: %v", err)) } @@ -90,7 +102,11 @@ func (bs *BlockStore) LoadBlockMeta(height uint) *BlockMeta { func (bs *BlockStore) LoadBlockValidation(height uint) *Validation { var n int64 var err error - validation := ReadBinary(&Validation{}, bs.GetReader(calcBlockValidationKey(height)), &n, &err).(*Validation) + r := bs.GetReader(calcBlockValidationKey(height)) + if r == nil { + panic(Fmt("Validation does not exist for height %v", height)) + } + validation := ReadBinary(&Validation{}, r, &n, &err).(*Validation) if err != nil { panic(Fmt("Error reading validation: %v", err)) } diff --git a/rpc/blocks.go b/rpc/blocks.go index c3a59bff5..e454cf281 100644 --- a/rpc/blocks.go +++ b/rpc/blocks.go @@ -17,9 +17,11 @@ func BlockchainInfoHandler(w http.ResponseWriter, r *http.Request) { maxHeight, _ := GetParamUint(r, "max_height") if maxHeight == 0 { maxHeight = blockStore.Height() + } else { + maxHeight = MinUint(blockStore.Height(), maxHeight) } if minHeight == 0 { - minHeight = MaxUint(0, maxHeight-20) + minHeight = MaxUint(1, maxHeight-20) } blockMetas := []*BlockMeta{} @@ -35,3 +37,21 @@ func BlockchainInfoHandler(w http.ResponseWriter, r *http.Request) { WriteAPIResponse(w, API_OK, res) return } + +//----------------------------------------------------------------------------- + +func BlockHandler(w http.ResponseWriter, r *http.Request) { + height, _ := GetParamUint(r, "height") + if height == 0 { + WriteAPIResponse(w, API_INVALID_PARAM, "height must be greater than 1") + return + } + if height > blockStore.Height() { + WriteAPIResponse(w, API_INVALID_PARAM, "height must be less than the current blockchain height") + return + } + + block := blockStore.LoadBlock(height) + WriteAPIResponse(w, API_OK, block) + return +} diff --git a/rpc/http_handler.go b/rpc/http_handler.go index 5d44fdebe..e55a28a67 100644 --- a/rpc/http_handler.go +++ b/rpc/http_handler.go @@ -37,7 +37,7 @@ func WriteAPIResponse(w http.ResponseWriter, status APIStatus, data interface{}) res.Data = data buf, n, err := new(bytes.Buffer), new(int64), new(error) - binary.WriteJSON(res, w, n, err) + binary.WriteJSON(res, buf, n, err) if *err != nil { log.Warn("Failed to write JSON APIResponse", "error", err) } diff --git a/rpc/http_server.go b/rpc/http_server.go index d829bde19..6a78ecb12 100644 --- a/rpc/http_server.go +++ b/rpc/http_server.go @@ -9,8 +9,9 @@ import ( func StartHTTPServer() { - http.HandleFunc("/block", BlockchainInfoHandler) - http.HandleFunc("/mempool", MempoolHandler) + http.HandleFunc("/blockchain", BlockchainInfoHandler) + http.HandleFunc("/block", BlockHandler) + http.HandleFunc("/broadcast_tx", BroadcastTxHandler) log.Info(Fmt("Starting RPC HTTP server on %s", Config.RPC.HTTPLAddr)) diff --git a/rpc/mempool.go b/rpc/mempool.go index 6b317fff1..dafe7386a 100644 --- a/rpc/mempool.go +++ b/rpc/mempool.go @@ -1,8 +1,6 @@ package rpc import ( - "bytes" - "fmt" "net/http" . "github.com/tendermint/tendermint/binary" @@ -10,36 +8,25 @@ import ( . "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") +func BroadcastTxHandler(w http.ResponseWriter, r *http.Request) { + txJSON := GetParam(r, "tx") + var err error + tx := ReadJSON(struct{ Tx }{}, []byte(txJSON), &err).(struct{ Tx }).Tx if err != nil { - WriteAPIResponse(w, API_INVALID_PARAM, Fmt("Invalid tx_bytes: %v", err)) + WriteAPIResponse(w, API_INVALID_PARAM, Fmt("Invalid tx: %v", err)) return } - reader, n := bytes.NewReader(txBytes), new(int64) - tx_ := ReadBinary(struct{ Tx }{}, reader, n, &err).(struct{ Tx }) - if err != nil { - WriteAPIResponse(w, API_INVALID_PARAM, Fmt("Invalid tx_bytes: %v", err)) - return - } - tx := tx_.Tx - err = mempoolReactor.BroadcastTx(tx) if err != nil { WriteAPIResponse(w, API_ERROR, Fmt("Error broadcasting transaction: %v", err)) return } - jsonBytes := JSONBytes(tx) - fmt.Println(">>", string(jsonBytes)) - - WriteAPIResponse(w, API_OK, Fmt("Broadcasted tx: %X", tx)) + WriteAPIResponse(w, API_OK, "") return } /* -curl -H 'content-type: text/plain;' http://127.0.0.1:8888/mempool?tx_bytes=0101146070FF17C39B2B0A64CA2BC431328037FA0F4760640000000000000001014025BE0AD9344DA24BC12FCB84903F88AB9B82107F414A0B570048CDEF7EDDD5AC96B34F0405B7A75B761447F8E6C899343F1EDB160B4C4FAAE92D5881D0023A0701206BD490C212E701A2136EEEA04F06FA4F287EE47E2B7A9B5D62EDD84CD6AD975301146070FF17C39B2B0A64CA2BC431328037FA0F47FF6400000000000000 +curl -H 'content-type: text/plain;' http://127.0.0.1:8888/submit_tx?tx=... */