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
|
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
|
// Bytes outputs a byte array containing the data of the Block
|
||||||
func (blk Block) Bytes() []byte {
|
func (blk Block) Bytes() []byte {
|
||||||
b, _ := json.Marshal(blk)
|
b, _ := json.Marshal(blk)
|
||||||
@@ -56,16 +70,25 @@ func (blk *Block) GetNonce() uint64 {
|
|||||||
func (blk *Block) IncrementNonce() {
|
func (blk *Block) IncrementNonce() {
|
||||||
blk.Nonce++
|
blk.Nonce++
|
||||||
}
|
}
|
||||||
func (block *Block) CalculatePoW(difficulty int) error {
|
func (block *Block) CalculatePoW(difficulty uint64) error {
|
||||||
hash := HashBytes(block.Bytes())
|
blockCopy := block.Copy()
|
||||||
|
blockCopy.Hash = Hash{}
|
||||||
|
|
||||||
|
hash := HashBytes(blockCopy.Bytes())
|
||||||
for !CheckPoW(hash, difficulty) {
|
for !CheckPoW(hash, difficulty) {
|
||||||
block.IncrementNonce()
|
blockCopy.IncrementNonce()
|
||||||
hash = HashBytes(block.Bytes())
|
hash = HashBytes(blockCopy.Bytes())
|
||||||
}
|
}
|
||||||
block.Hash = hash
|
block.Hash = hash
|
||||||
return nil
|
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) {
|
func BlockFromBytes(b []byte) (*Block, error) {
|
||||||
var block *Block
|
var block *Block
|
||||||
err := json.Unmarshal(b, &block)
|
err := json.Unmarshal(b, &block)
|
||||||
|
|||||||
@@ -18,11 +18,14 @@ func TestBlock(t *testing.T) {
|
|||||||
Hash: HashBytes([]byte("blockhash")),
|
Hash: HashBytes([]byte("blockhash")),
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := BlockFromBytes(block.Bytes())
|
blockParsed, err := BlockFromBytes(block.Bytes())
|
||||||
assert.Nil(t, err)
|
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)
|
nonce, err := CalculatePoW(block, difficulty)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
block.Nonce = nonce
|
block.Nonce = nonce
|
||||||
@@ -47,7 +50,7 @@ func TestNewBlock(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, block2.Bytes(), block.Bytes())
|
assert.Equal(t, block2.Bytes(), block.Bytes())
|
||||||
|
|
||||||
difficulty := 2
|
difficulty := uint64(2)
|
||||||
nonce, err := CalculatePoW(block, difficulty)
|
nonce, err := CalculatePoW(block, difficulty)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
block.Nonce = nonce
|
block.Nonce = nonce
|
||||||
|
|||||||
@@ -8,18 +8,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Blockchain struct {
|
type Blockchain struct {
|
||||||
Id []byte // Id allows to have multiple blockchains
|
Id []byte // Id allows to have multiple blockchains
|
||||||
Genesis Hash
|
Difficulty uint64
|
||||||
LastBlock *Block
|
Genesis Hash
|
||||||
db *db.Db
|
LastBlock *Block
|
||||||
|
db *db.Db
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlockchain(database *db.Db) *Blockchain {
|
func NewBlockchain(database *db.Db, dif uint64) *Blockchain {
|
||||||
blockchain := &Blockchain{
|
blockchain := &Blockchain{
|
||||||
Id: []byte{},
|
Id: []byte{},
|
||||||
Genesis: Hash{},
|
Difficulty: dif,
|
||||||
LastBlock: &Block{},
|
Genesis: HashBytes([]byte("genesis")),
|
||||||
db: database,
|
LastBlock: &Block{},
|
||||||
|
db: database,
|
||||||
}
|
}
|
||||||
return blockchain
|
return blockchain
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func TestBlockchainDataStructure(t *testing.T) {
|
|||||||
db, err := db.New(dir)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
bc := NewBlockchain(db)
|
bc := NewBlockchain(db, uint64(1))
|
||||||
block := bc.NewBlock([]Tx{})
|
block := bc.NewBlock([]Tx{})
|
||||||
|
|
||||||
block2, err := BlockFromBytes(block.Bytes())
|
block2, err := BlockFromBytes(block.Bytes())
|
||||||
@@ -28,7 +28,7 @@ func TestGetBlock(t *testing.T) {
|
|||||||
db, err := db.New(dir)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
bc := NewBlockchain(db)
|
bc := NewBlockchain(db, uint64(1))
|
||||||
|
|
||||||
block := bc.NewBlock([]Tx{})
|
block := bc.NewBlock([]Tx{})
|
||||||
assert.Equal(t, block.Height, uint64(1))
|
assert.Equal(t, block.Height, uint64(1))
|
||||||
@@ -47,12 +47,11 @@ func TestGetPrevBlock(t *testing.T) {
|
|||||||
db, err := db.New(dir)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
difficulty := 1
|
bc := NewBlockchain(db, uint64(1))
|
||||||
bc := NewBlockchain(db)
|
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
block := bc.NewBlock([]Tx{})
|
block := bc.NewBlock([]Tx{})
|
||||||
block.CalculatePoW(difficulty)
|
block.CalculatePoW(bc.Difficulty)
|
||||||
assert.Equal(t, block.Height, uint64(i+1))
|
assert.Equal(t, block.Height, uint64(i+1))
|
||||||
|
|
||||||
err = bc.AddBlock(block)
|
err = bc.AddBlock(block)
|
||||||
@@ -83,7 +82,7 @@ func TestAddBlockWithTx(t *testing.T) {
|
|||||||
db, err := db.New(dir)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
bc := NewBlockchain(db)
|
bc := NewBlockchain(db, uint64(1))
|
||||||
|
|
||||||
var txs []Tx
|
var txs []Tx
|
||||||
tx := NewTx(addr0, addr1, []Input{}, []Output{})
|
tx := NewTx(addr0, addr1, []Input{}, []Output{})
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type PoWData interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckPoW verifies the PoW difficulty of a Hash
|
// 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
|
var empty [32]byte
|
||||||
if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) {
|
if !bytes.Equal(hash[:][0:difficulty], empty[0:difficulty]) {
|
||||||
return false
|
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
|
// 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())
|
hash := HashBytes(data.Bytes())
|
||||||
for !CheckPoW(hash, difficulty) {
|
for !CheckPoW(hash, difficulty) {
|
||||||
data.IncrementNonce()
|
data.IncrementNonce()
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func (d *testData) IncrementNonce() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPoW(t *testing.T) {
|
func TestPoW(t *testing.T) {
|
||||||
difficulty := 2
|
difficulty := uint64(2)
|
||||||
data := &testData{
|
data := &testData{
|
||||||
Data: []byte("test"),
|
Data: []byte("test"),
|
||||||
Nonce: 0,
|
Nonce: 0,
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ func AddressFromPrivK(privK *ecdsa.PrivateKey) Address {
|
|||||||
return Address(h)
|
return Address(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sig *Signature) Bytes(r, s *big.Int) []byte {
|
func (sig *Signature) Bytes() []byte {
|
||||||
b := r.Bytes()
|
b := sig.R.Bytes()
|
||||||
b = append(b, s.Bytes()...)
|
b = append(b, sig.S.Bytes()...)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
node/node.go
29
node/node.go
@@ -8,19 +8,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
PrivK *ecdsa.PrivateKey
|
PrivK *ecdsa.PrivateKey
|
||||||
Addr core.Address
|
Addr core.Address
|
||||||
Bc *core.Blockchain
|
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()
|
privK, err := core.NewKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
addr := core.AddressFromPrivK(privK)
|
addr := core.AddressFromPrivK(privK)
|
||||||
|
|
||||||
bc := core.NewBlockchain(db)
|
bc := core.NewBlockchain(db, dif)
|
||||||
|
|
||||||
node := &Node{
|
node := &Node{
|
||||||
PrivK: privK,
|
PrivK: privK,
|
||||||
@@ -33,3 +34,21 @@ func NewNode(db *db.Db) (*Node, error) {
|
|||||||
func (node *Node) Sign(m []byte) (*core.Signature, error) {
|
func (node *Node) Sign(m []byte) (*core.Signature, error) {
|
||||||
return core.Sign(node.PrivK, m)
|
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)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
node, err := NewNode(db)
|
node, err := NewNode(db, uint64(1))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, node.Addr, core.AddressFromPrivK(node.PrivK))
|
assert.Equal(t, node.Addr, core.AddressFromPrivK(node.PrivK))
|
||||||
@@ -27,7 +27,7 @@ func TestNodeSignature(t *testing.T) {
|
|||||||
db, err := db.New(dir)
|
db, err := db.New(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
node, err := NewNode(db)
|
node, err := NewNode(db, uint64(1))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
m := []byte("test")
|
m := []byte("test")
|
||||||
@@ -36,3 +36,38 @@ func TestNodeSignature(t *testing.T) {
|
|||||||
pubK := node.PrivK.PublicKey
|
pubK := node.PrivK.PublicKey
|
||||||
assert.True(t, core.VerifySignature(&pubK, m, *sig))
|
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