mirror of
https://github.com/arnaucube/slowlorisdb.git
synced 2026-02-28 05:46:48 +01:00
add node create blocks from pending txs
This commit is contained in:
@@ -43,6 +43,20 @@ type Block struct {
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
func (block Block) Copy() *Block {
|
||||
return &Block{
|
||||
Height: block.Height,
|
||||
PrevHash: block.PrevHash,
|
||||
NextHash: block.NextHash,
|
||||
Txs: block.Txs,
|
||||
Miner: block.Miner,
|
||||
Timestamp: block.Timestamp,
|
||||
Nonce: block.Nonce,
|
||||
Hash: block.Hash,
|
||||
Signature: block.Signature,
|
||||
}
|
||||
}
|
||||
|
||||
// Bytes outputs a byte array containing the data of the Block
|
||||
func (blk Block) Bytes() []byte {
|
||||
b, _ := json.Marshal(blk)
|
||||
@@ -56,16 +70,25 @@ func (blk *Block) GetNonce() uint64 {
|
||||
func (blk *Block) IncrementNonce() {
|
||||
blk.Nonce++
|
||||
}
|
||||
func (block *Block) CalculatePoW(difficulty int) error {
|
||||
hash := HashBytes(block.Bytes())
|
||||
func (block *Block) CalculatePoW(difficulty uint64) error {
|
||||
blockCopy := block.Copy()
|
||||
blockCopy.Hash = Hash{}
|
||||
|
||||
hash := HashBytes(blockCopy.Bytes())
|
||||
for !CheckPoW(hash, difficulty) {
|
||||
block.IncrementNonce()
|
||||
hash = HashBytes(block.Bytes())
|
||||
blockCopy.IncrementNonce()
|
||||
hash = HashBytes(blockCopy.Bytes())
|
||||
}
|
||||
block.Hash = hash
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckBlockPoW(block *Block, difficulty uint64) bool {
|
||||
blockCopy := block.Copy()
|
||||
blockCopy.Hash = Hash{}
|
||||
return CheckPoW(HashBytes(blockCopy.Bytes()), difficulty)
|
||||
}
|
||||
|
||||
func BlockFromBytes(b []byte) (*Block, error) {
|
||||
var block *Block
|
||||
err := json.Unmarshal(b, &block)
|
||||
|
||||
@@ -18,11 +18,14 @@ func TestBlock(t *testing.T) {
|
||||
Hash: HashBytes([]byte("blockhash")),
|
||||
}
|
||||
|
||||
block, err := BlockFromBytes(block.Bytes())
|
||||
blockParsed, err := BlockFromBytes(block.Bytes())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, block.Bytes(), block.Bytes())
|
||||
assert.Equal(t, blockParsed.Bytes(), block.Bytes())
|
||||
|
||||
difficulty := 2
|
||||
blockCopy := block.Copy()
|
||||
assert.Equal(t, blockCopy.Bytes(), block.Bytes())
|
||||
|
||||
difficulty := uint64(2)
|
||||
nonce, err := CalculatePoW(block, difficulty)
|
||||
assert.Nil(t, err)
|
||||
block.Nonce = nonce
|
||||
@@ -47,7 +50,7 @@ func TestNewBlock(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, block2.Bytes(), block.Bytes())
|
||||
|
||||
difficulty := 2
|
||||
difficulty := uint64(2)
|
||||
nonce, err := CalculatePoW(block, difficulty)
|
||||
assert.Nil(t, err)
|
||||
block.Nonce = nonce
|
||||
|
||||
@@ -8,18 +8,20 @@ import (
|
||||
)
|
||||
|
||||
type Blockchain struct {
|
||||
Id []byte // Id allows to have multiple blockchains
|
||||
Genesis Hash
|
||||
LastBlock *Block
|
||||
db *db.Db
|
||||
Id []byte // Id allows to have multiple blockchains
|
||||
Difficulty uint64
|
||||
Genesis Hash
|
||||
LastBlock *Block
|
||||
db *db.Db
|
||||
}
|
||||
|
||||
func NewBlockchain(database *db.Db) *Blockchain {
|
||||
func NewBlockchain(database *db.Db, dif uint64) *Blockchain {
|
||||
blockchain := &Blockchain{
|
||||
Id: []byte{},
|
||||
Genesis: Hash{},
|
||||
LastBlock: &Block{},
|
||||
db: database,
|
||||
Id: []byte{},
|
||||
Difficulty: dif,
|
||||
Genesis: HashBytes([]byte("genesis")),
|
||||
LastBlock: &Block{},
|
||||
db: database,
|
||||
}
|
||||
return blockchain
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestBlockchainDataStructure(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
bc := NewBlockchain(db)
|
||||
bc := NewBlockchain(db, uint64(1))
|
||||
block := bc.NewBlock([]Tx{})
|
||||
|
||||
block2, err := BlockFromBytes(block.Bytes())
|
||||
@@ -28,7 +28,7 @@ func TestGetBlock(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
bc := NewBlockchain(db)
|
||||
bc := NewBlockchain(db, uint64(1))
|
||||
|
||||
block := bc.NewBlock([]Tx{})
|
||||
assert.Equal(t, block.Height, uint64(1))
|
||||
@@ -47,12 +47,11 @@ func TestGetPrevBlock(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
difficulty := 1
|
||||
bc := NewBlockchain(db)
|
||||
bc := NewBlockchain(db, uint64(1))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
block := bc.NewBlock([]Tx{})
|
||||
block.CalculatePoW(difficulty)
|
||||
block.CalculatePoW(bc.Difficulty)
|
||||
assert.Equal(t, block.Height, uint64(i+1))
|
||||
|
||||
err = bc.AddBlock(block)
|
||||
@@ -83,7 +82,7 @@ func TestAddBlockWithTx(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
bc := NewBlockchain(db)
|
||||
bc := NewBlockchain(db, uint64(1))
|
||||
|
||||
var txs []Tx
|
||||
tx := NewTx(addr0, addr1, []Input{}, []Output{})
|
||||
|
||||
@@ -31,7 +31,7 @@ type PoWData interface {
|
||||
}
|
||||
|
||||
// CheckPoW verifies the PoW difficulty of a Hash
|
||||
func CheckPoW(hash Hash, difficulty int) bool {
|
||||
func CheckPoW(hash Hash, difficulty uint64) bool {
|
||||
var empty [32]byte
|
||||
if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) {
|
||||
return false
|
||||
@@ -40,7 +40,7 @@ func CheckPoW(hash Hash, difficulty int) bool {
|
||||
}
|
||||
|
||||
// CalculatePoW calculates the nonce for the given data in order to fit in the current Proof of Work difficulty
|
||||
func CalculatePoW(data PoWData, difficulty int) (uint64, error) {
|
||||
func CalculatePoW(data PoWData, difficulty uint64) (uint64, error) {
|
||||
hash := HashBytes(data.Bytes())
|
||||
for !CheckPoW(hash, difficulty) {
|
||||
data.IncrementNonce()
|
||||
|
||||
@@ -36,7 +36,7 @@ func (d *testData) IncrementNonce() {
|
||||
}
|
||||
|
||||
func TestPoW(t *testing.T) {
|
||||
difficulty := 2
|
||||
difficulty := uint64(2)
|
||||
data := &testData{
|
||||
Data: []byte("test"),
|
||||
Nonce: 0,
|
||||
|
||||
@@ -45,9 +45,9 @@ func AddressFromPrivK(privK *ecdsa.PrivateKey) Address {
|
||||
return Address(h)
|
||||
}
|
||||
|
||||
func (sig *Signature) Bytes(r, s *big.Int) []byte {
|
||||
b := r.Bytes()
|
||||
b = append(b, s.Bytes()...)
|
||||
func (sig *Signature) Bytes() []byte {
|
||||
b := sig.R.Bytes()
|
||||
b = append(b, sig.S.Bytes()...)
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
29
node/node.go
29
node/node.go
@@ -8,19 +8,20 @@ import (
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
PrivK *ecdsa.PrivateKey
|
||||
Addr core.Address
|
||||
Bc *core.Blockchain
|
||||
PrivK *ecdsa.PrivateKey
|
||||
Addr core.Address
|
||||
Bc *core.Blockchain
|
||||
PendingTxs []core.Tx
|
||||
}
|
||||
|
||||
func NewNode(db *db.Db) (*Node, error) {
|
||||
func NewNode(db *db.Db, dif uint64) (*Node, error) {
|
||||
privK, err := core.NewKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr := core.AddressFromPrivK(privK)
|
||||
|
||||
bc := core.NewBlockchain(db)
|
||||
bc := core.NewBlockchain(db, dif)
|
||||
|
||||
node := &Node{
|
||||
PrivK: privK,
|
||||
@@ -33,3 +34,21 @@ func NewNode(db *db.Db) (*Node, error) {
|
||||
func (node *Node) Sign(m []byte) (*core.Signature, error) {
|
||||
return core.Sign(node.PrivK, m)
|
||||
}
|
||||
|
||||
func (node *Node) AddToPendingTxs(tx core.Tx) {
|
||||
node.PendingTxs = append(node.PendingTxs, tx)
|
||||
}
|
||||
|
||||
func (node *Node) BlockFromPendingTxs() (*core.Block, error) {
|
||||
block := node.Bc.NewBlock(node.PendingTxs)
|
||||
err := block.CalculatePoW(node.Bc.Difficulty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sig, err := node.Sign(block.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block.Signature = sig.Bytes()
|
||||
return block, nil
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func TestNode(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
node, err := NewNode(db)
|
||||
node, err := NewNode(db, uint64(1))
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, node.Addr, core.AddressFromPrivK(node.PrivK))
|
||||
@@ -27,7 +27,7 @@ func TestNodeSignature(t *testing.T) {
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
node, err := NewNode(db)
|
||||
node, err := NewNode(db, uint64(1))
|
||||
assert.Nil(t, err)
|
||||
|
||||
m := []byte("test")
|
||||
@@ -36,3 +36,38 @@ func TestNodeSignature(t *testing.T) {
|
||||
pubK := node.PrivK.PublicKey
|
||||
assert.True(t, core.VerifySignature(&pubK, m, *sig))
|
||||
}
|
||||
|
||||
func TestBlockFromPendingTxs(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("", "db")
|
||||
assert.Nil(t, err)
|
||||
db, err := db.New(dir)
|
||||
assert.Nil(t, err)
|
||||
|
||||
node, err := NewNode(db, uint64(1))
|
||||
assert.Nil(t, err)
|
||||
|
||||
addr0 := core.Address(core.HashBytes([]byte("addr0")))
|
||||
addr1 := core.Address(core.HashBytes([]byte("addr1")))
|
||||
tx := core.NewTx(addr0, addr1, []core.Input{}, []core.Output{})
|
||||
node.AddToPendingTxs(*tx)
|
||||
block, err := node.BlockFromPendingTxs()
|
||||
assert.True(t, core.CheckBlockPoW(block, node.Bc.Difficulty))
|
||||
// TODO add VerifyBlockSignature
|
||||
}
|
||||
|
||||
// func TestBlockFromPendingTxsIteration(t *testing.T) {
|
||||
// dir, err := ioutil.TempDir("", "db")
|
||||
// assert.Nil(t, err)
|
||||
// db, err := db.New(dir)
|
||||
// assert.Nil(t, err)
|
||||
//
|
||||
// node, err := NewNode(db, uint64(1))
|
||||
// assert.Nil(t, err)
|
||||
//
|
||||
// addr0 := core.Address(core.HashBytes([]byte("addr0")))
|
||||
// addr1 := core.Address(core.HashBytes([]byte("addr1")))
|
||||
// for i := 0; i < 10; i++ {
|
||||
// tx := core.NewTx(addr0, addr1, []core.Input{}, []core.Output{})
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user