Skip to content

Commit

Permalink
improved code
Browse files Browse the repository at this point in the history
  • Loading branch information
OsauravO committed Apr 28, 2024
1 parent 0837c57 commit a4da1a3
Show file tree
Hide file tree
Showing 2 changed files with 3,256 additions and 142 deletions.
265 changes: 127 additions & 138 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ const TargetValue string = "0000ffff00000000000000000000000000000000000000000000

// checkByteArray compares two byte arrays lexicographically
func checkByteArray(a, b []byte) int {
minLength := len(a)
if len(b) < minLength {
minLength = len(b)
mini := len(a)
if len(b) < mini {
mini = len(b)
}

for i := 0; i < minLength; i++ {
for i := 0; i < mini; i++ {
if a[i] < b[i] {
return -1
} else if a[i] > b[i] {
Expand Down Expand Up @@ -150,12 +150,15 @@ func checkByteArray(a, b []byte) int {
func proofOfWork(blockHeader *BlockHeader) bool {
targetBytes, _ := hex.DecodeString(TargetValue)
for {
serializedHeader := srlzBhead(blockHeader)
hash := reverseBytes(sha256Hash(sha256Hash(serializedHeader)))
sh := srlzBhead(blockHeader)
hash := reverseBytes(sha256Hash(sha256Hash(sh)))
if checkByteArray(hash, targetBytes) == -1 {
return true
}
if blockHeader.Nonce < 0 || blockHeader.Nonce > 0xffffffff {
if blockHeader.Nonce < 0 {
return false
}
if blockHeader.Nonce > 0xffffffff{
return false
}
blockHeader.Nonce++
Expand Down Expand Up @@ -205,7 +208,7 @@ func isSegWitTransaction(tx *Transaction) bool {
}

func CreateCoinbase(netReward uint64) *Transaction {
witnessCommitment := witnMerkle()
witComm := witnMerkle()
coinbaseTx := Transaction{
Version: 1,
Vin: []Input{
Expand Down Expand Up @@ -234,8 +237,8 @@ func CreateCoinbase(netReward uint64) *Transaction {
Value: uint64(netReward),
},
{
Scriptpubkey: "6a24" + "aa21a9ed" + witnessCommitment, //OPRETURN +OP_PUSHBYTES_36+ commitment header + witnessCommitment
ScriptpubkeyAsm: "OP_RETURN" + "OP_PUSHBYTES_36" + "aa21a9ed" + witnessCommitment,
Scriptpubkey: "6a24" + "aa21a9ed" + witComm, //OPRETURN +OP_PUSHBYTES_36+ commitment header + witComm
ScriptpubkeyAsm: "OP_RETURN" + "OP_PUSHBYTES_36" + "aa21a9ed" + witComm,
ScriptpubkeyType: "op_return",
ScriptpubkeyAddress: "bc1qma9lnumzzpejq2l9ntjepa2lg2re5gdqn3nf0c",
Value: uint64(0),
Expand All @@ -247,43 +250,38 @@ func CreateCoinbase(netReward uint64) *Transaction {
}

func merkNode(lnode *MerkleNode, rnode *MerkleNode, data []byte) *MerkleNode {
var mn MerkleNode = MerkleNode{}
if lnode == nil && rnode == nil {
//hash256 of the data
mn.Data = reverseBytes(data)
} else {
var prevHash []byte = append(lnode.Data, rnode.Data...)
// var node MerkleNode = *merkNode(nil, nil, data)
// nodes = append(nodes, node)
mn.Data = sha256Hash(sha256Hash(prevHash))
}
mn.Left = lnode
mn.Right = rnode
return &mn
node := &MerkleNode{}
if lnode == nil && rnode == nil {
node.Data = reverseBytes(data)
} else {
combinedHash := append(lnode.Data, rnode.Data...)
node.Data = sha256Hash(sha256Hash(combinedHash))
}
node.Left = lnode
node.Right = rnode
return node
}

func merkTree(leaves []string) *MerkleNode {
var nodes []MerkleNode

for _, leaf := range leaves {
data, _ := hex.DecodeString(leaf)
var node MerkleNode = *merkNode(nil, nil, data)
nodes = append(nodes, node)
}

for len(nodes) > 1 {
var newLevel []MerkleNode
for i := 0; i < len(nodes); i += 2 {
// handleError case where the total number of nodes is odd.
if len(nodes)%2 != 0 {
nodes = append(nodes, nodes[len(nodes)-1])
}
node := *merkNode(&nodes[i], &nodes[i+1], nil)
newLevel = append(newLevel, node)
}
nodes = newLevel
}
return &nodes[0]
var nodes []*MerkleNode
for _, leaf := range leaves {
data, _ := hex.DecodeString(leaf)
node := merkNode(nil, nil, data)
nodes = append(nodes, node)
}
for len(nodes) > 1 {
var nextLevel []*MerkleNode
for i := 0; i < len(nodes); i += 2 {
if i+1 == len(nodes) {
nextLevel = append(nextLevel, nodes[i])
break
}
node := merkNode(nodes[i], nodes[i+1], nil)
nextLevel = append(nextLevel, node)
}
nodes = nextLevel
}
return nodes[0]

}

Expand All @@ -303,53 +301,52 @@ func Comp(a, b TxInfo) bool {
return float64(a.Fee)/float64(a.Weight) > float64(b.Fee)/float64(b.Weight)
}
func Ordering() (uint64, []string, []string) {
var allowedTxIDs []string
var notAllowedTxIDs []string

Directory := "./mempool"
files, _ := os.ReadDir(Directory)
var txInfo []TxInfo
for _, file := range files {
txData, err := readJSON(Directory + "/" + file.Name())
handleError(err)
var tx Transaction
err = json.Unmarshal([]byte(txData), &tx)
var fee uint64 = 0
for _, vin := range tx.Vin {
fee += vin.Prevout.Value
}
for _, vout := range tx.Vout {
fee -= vout.Value
}
serlzd, _ := serTx(&tx)
segserlzd, _ := SegWitSerialize(&tx)
txID := reverseBytes(sha256Hash(sha256Hash(serlzd)))
wtxID := reverseBytes(sha256Hash(sha256Hash(segserlzd)))
txInfo = append(txInfo, TxInfo{TxID: hex.EncodeToString(txID), WTxID: hex.EncodeToString(wtxID), Fee: fee, Weight: uint64(calWitSize(&tx) + calBaseSize(&tx)*4)})
}
sort.Slice(txInfo, func(i, j int) bool {
return Comp(txInfo[i], txInfo[j])
})

var reward uint64 = 0
var allowedTxs []TxInfo
var maxWeight uint64 = 4000000
var targetScore float64 = 108.0

for _, tx := range txInfo {
remainingWeight := maxWeight - tx.Weight
currentScore := float64(reward+tx.Fee) / float64(maxWeight-remainingWeight) * 100.0

if remainingWeight >= 0 && currentScore <= targetScore {
allowedTxs = append(allowedTxs, tx)
maxWeight = remainingWeight
allowedTxIDs = append(allowedTxIDs, tx.TxID)
notAllowedTxIDs = append(notAllowedTxIDs, tx.WTxID)
reward += tx.Fee
}
}
var allowedTxIDs []string
var notAllowedTxIDs []string

return reward, allowedTxIDs, notAllowedTxIDs
Directory := "./mempool"
files, _ := os.ReadDir(Directory)
var txInfo []TxInfo
for _, file := range files {
txData, err := readJSON(Directory + "/" + file.Name())
handleError(err)
var tx Transaction
err = json.Unmarshal([]byte(txData), &tx)
var fee uint64 = 0
for _, vin := range tx.Vin {
fee += vin.Prevout.Value
}
for _, vout := range tx.Vout {
fee -= vout.Value
}
serlzd, _ := serTx(&tx)
segserlzd, _ := SegWitSerialize(&tx)
txID := reverseBytes(sha256Hash(sha256Hash(serlzd)))
wtxID := reverseBytes(sha256Hash(sha256Hash(segserlzd)))
txInfo = append(txInfo, TxInfo{TxID: hex.EncodeToString(txID), WTxID: hex.EncodeToString(wtxID), Fee: fee, Weight: uint64(calWitSize(&tx) + calBaseSize(&tx)*4)})

}
sort.Slice(txInfo, func(i, j int) bool {
return Comp(txInfo[i], txInfo[j])
})

var reward uint64 = 0
var allowedTxs []TxInfo
var maxWeight uint64 = 3900000
for _, tx := range txInfo {
if maxWeight >= tx.Weight {
allowedTxs = append(allowedTxs, tx)
maxWeight -= tx.Weight
allowedTxIDs = append(allowedTxIDs, tx.TxID)
notAllowedTxIDs = append(notAllowedTxIDs, tx.WTxID)
reward += tx.Fee
}
}

// allowedTxIDs = append(allowedTxIDs, tx.TxID)
// notAllowedTxIDs = append(notAllowedTxIDs, tx.WTxID)
// reward += tx.Fee
return reward, allowedTxIDs, notAllowedTxIDs
}

func SerializeVarInt(n uint64) []byte {
Expand All @@ -366,65 +363,57 @@ func SerializeVarInt(n uint64) []byte {

func serTx(tx *Transaction) ([]byte, error) {

var serlzd []byte
// Serialize version

versionBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(versionBytes, tx.Version)
serlzd = append(serlzd, versionBytes...)
// Serialize vin count
vinCount := uint64(len(tx.Vin))
serlzd = append(serlzd, SerializeVarInt(vinCount)...)
var serialized []byte

// Serialize vin
for _, vin := range tx.Vin {
txidBytes, _ := hex.DecodeString(vin.TxID)
serlzd = append(serlzd, reverseBytes(txidBytes)...)
// Serialize version
serialized = append(serialized, uint32ToLittleEndian(tx.Version)...)

voutBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(voutBytes, vin.Vout)
serlzd = append(serlzd, voutBytes...)
// Serialize vin count
serialized = append(serialized, SerializeVarInt(uint64(len(tx.Vin)))...)

Scriptsig_bytes, _ := hex.DecodeString(vin.Scriptsig)
length_scriptsig := (uint64(len(Scriptsig_bytes)))
serlzd = append(serlzd, SerializeVarInt(length_scriptsig)...)
// Serialize vin
for _, vin := range tx.Vin {
txidBytes, _ := hex.DecodeString(vin.TxID)
serialized = append(serialized, reverseBytes(txidBytes)...)
serialized = append(serialized, uint32ToLittleEndian(vin.Vout)...)

serlzd = append(serlzd, Scriptsig_bytes...)
scriptSigBytes, _ := hex.DecodeString(vin.Scriptsig)
serialized = append(serialized, SerializeVarInt(uint64(len(scriptSigBytes)))...)
serialized = append(serialized, scriptSigBytes...)

// Serialize sequence
sequenceBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(sequenceBytes, vin.Sequence)
serlzd = append(serlzd, sequenceBytes...)
serialized = append(serialized, uint32ToLittleEndian(vin.Sequence)...)
}

}
// Serialize vout count
serialized = append(serialized, SerializeVarInt(uint64(len(tx.Vout)))...)

// Serialize vout count
voutCount := uint64(len(tx.Vout))
serlzd = append(serlzd, SerializeVarInt(voutCount)...)
// Serialize vout
for _, vout := range tx.Vout {
serialized = append(serialized, uint64ToLittleEndian(vout.Value)...)

// Serialize vout
for _, vout := range tx.Vout {
valueBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(valueBytes, vout.Value)
serlzd = append(serlzd, valueBytes...)
scriptPubKeyBytes, err := hex.DecodeString(vout.Scriptpubkey)
if err != nil {
return nil, err
}
serialized = append(serialized, SerializeVarInt(uint64(len(scriptPubKeyBytes)))...)
serialized = append(serialized, scriptPubKeyBytes...)
}

// Serialize scriptPubKey length
scriptPubKeyBytes, err := hex.DecodeString(vout.Scriptpubkey)
scriptPubKeyLen := uint64(len(scriptPubKeyBytes)) // Divide by 2 if appending the length of the non decoded form to get byte length since scriptPubKey is hex encoded
serlzd = append(serlzd, SerializeVarInt(scriptPubKeyLen)...)
// Serialize locktime
serialized = append(serialized, uint32ToLittleEndian(tx.Locktime)...)

// Serialize scriptPubKey
if err != nil {
return nil, err
}
serlzd = append(serlzd, scriptPubKeyBytes...)
}
//Locktime
locktimeBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(locktimeBytes, tx.Locktime)
serlzd = append(serlzd, locktimeBytes...)
return serialized, nil
}
func uint32ToLittleEndian(value uint32) []byte {
bytes := make([]byte, 4)
binary.LittleEndian.PutUint32(bytes, value)
return bytes
}

return serlzd, nil
func uint64ToLittleEndian(value uint64) []byte {
bytes := make([]byte, 8)
binary.LittleEndian.PutUint64(bytes, value)
return bytes
}
func SegWitSerialize(tx *Transaction) ([]byte, error) {

Expand Down
Loading

0 comments on commit a4da1a3

Please sign in to comment.