commit inicial do projeto
This commit is contained in:
99
internal/state/state.go
Normal file
99
internal/state/state.go
Normal file
@ -0,0 +1,99 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"dejo_node/internal/staking"
|
||||
"dejo_node/internal/transactions"
|
||||
)
|
||||
|
||||
type State struct {
|
||||
mu sync.RWMutex
|
||||
Balances map[string]uint64
|
||||
}
|
||||
|
||||
func NewState() *State {
|
||||
return &State{
|
||||
Balances: make(map[string]uint64),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *State) Apply(tx *transactions.Transaction) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if tx.From == tx.To {
|
||||
return fmt.Errorf("transação inválida: origem = destino")
|
||||
}
|
||||
if tx.Value <= 0 {
|
||||
return fmt.Errorf("valor zero não permitido")
|
||||
}
|
||||
fromBal := s.Balances[tx.From]
|
||||
if fromBal < uint64(tx.Value) {
|
||||
return fmt.Errorf("saldo insuficiente: %s tem %d, precisa de %f", tx.From, fromBal, tx.Value)
|
||||
}
|
||||
s.Balances[tx.From] -= uint64(tx.Value)
|
||||
s.Balances[tx.To] += uint64(tx.Value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) Transfer(from, to string, amount uint64) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.Balances[from] < amount {
|
||||
return fmt.Errorf("saldo insuficiente")
|
||||
}
|
||||
s.Balances[from] -= amount
|
||||
s.Balances[to] += amount
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) Mint(to string, amount uint64) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.Balances[to] += amount
|
||||
}
|
||||
|
||||
func (s *State) Stake(address string, amount uint64, dur int64) error {
|
||||
if err := s.Transfer(address, "staking_pool", amount); err != nil {
|
||||
return err
|
||||
}
|
||||
return staking.NewStakingStore().Stake(address, amount, uint64(dur))
|
||||
}
|
||||
|
||||
func (s *State) Unstake(address string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if err := staking.NewStakingStore().Unstake(address); err != nil {
|
||||
return err
|
||||
}
|
||||
s.Balances[address] += 1000 // Exemplo: devolve saldo fixo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) SaveToDisk(path string) error {
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
enc := gob.NewEncoder(f)
|
||||
return enc.Encode(s.Balances)
|
||||
}
|
||||
|
||||
func (s *State) LoadFromDisk(path string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
s.Balances = make(map[string]uint64)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
dec := gob.NewDecoder(f)
|
||||
return dec.Decode(&s.Balances)
|
||||
}
|
||||
Reference in New Issue
Block a user