## 🧩 Roadmap DEJO Node v1.0.0 — Documentação Técnica Operacional

---

### 🧠 1. Execução de Transações no Bloco

#### **1.1. Estrutura de Contas**
> Implementar estrutura de dados que armazena contas, com saldo e nonce.

- Criar uma struct `Account`:
  ```go
  type Account struct {
      Balance uint64
      Nonce   uint64
  }
  ```
- Criar um `map[string]*Account` que representa o conjunto de contas (`state.accounts`)
- O acesso será via endereço (`string`) como chave
- Contas devem ser inicializadas com `Balance = 0` caso ainda não existam

---

#### **1.2. Aplicar Transações**
> Criar lógica que modifica o estado de contas ao aplicar uma transação do tipo `Transfer`.

- Criar função:
  ```go
  func (s *State) ApplyTransaction(tx *Transaction) error
  ```
- Verificar se:
  - Conta `from` existe
  - `from.Balance >= tx.Value`
  - `tx.Nonce == from.Nonce`
- Aplicar mudanças:
  - Deduzir `Value` da conta `from`
  - Acrescentar `Value` à conta `to`
  - Incrementar `Nonce` da conta `from`
- Retornar erro se transação for inválida

---

#### **1.3. Executar lote de transações ao final do bloco**
> Aplicar todas as transações do bloco no commit.

- No final do `StartConsensusLoop`, quando o bloco é finalizado:
  ```go
  for _, tx := range block.Txns {
      err := state.ApplyTransaction(tx)
      if err != nil {
          log.Printf("❌ Erro ao aplicar tx: %+v\n", err)
      }
  }
  ```

---

### 📚 2. Módulo de Estado (`internal/state`)

#### **2.1. Estrutura do módulo `state`**
> Centralizar toda lógica de mutação de estado (contas, staking, dao).

- Criar `internal/state/state.go`
- Definir `State`:
  ```go
  type State struct {
      Accounts map[string]*Account
      Staking  *staking.StakingStore
      DAO      *dao.DAOStore
  }
  ```
- Implementar métodos:
  - `ApplyTransaction(tx *Transaction) error`
  - `GetBalance(address string) uint64`
  - `Mint(address string, value uint64)`
  - `SaveToDisk(path string)` / `LoadFromDisk(path string)`

---

#### **2.2. Encapsular staking/DAO dentro de State**
> Injetar dependência de staking e DAO no state para simplificar o acesso global.

- Criar `NewState()` que instancia os campos `Accounts`, `Staking` e `DAO`
- Atualizar consenso e handlers para usar `state.Staking` e `state.DAO` em vez de referências diretas

---

### 💸 3. Recompensas e Penalidades

#### **3.1. Recompensa**
> Premiar validadores que participaram corretamente da rodada.

- No commit do bloco:
  - Calcular stake total que participou
  - Distribuir `totalReward = 5 tokens` proporcionalmente:
    ```go
    reward := (validatorStake * totalReward) / totalStake
    state.Mint(validatorID, reward)
    ```
- Validadores que não participaram não recebem nada

---

#### **3.2. Slash**
> Penalizar validadores que não participaram da rodada.

- Após o commit:
  - Identificar validadores ativos que **não** fizeram `PRECOMMIT`
  - Deduzir 50 tokens via:
    ```go
    state.accounts[validator].Balance -= 50
    ```

---

### 🌐 4. API REST Estendida

#### **4.1. `/accounts/{addr}`**
> Obter saldo e informações de conta.

- GET `/accounts/{addr}`
- Retornar:
  ```json
  {
    "address": "node-A",
    "balance": 950,
    "nonce": 3
  }
  ```

---

#### **4.2. `/validators`**
> Obter todos validadores ativos.

- GET `/validators`
- Retornar lista:
  ```json
  [
    { "address": "node-A", "stake": 1000, "status": "online" },
    ...
  ]
  ```

---

#### **4.3. `/dao/status`**
> Visualizar estado atual da DAO.

- GET `/dao/status`
- Retornar:
  - Propostas em aberto
  - Número de votos
  - % de quorum atingido
  - Tempo restante

---

### 🧪 5. Testes

#### **5.1. Testes com múltiplos nós**
> Verificar se transações em node-A aparecem em blocos de node-B.

- Lançar `node-A` e `node-B`
- Enviar `POST /transaction` em A
- Verificar `GET /blocks` em B e encontrar a transação

---

#### **5.2. Validação de saldo**
> Testar aplicação de transações.

- Verificar que saldo de `from` diminui
- Verificar que saldo de `to` aumenta
- Verificar que `Nonce` incrementa

---

#### **5.3. Testes de recompensas e penalidades**
> Validar que rewards/slash funcionam corretamente.

- Propor bloco com `node-A`, verificar +5 tokens
- Omissão de `PRECOMMIT` de `node-B`, verificar -50 tokens