2021-05-12 19:34:14 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
2021-07-19 20:19:06 +00:00
|
|
|
"encoding/binary"
|
2021-05-12 19:34:14 +00:00
|
|
|
"time"
|
|
|
|
|
2021-06-10 20:31:44 +00:00
|
|
|
"github.com/Secured-Finance/dione/types"
|
|
|
|
|
2021-06-08 21:30:23 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/crypto"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
|
2021-05-12 19:34:14 +00:00
|
|
|
"github.com/wealdtech/go-merkletree"
|
|
|
|
"github.com/wealdtech/go-merkletree/keccak256"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Block struct {
|
|
|
|
Header *BlockHeader
|
|
|
|
Data []*Transaction
|
|
|
|
}
|
|
|
|
|
|
|
|
type BlockHeader struct {
|
2021-05-26 20:57:54 +00:00
|
|
|
Timestamp int64
|
|
|
|
Height uint64
|
|
|
|
Hash []byte
|
|
|
|
LastHash []byte
|
|
|
|
LastHashProof *merkletree.Proof
|
2021-07-11 23:23:00 +00:00
|
|
|
Proposer *peer.ID
|
2021-06-08 21:30:23 +00:00
|
|
|
ProposerEth common.Address
|
2021-05-26 20:57:54 +00:00
|
|
|
Signature []byte
|
2021-06-10 20:31:44 +00:00
|
|
|
BeaconEntry types.BeaconEntry
|
|
|
|
ElectionProof *types.ElectionProof
|
2021-05-12 19:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func GenesisBlock() *Block {
|
|
|
|
return &Block{
|
|
|
|
Header: &BlockHeader{
|
|
|
|
Timestamp: 1620845070,
|
2021-05-25 15:32:06 +00:00
|
|
|
Height: 0,
|
2021-05-12 19:34:14 +00:00
|
|
|
Hash: []byte("DIMICANDUM"),
|
|
|
|
},
|
|
|
|
Data: []*Transaction{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-11 11:40:32 +00:00
|
|
|
func CreateBlock(lastBlockHeader *BlockHeader, txs []*Transaction, minerEth common.Address, privateKey crypto.PrivKey, eproof *types.ElectionProof) (*Block, error) {
|
2021-07-19 22:38:55 +00:00
|
|
|
timestamp := time.Now().UnixNano()
|
2021-05-12 19:34:14 +00:00
|
|
|
|
|
|
|
// extract hashes from transactions
|
2021-07-19 20:19:06 +00:00
|
|
|
var merkleHashes [][]byte
|
2021-05-12 19:34:14 +00:00
|
|
|
for _, tx := range txs {
|
2021-07-19 20:19:06 +00:00
|
|
|
merkleHashes = append(merkleHashes, tx.Hash)
|
2021-05-12 19:34:14 +00:00
|
|
|
}
|
2021-07-19 20:19:06 +00:00
|
|
|
merkleHashes = append(merkleHashes, lastBlockHeader.Hash)
|
|
|
|
timestampBytes := make([]byte, 8)
|
|
|
|
binary.LittleEndian.PutUint64(timestampBytes, uint64(timestamp))
|
|
|
|
merkleHashes = append(merkleHashes, timestampBytes)
|
2021-05-12 19:34:14 +00:00
|
|
|
|
2021-07-19 20:19:06 +00:00
|
|
|
tree, err := merkletree.NewUsing(merkleHashes, keccak256.New(), true)
|
2021-05-12 19:34:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// fetch merkle tree root hash (block hash)
|
|
|
|
blockHash := tree.Root()
|
|
|
|
|
2021-06-08 21:30:23 +00:00
|
|
|
// sign the block hash
|
|
|
|
s, err := privateKey.Sign(blockHash)
|
2021-05-12 19:34:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-05-26 20:57:54 +00:00
|
|
|
lastHashProof, err := tree.GenerateProof(lastBlockHeader.Hash, 0)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-06-08 21:30:23 +00:00
|
|
|
proposer, err := peer.IDFromPrivateKey(privateKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-07-11 23:23:00 +00:00
|
|
|
for _, tx := range txs {
|
|
|
|
mp, err := tree.GenerateProof(tx.Hash, 0)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
tx.MerkleProof = mp
|
|
|
|
}
|
|
|
|
|
2021-05-12 19:34:14 +00:00
|
|
|
block := &Block{
|
|
|
|
Header: &BlockHeader{
|
2021-05-26 20:57:54 +00:00
|
|
|
Timestamp: timestamp,
|
|
|
|
Height: lastBlockHeader.Height + 1,
|
2021-07-11 23:23:00 +00:00
|
|
|
Proposer: &proposer,
|
2021-06-08 21:30:23 +00:00
|
|
|
ProposerEth: minerEth,
|
|
|
|
Signature: s,
|
2021-05-26 20:57:54 +00:00
|
|
|
Hash: blockHash,
|
|
|
|
LastHash: lastBlockHeader.Hash,
|
|
|
|
LastHashProof: lastHashProof,
|
2021-06-11 11:40:32 +00:00
|
|
|
ElectionProof: eproof,
|
2021-05-12 19:34:14 +00:00
|
|
|
},
|
|
|
|
Data: txs,
|
|
|
|
}
|
|
|
|
|
|
|
|
return block, nil
|
|
|
|
}
|