fiz: correções da pool

This commit is contained in:
Júnior
2025-06-17 18:26:14 -03:00
parent 682027d517
commit 9259f36e9c
31 changed files with 373 additions and 269 deletions

View File

@ -3,6 +3,7 @@ package api
import (
"net/http"
"strconv"
"github.com/gorilla/mux"
)
@ -12,7 +13,7 @@ func (h *Handler) ListBlocks(w http.ResponseWriter, r *http.Request) {
WriteError(w, http.StatusInternalServerError, "Erro ao listar blocos")
return
}
WriteJSON(w, blocks)
WriteJSON(w, http.StatusOK, blocks)
}
func (h *Handler) GetBlockByHeight(w http.ResponseWriter, r *http.Request) {
@ -27,5 +28,5 @@ func (h *Handler) GetBlockByHeight(w http.ResponseWriter, r *http.Request) {
WriteError(w, http.StatusNotFound, "Bloco não encontrado")
return
}
WriteJSON(w, block)
}
WriteJSON(w, http.StatusOK, block)
}

View File

@ -5,8 +5,9 @@ import (
"net/http"
"strconv"
"github.com/gorilla/mux"
"dejo_node/internal/dao"
"github.com/gorilla/mux"
)
type CreateProposalRequest struct {
@ -30,7 +31,7 @@ func (h *Handler) CreateProposal(w http.ResponseWriter, r *http.Request) {
}
p := DaoStore.Create(req.Title, req.Content, req.Creator, dao.ProposalType(req.Type), req.Duration)
_ = DaoStore.SaveToDisk("data/proposals.db")
WriteJSON(w, p)
WriteJSON(w, http.StatusOK, p)
}
func (h *Handler) VoteProposal(w http.ResponseWriter, r *http.Request) {
@ -53,7 +54,7 @@ func (h *Handler) VoteProposal(w http.ResponseWriter, r *http.Request) {
_ = p.Vote(req.Address, req.Approve)
p.CheckAndClose(h.snapshotStakes())
_ = DaoStore.SaveToDisk("data/proposals.db")
WriteJSON(w, p)
WriteJSON(w, http.StatusOK, p)
}
func (h *Handler) GetProposal(w http.ResponseWriter, r *http.Request) {
@ -68,11 +69,11 @@ func (h *Handler) GetProposal(w http.ResponseWriter, r *http.Request) {
WriteError(w, http.StatusNotFound, "Proposta não encontrada")
return
}
WriteJSON(w, p)
WriteJSON(w, http.StatusOK, p)
}
func (h *Handler) ListProposals(w http.ResponseWriter, r *http.Request) {
WriteJSON(w, DaoStore.List())
WriteJSON(w, http.StatusOK, DaoStore.List())
}
func (h *Handler) snapshotStakes() map[string]uint64 {
@ -81,4 +82,4 @@ func (h *Handler) snapshotStakes() map[string]uint64 {
snapshot[addr] = entry.Amount
}
return snapshot
}
}

View File

@ -1,20 +1,33 @@
package api
import (
"dejo_node/internal/mempool"
"dejo_node/internal/staking"
"dejo_node/internal/storage"
"dejo_node/internal/transactions"
"net/http"
)
type Handler struct {
Store *storage.BlockStore
StakingStore *staking.StakingStore
Mempool *mempool.Mempool
Mempool *transactions.Mempool
}
func NewHandler() *Handler {
return &Handler{
Store: storage.NewBlockStore("data/blocks.json"),
StakingStore: staking.NewStakingStore(),
}
}
return &Handler{}
}
func (h *Handler) SetStores(blockStore *storage.BlockStore, stakingStore *staking.StakingStore, mempool *transactions.Mempool) {
h.Store = blockStore
h.StakingStore = stakingStore
h.Mempool = mempool
}
func (h *Handler) Ping(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("pong"))
}
func (h *Handler) HandleConsensus(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}

View File

@ -2,9 +2,10 @@ package api
import (
"net/http"
"time"
)
func (h *Handler) Health(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}
w.Write([]byte(time.Now().Format(time.RFC3339)))
}

View File

@ -2,41 +2,25 @@ package api
import (
"github.com/gorilla/mux"
"net/http"
)
func NewRouter(h *Handler) http.Handler {
r := mux.NewRouter()
r.HandleFunc("/health", h.Health).Methods("GET")
r.HandleFunc("/startup", h.Startup).Methods("GET")
r.HandleFunc("/ready", h.Ready).Methods("GET")
// ⚡ Transações
r.HandleFunc("/transaction", h.SendTransaction).Methods("POST")
r.HandleFunc("/transaction/{hash}", h.GetTransactionByHash).Methods("GET")
// 🔐 Staking
r.HandleFunc("/stake", h.StakeHandler).Methods("POST")
r.HandleFunc("/unstake", h.UnstakeHandler).Methods("POST")
r.HandleFunc("/stake/{address}", h.GetStakeInfo).Methods("GET")
// 🗳️ DAO
r.HandleFunc("/dao/proposals", h.CreateProposal).Methods("POST")
r.HandleFunc("/dao/proposals/{id}/vote", h.VoteProposal).Methods("POST")
r.HandleFunc("/dao/proposals", h.ListProposals).Methods("GET")
r.HandleFunc("/dao/proposals/{id}", h.GetProposal).Methods("GET")
// 💰 Accounts
r.HandleFunc("/accounts/{address}", HandleGetBalance).Methods("GET")
r.HandleFunc("/accounts/{address}/txs", HandleGetTransactionsByAddress).Methods("GET")
// 📦 Blocos
func (h *Handler) RegisterRoutes(r *mux.Router) {
// Rotas de blocos
r.HandleFunc("/blocks", h.ListBlocks).Methods("GET")
r.HandleFunc("/blocks/{height}", h.GetBlockByHeight).Methods("GET")
// ❤️ Heartbeat
r.HandleFunc("/ping", HandlePing).Methods("GET")
// Rotas de staking
r.HandleFunc("/stake", h.Stake).Methods("POST")
r.HandleFunc("/unstake", h.Unstake).Methods("POST")
r.HandleFunc("/stake-info", h.GetStakeInfo).Methods("GET")
return r
}
// Rotas de transações
r.HandleFunc("/tx", h.SubmitTransaction).Methods("POST")
r.HandleFunc("/tx/{hash}", h.GetTransaction).Methods("GET")
// Rotas de consenso
r.HandleFunc("/consensus", h.HandleConsensus).Methods("POST")
// Health check
r.HandleFunc("/ping", h.Ping).Methods("GET")
}

View File

@ -1,21 +1,19 @@
package api
import (
"github.com/gorilla/mux"
"net/http"
"dejo_node/internal/ws"
"net/http"
"github.com/gorilla/mux"
)
func NewServer(handler *Handler) http.Handler {
r := mux.NewRouter()
// ⚠️ Endpoints removidos temporariamente pois ainda não foram implementados
// r.HandleFunc("/block/latest", handler.GetLatestBlock).Methods("GET")
// r.HandleFunc("/block/{index}", handler.GetBlockByIndex).Methods("GET")
// r.HandleFunc("/tx/{hash}", handler.GetTransactionByHash).Methods("GET")
// r.HandleFunc("/tx", handler.PostTransaction).Methods("POST")
// r.HandleFunc("/oracle/{key}", handler.GetOracleValue).Methods("GET")
// Endpoints básicos
r.HandleFunc("/ping", handler.Ping).Methods("GET")
r.HandleFunc("/consensus", handler.HandleConsensus).Methods("POST")
r.HandleFunc("/ws", ws.HandleWS).Methods("GET")
return r
}
}

View File

@ -1,53 +1,52 @@
package api
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"strconv"
)
type StakeRequest struct {
Address string `json:"address"`
Amount uint64 `json:"amount"`
Duration int64 `json:"duration"`
}
type UnstakeRequest struct {
Address string `json:"address"`
}
func (h *Handler) StakeHandler(w http.ResponseWriter, r *http.Request) {
var req StakeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
WriteError(w, http.StatusBadRequest, "Invalid request")
return
}
if err := h.StakingStore.Stake(req.Address, req.Amount, uint64(req.Duration)); err != nil {
WriteError(w, http.StatusInternalServerError, "Failed to stake")
return
}
WriteJSON(w, map[string]string{"message": "Stake registered successfully"})
}
func (h *Handler) UnstakeHandler(w http.ResponseWriter, r *http.Request) {
var req UnstakeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
WriteError(w, http.StatusBadRequest, "Invalid request")
return
}
if err := h.StakingStore.Unstake(req.Address); err != nil {
WriteError(w, http.StatusInternalServerError, "Failed to unstake")
return
}
WriteJSON(w, map[string]string{"message": "Unstake successful"})
}
func (h *Handler) GetStakeInfo(w http.ResponseWriter, r *http.Request) {
address := mux.Vars(r)["address"]
info, ok := h.StakingStore.GetStakeInfo(address)
if !ok {
WriteError(w, http.StatusNotFound, "Stake info not found")
address := r.URL.Query().Get("address")
info, exists := h.StakingStore.GetStakeInfo(address)
if !exists {
WriteError(w, http.StatusNotFound, "Endereço não encontrado")
return
}
WriteJSON(w, info)
}
WriteJSON(w, http.StatusOK, info)
}
func (h *Handler) Stake(w http.ResponseWriter, r *http.Request) {
address := r.URL.Query().Get("address")
amountStr := r.URL.Query().Get("amount")
durationStr := r.URL.Query().Get("duration")
amount, err := strconv.ParseUint(amountStr, 10, 64)
if err != nil {
WriteError(w, http.StatusBadRequest, "Valor inválido")
return
}
duration, err := strconv.ParseUint(durationStr, 10, 64)
if err != nil {
WriteError(w, http.StatusBadRequest, "Duração inválida")
return
}
err = h.StakingStore.Stake(address, amount, duration)
if err != nil {
WriteError(w, http.StatusInternalServerError, "Erro ao realizar stake")
return
}
w.WriteHeader(http.StatusOK)
}
func (h *Handler) Unstake(w http.ResponseWriter, r *http.Request) {
address := r.URL.Query().Get("address")
err := h.StakingStore.Unstake(address)
if err != nil {
WriteError(w, http.StatusInternalServerError, "Erro ao remover stake")
return
}
w.WriteHeader(http.StatusOK)
}

View File

@ -1,30 +1,33 @@
package api
import (
"encoding/json"
"log"
"net/http"
"dejo_node/internal/transactions"
"net/http"
)
func (h *Handler) SendTransaction(w http.ResponseWriter, r *http.Request) {
log.Println("📥 Nova transação recebida")
func (h *Handler) SubmitTransaction(w http.ResponseWriter, r *http.Request) {
var tx transactions.Transaction
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&tx); err != nil {
http.Error(w, "formato inválido", http.StatusBadRequest)
err := ReadJSON(r, &tx)
if err != nil {
WriteError(w, http.StatusBadRequest, "Transação inválida")
return
}
if tx.From == "" || tx.To == "" || tx.Value <= 0 {
http.Error(w, "transação inválida", http.StatusBadRequest)
err = h.Mempool.Add(&tx)
if err != nil {
WriteError(w, http.StatusInternalServerError, "Erro ao adicionar transação")
return
}
h.Mempool.Add(&tx)
log.Printf("✅ Transação adicionada ao mempool: %+v\n", tx)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
}
func (h *Handler) GetTransaction(w http.ResponseWriter, r *http.Request) {
hash := r.URL.Query().Get("hash")
tx := h.Mempool.GetByHash(hash)
if tx == nil {
WriteError(w, http.StatusNotFound, "Transação não encontrada")
return
}
WriteJSON(w, http.StatusOK, tx)
}

View File

@ -5,18 +5,17 @@ import (
"net/http"
)
func WriteError(w http.ResponseWriter, code int, msg string) {
w.WriteHeader(code)
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"success": false,
"error": msg,
})
func WriteJSON(w http.ResponseWriter, status int, v any) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
return json.NewEncoder(w).Encode(v)
}
func WriteJSON(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"data": data,
})
}
func ReadJSON(r *http.Request, v any) error {
return json.NewDecoder(r.Body).Decode(v)
}
func WriteError(w http.ResponseWriter, status int, message string) {
w.WriteHeader(status)
json.NewEncoder(w).Encode(map[string]string{"error": message})
}