Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions REST/EPAccount.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package REST

import (
"fmt"
"github.com/bazo-blockchain/bazo-client/client"
"github.com/bazo-blockchain/bazo-client/network"
"github.com/bazo-blockchain/bazo-miner/protocol"
"github.com/gorilla/mux"
"math/big"
"net/http"
Expand All @@ -16,22 +15,13 @@ func GetAccountEndpoint(w http.ResponseWriter, req *http.Request) {
logger.Printf("Incoming acc request for id: %v", param)

var address [64]byte
var addressHash [32]byte

pubKeyInt, _ := new(big.Int).SetString(param, 16)

if len(param) == 64 {
copy(addressHash[:], pubKeyInt.Bytes())

network.AccReq(false, addressHash)

accI, _ := network.Fetch(network.AccChan)
acc := accI.(*protocol.Account)

address = acc.Address
} else if len(param) == 128 {
if len(param) == 128 {
copy(address[:], pubKeyInt.Bytes())
addressHash = protocol.SerializeHashContent(address)
} else {
logger.Fatal(fmt.Sprintf("provided invalid address %x\n", param))
}

acc, lastTenTx, err := client.GetAccount(address)
Expand Down
2 changes: 0 additions & 2 deletions cli/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ func checkAccount(args *accountArgs, logger *log.Logger) error {
address = crypto.GetAddressFromPubKey(&privKey.PublicKey)
}

logger.Printf("My address: %x\n", address)

acc, _, err := client.CheckAccount(address)
if err != nil {
logger.Println(err)
Expand Down
13 changes: 12 additions & 1 deletion cli/funds.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"errors"
"fmt"
"github.com/bazo-blockchain/bazo-client/client"
"github.com/bazo-blockchain/bazo-client/cstorage"
"github.com/bazo-blockchain/bazo-client/network"
"github.com/bazo-blockchain/bazo-client/util"
"github.com/bazo-blockchain/bazo-miner/crypto"
"github.com/bazo-blockchain/bazo-miner/p2p"
"github.com/bazo-blockchain/bazo-miner/protocol"
"github.com/urfave/cli"
"log"
"sort"
)

type fundsArgs struct {
Expand Down Expand Up @@ -117,7 +119,14 @@ func sendFunds(args *fundsArgs, logger *log.Logger) error {
fromAddress := crypto.GetAddressFromPubKey(&fromPrivKey.PublicKey)
toAddress := crypto.GetAddressFromPubKey(toPubKey)

tx, err := protocol.ConstrFundsTx(
client.SyncBeforeTx(fromAddress)

proofs, err := cstorage.ReadMerkleProofs()
sort.Slice(proofs, func(i, j int) bool {
return proofs[i].Height > proofs[j].Height
})

tx, err := protocol.NewSignedFundsTx(
byte(args.header),
uint64(args.amount),
uint64(args.fee),
Expand All @@ -132,6 +141,8 @@ func sendFunds(args *fundsArgs, logger *log.Logger) error {
return err
}

tx.Proofs = proofs

if err := network.SendTx(util.Config.BootstrapIpport, tx, p2p.FUNDSTX_BRDCST); err != nil {
logger.Printf("%v\n", err)
return err
Expand Down
1 change: 1 addition & 0 deletions cli/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func GetRestCommand() cli.Command {
Name: "rest",
Usage: "start the REST service",
Action: func(c *cli.Context) error {
client.Init()
client.Sync()
REST.Init()
return nil
Expand Down
4 changes: 2 additions & 2 deletions client/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ func GetAccount(address [64]byte) (*Account, []*FundsTxJson, error) {
//Set default params
activeParameters = miner.NewDefaultParameters()

network.AccReq(false, protocol.SerializeHashContent(account.Address))
network.AccReq(false, account.Address)
if accI, _ := network.Fetch(network.AccChan); accI != nil {
if acc := accI.(*protocol.Account); acc != nil {
account.IsCreated = true
account.IsStaking = acc.IsStaking

network.AccReq(true, protocol.SerializeHashContent(account.Address))
network.AccReq(true, account.Address)
if rootAccI, _ := network.Fetch(network.AccChan); rootAccI != nil {
if rootAcc := rootAccI.(*protocol.Account); rootAcc != nil {
account.IsRoot = true
Expand Down
204 changes: 134 additions & 70 deletions client/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@ var (
)

//Update allBlockHeaders to the latest header. Start listening to broadcasted headers after.
func SyncBeforeTx(address [64]byte) {
loadBlockHeaders()
incomingBlockHeaders(true)
GetAccount(address)
}

func Sync() {
loadBlockHeaders()
go incomingBlockHeaders()
go incomingBlockHeaders(false)
}

func loadBlockHeaders() {
var last *protocol.Block

//youngest = fetchBlockHeader(nil)
if last = cstorage.ReadLastBlockHeader(); last != nil {
if last, _ = cstorage.ReadLastBlockHeader(); last != nil {
var loaded []*protocol.Block
loaded = loadDB(last, [32]byte{}, loaded)
blockHeaders = append(blockHeaders, loaded...)
Expand All @@ -40,7 +46,7 @@ func loadBlockHeaders() {
network.Uptodate = true
}

func incomingBlockHeaders() {
func incomingBlockHeaders(untilSynced bool) {
for {
blockHeaderIn := <-network.BlockHeaderIn

Expand Down Expand Up @@ -85,6 +91,10 @@ func incomingBlockHeaders() {

blockHeaders = append(blockHeaders, blockHeaderIn)
cstorage.WriteLastBlockHeader(blockHeaderIn)

if untilSynced {
return
}
}
}
}
Expand Down Expand Up @@ -118,7 +128,7 @@ func loadDB(last *protocol.Block, abort [32]byte, loaded []*protocol.Block) []*p
var ancestor *protocol.Block

if last.PrevHash != abort {
if ancestor = cstorage.ReadBlockHeader(last.PrevHash); ancestor == nil {
if ancestor, _ = cstorage.ReadBlockHeader(last.PrevHash); ancestor == nil {
logger.Fatal()
}

Expand Down Expand Up @@ -174,83 +184,137 @@ func getState(acc *Account, lastTenTx []*FundsTxJson) (err error) {

relevantBlocks, err := getRelevantBlocks(relevantHeadersConfigBF)
for _, block := range relevantBlocks {
if block != nil {
//Balance funds and collect fee
for _, txHash := range block.FundsTxData {
err := network.TxReq(p2p.FUNDSTX_REQ, txHash)
if err != nil {
return err
}

txI, err := network.Fetch(network.FundsTxChan)
if err != nil {
return err
}

tx := txI.(protocol.Transaction)
fundsTx := txI.(*protocol.FundsTx)

if fundsTx.From == acc.Address || fundsTx.To == acc.Address || block.Beneficiary == acc.Address {
//Validate tx
if err := validateTx(block, tx, txHash); err != nil {
return err
}

if fundsTx.From == acc.Address {
//If Acc is no root, balance funds
if !acc.IsRoot {
acc.Balance -= fundsTx.Amount
acc.Balance -= fundsTx.Fee
}

acc.TxCnt += 1
}

if fundsTx.To == acc.Address {
acc.Balance += fundsTx.Amount

put(lastTenTx, ConvertFundsTx(fundsTx, "verified"))
}

if block.Beneficiary == acc.Address {
acc.Balance += fundsTx.Fee
}
}
}
if block == nil {
continue
}

//Update config parameters and collect fee
for _, txHash := range block.ConfigTxData {
err := network.TxReq(p2p.CONFIGTX_REQ, txHash)
if err != nil {
return err
}
err = updateConfigParameters(block)
if err != nil {
return err
}

txI, err := network.Fetch(network.ConfigTxChan)
if err != nil {
return err
}
// Check if bloomfilter returns false, if yes, the block has nothing related to account's address
if !block.BloomFilter.Test(acc.Address[:]) {
continue
}

tx := txI.(protocol.Transaction)
configTx := txI.(*protocol.ConfigTx)
fundsTxs, err := requestFundsTx(block)

configTxSlice := []*protocol.ConfigTx{configTx}
// Check if it's a block with a Bloomfilter that returns false positive
if len(fundsTxs) == 0 && block.Beneficiary != acc.Address {
// TODO @rmnblm
}

if block.Beneficiary == acc.Address {
//Validate tx
if err := validateTx(block, tx, txHash); err != nil {
return err
}
err = balanceFunds(fundsTxs, block, acc, lastTenTx)
if err != nil {
return err
}

acc.Balance += configTx.Fee
}
if block.Beneficiary == acc.Address {
acc.Balance += block.TotalFees
}
}

miner.CheckAndChangeParameters(&activeParameters, &configTxSlice)
}
return nil
}

//TODO stakeTx
func requestFundsTx(block *protocol.Block) (fundsTxs []*protocol.FundsTx, err error) {
for _, txHash := range block.FundsTxData {
err := network.TxReq(p2p.FUNDSTX_REQ, txHash)
if err != nil {
return nil, err
}

txI, err := network.Fetch(network.FundsTxChan)
if err != nil {
return nil, err
}

fundsTx := txI.(*protocol.FundsTx)
fundsTxs = append(fundsTxs, fundsTx)
}

return fundsTxs, nil
}

func balanceFunds(fundsTxs []*protocol.FundsTx, block *protocol.Block, acc *Account, lastTenTx []*FundsTxJson) error {
bucket := protocol.NewTxBucket(acc.Address)

for _, fundsTx := range fundsTxs {
if fundsTx.From == acc.Address || fundsTx.To == acc.Address {
bucket.AddFundsTx(fundsTx)
}
}

bucketHash := bucket.Hash()
if err := validateBucket(block, bucketHash); err != nil {
return err
}

for _, fundsTx := range bucket.Transactions {
// Check if account is sender of a transaction
if fundsTx.From == acc.Address {
//If Acc is no root, balance funds
if !acc.IsRoot {
acc.Balance -= fundsTx.Amount
acc.Balance -= fundsTx.Fee
}
acc.TxCnt += 1
}

if fundsTx.To == acc.Address {
acc.Balance += fundsTx.Amount
put(lastTenTx, ConvertFundsTx(fundsTx, "verified"))
}
}

// Create the Merkle proof for this block
merkleTree := block.BuildMerkleTree()
mhashes, err := merkleTree.MerkleProof(bucketHash)
if err != nil {
return err
}

proof := protocol.NewMerkleProof(
block.Height,
mhashes,
bucket.Address,
bucket.RelativeBalance,
bucket.CalculateMerkleRoot())

err = cstorage.WriteMerkleProof(&proof)
if err != nil {
return err
}

logger.Printf("Merkle proof written to client storage for tx at block height %v", block.Height)

return nil
}

func updateConfigParameters(block *protocol.Block) error {
for _, txHash := range block.ConfigTxData {
err := network.TxReq(p2p.CONFIGTX_REQ, txHash)
if err != nil {
return err
}

txI, err := network.Fetch(network.ConfigTxChan)
if err != nil {
return err
}

tx := txI.(protocol.Transaction)
configTx := txI.(*protocol.ConfigTx)

//Validate tx
if err := validateTx(block, tx, txHash); err != nil {
return err
}

configTxSlice := []*protocol.ConfigTx{configTx}
miner.CheckAndChangeParameters(&activeParameters, &configTxSlice)
}

return nil
}
Loading