Skip to content

Commit

Permalink
Merge pull request #8 from 0xsharma/shivam/add-send-tx
Browse files Browse the repository at this point in the history
add : send-tx cmd, fix downloader
  • Loading branch information
0xsharma authored Oct 24, 2023
2 parents 2958f34 + fa38e58 commit 8f1bc68
Show file tree
Hide file tree
Showing 15 changed files with 873 additions and 61 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ terminal/instance 3 : go run main.go start 3
And so on....
```

### Send Transactions


Make sure a node is running and note the endpoint.

```
go run main.go send-tx --to <TO_ADDR> --privatekey <SENDER_PRIV_KEY> --value <TX_VALUE> --rpc <RPC_ADDR> --nonce <NONCE>
```
example (also, will run with fresh chain and default config) :
```
go run main.go send-tx --to 0x93a63fc45341fc02ac9cce62cc5aeb5c5799403e --privatekey c3fc038a9abc0f483e2e1f8a0b4db676bce3eaebd7d9afc68e1e7e28ca8738a6 --value 1 --rpc localhost:17111 --nonce 0
```
(increase the nonce for the consecutive transactions by 1 to fire more transactions)
###### NOTE : Transactions can also be send using RPC calls directly.

### Run Tests

```
Expand Down
64 changes: 58 additions & 6 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
"github.com/0xsharma/compact-chain/types"
"github.com/0xsharma/compact-chain/util"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
version = "v0.0.1"
version = "v1.1.0"
rootCmd = &cobra.Command{}

versionCmd = &cobra.Command{
Expand All @@ -36,6 +37,32 @@ var (
},
}

sendTxCmd = &cobra.Command{
Use: "send-tx",
Short: "Send a transaction to the Compact-Chain node",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Sending transaction to Compact-Chain node\n\n")

flags := cmd.Flags()

to, _ := flags.GetString("to")
value, _ := flags.GetInt64("value")
privateKey, _ := flags.GetString("privatekey")
nonce, _ := flags.GetInt64("nonce")
rpcAddr, _ := flags.GetString("rpc")

sendTxCfg := &sendTxConfig{
To: to,
Value: value,
PrivateKey: privateKey,
Nonce: nonce,
RPCAddr: rpcAddr,
}

SendTx(sendTxCfg)
},
}

demoCmd = &cobra.Command{
Use: "demo",
Short: "Demo the Compact-Chain node",
Expand All @@ -51,10 +78,32 @@ func Execute() error {
return rootCmd.Execute()
}

// nolint : errcheck
func init() {
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(startCmd)
rootCmd.AddCommand(demoCmd)
rootCmd.AddCommand(sendTxCmd)

sendTxCmd.PersistentFlags().String("to", "", "To Address")
viper.BindPFlag("to", sendTxCmd.PersistentFlags().Lookup("to"))
cobra.MarkFlagRequired(sendTxCmd.PersistentFlags(), "to")

sendTxCmd.PersistentFlags().Int64("value", 0, "Value to send")
viper.BindPFlag("value", sendTxCmd.PersistentFlags().Lookup("value"))
cobra.MarkFlagRequired(sendTxCmd.PersistentFlags(), "value")

sendTxCmd.PersistentFlags().String("privatekey", "", "Private key to sign transaction")
viper.BindPFlag("privatekey", sendTxCmd.PersistentFlags().Lookup("privatekey"))
cobra.MarkFlagRequired(sendTxCmd.PersistentFlags(), "privatekey")

sendTxCmd.PersistentFlags().Int64("nonce", 0, "Nonce of transaction")
viper.BindPFlag("nonce", sendTxCmd.PersistentFlags().Lookup("nonce"))
cobra.MarkFlagRequired(sendTxCmd.PersistentFlags(), "nonce")

sendTxCmd.PersistentFlags().String("rpc", "", "RPC endpoint of node")
viper.BindPFlag("rpc", sendTxCmd.PersistentFlags().Lookup("rpc"))
cobra.MarkFlagRequired(sendTxCmd.PersistentFlags(), "rpc")
}

var (
Expand Down Expand Up @@ -109,11 +158,14 @@ func startBlockchainNode(nodeId int64) {
StateDBDir: stateDbPath + fmt.Sprint(nodeId),
MinFee: big.NewInt(100),
RPCPort: ":1711" + fmt.Sprint(nodeId),
BalanceAlloc: map[string]*big.Int{},
P2PPort: ":6060" + fmt.Sprint(nodeId),
Peers: []string{"localhost:60601", "localhost:60602", "localhost:60603"},
BlockTime: 4,
SignerPrivateKey: util.HexToPrivateKey("c3fc038a9abc0f483e2e1f8a0b4db676bce3eaebd7d9afc68e1e7e28ca8738a" + fmt.Sprint(nodeId)),
BalanceAlloc: map[string]*big.Int{
"0xa52c981eee8687b5e4afd69aa5006548c24d7685": big.NewInt(1000000000000000000), // Allocating funds to 0xa52c981eee8687b5e4afd69aa5006548c24d7685
},
P2PPort: ":6060" + fmt.Sprint(nodeId),
Peers: []string{"localhost:60601", "localhost:60602", "localhost:60603"},
BlockTime: 4,
SignerPrivateKey: util.HexToPrivateKey("c3fc038a9abc0f483e2e1f8a0b4db676bce3eaebd7d9afc68e1e7e28ca8738a" + fmt.Sprint(nodeId)),
Mine: true,
}

core.StartBlockchain(config)
Expand Down
59 changes: 59 additions & 0 deletions cmd/send-tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package cmd

import (
"fmt"
"log"
"math/big"
"net/rpc"

"github.com/0xsharma/compact-chain/types"
"github.com/0xsharma/compact-chain/util"
)

type sendTxConfig struct {
PrivateKey string
To string
Value int64
RPCAddr string
Nonce int64
}

func SendTx(sendTxCfg *sendTxConfig) {
ua := util.NewUnlockedAccount(util.HexToPrivateKey(sendTxCfg.PrivateKey))
from := ua.Address()

tx := &types.Transaction{
From: *from,
To: *util.StringToAddress(sendTxCfg.To),
Value: big.NewInt(sendTxCfg.Value),
Msg: []byte("hello"),
Fee: big.NewInt(1000),
Nonce: big.NewInt(sendTxCfg.Nonce),
}
tx.Sign(ua)

fmt.Printf("%+v\n", tx)
res, err := SendRpcRequest("TxPool.AddTx_RPC", tx, sendTxCfg.RPCAddr)

if err != nil {
log.Fatal(err)
}

fmt.Println(res)
}

func SendRpcRequest(method string, params interface{}, rpcAddr string) (interface{}, error) {
client, err := rpc.DialHTTP("tcp", rpcAddr)
if err != nil {
log.Fatal("dialing: ", err)
}

var reply types.RPCResponse

err = client.Call(method, params, &reply)
if err != nil {
log.Fatal("error: ", err)
}

return reply, nil
}
9 changes: 8 additions & 1 deletion consensus/pow/pow.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ func (c *POW) Mine(b *types.Block, mineInterrupt chan bool) *types.Block {
for {
select {
case <-mineInterrupt:
for _, tx := range b.Transactions {
err := c.TxProcessor.RollbackTx(tx)
if err != nil {
fmt.Println("Failed to rollback Tx :", "tx :", tx, "error", err)
}
}

return nil

default:
Expand All @@ -86,7 +93,7 @@ func (c *POW) Validate(b *types.Block) bool {
validTxs := []*types.Transaction{}

for _, tx := range b.Transactions {
if c.TxProcessor.IsValid(tx) {
if c.TxProcessor.IsValidImport(tx) {
err := c.TxProcessor.ProcessTx(tx)
if err == nil {
validTxs = append(validTxs, tx)
Expand Down
30 changes: 24 additions & 6 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func StartBlockchain(config *config.Config) {

shouldSleep := true

err := chain.AddBlock([]byte(fmt.Sprintf("Block %d", lastBlockNumber.Int64()+1)), chain.Txpool.Transactions, chain.MineInterrupt, config.SignerPrivateKey)
err := chain.AddBlock([]byte(fmt.Sprintf("Block %d", lastBlockNumber.Int64()+1)), chain.Txpool.GetTxs(), chain.MineInterrupt, config.SignerPrivateKey)
if err != nil {
shouldSleep = false
}
Expand All @@ -204,10 +204,7 @@ func (bc *Blockchain) ImportBlockLoop() {
err := bc.AddExternalBlock(block)
if err == nil {
bc.MineInterrupt <- true
} else {
fmt.Println("Error importing block", err)
}

}
}
}
Expand Down Expand Up @@ -250,11 +247,20 @@ func (bc *Blockchain) AddBlock(data []byte, txs []*types.Transaction, mineInterr
bc.LastBlock = minedBlock
elapsed := time.Since(start)

fmt.Println("Mined block", block.Number, block.DeriveHash().String(), "Elapsed", elapsed.Seconds(), "data", string(block.ExtraData))
for _, tx := range minedBlock.Transactions {
// nolint : errcheck
bc.Txpool.RemoveTx(tx)
}

fmt.Println("Mined block", block.Number, block.DeriveHash().String(), "Elapsed", prettySeconds(elapsed.Seconds()), "data", string(block.ExtraData), "TxCount", len(block.Transactions))

return nil
}

func prettySeconds(f float64) string {
return fmt.Sprintf("%.2fsec", f)
}

func (bc *Blockchain) RemoveLastBlock() {
if bc.LastBlock.Number.Int64() == 0 {
// Cannot remove genesis block
Expand All @@ -276,6 +282,13 @@ func (bc *Blockchain) RemoveLastBlock() {
panic(err)
}

for _, tx := range bc.LastBlock.Transactions {
err := bc.TxProcessor.RollbackTx(tx)
if err != nil {
fmt.Println("Failed to rollback Tx :", "tx :", tx, "error", err)
}
}

newLastBlock, err := bc.BlockchainDb.GetBlockByHash(lastBlockParentHash)
if err != nil {
panic(err)
Expand Down Expand Up @@ -330,8 +343,13 @@ func (bc *Blockchain) AddExternalBlock(block *types.Block) error {
panic(err)
}

for _, tx := range block.Transactions {
// nolint : errcheck
bc.Txpool.RemoveTx(tx)
}

bc.LastBlock = block
fmt.Println("Imported block", block.Number, block.DeriveHash().String())
fmt.Println("Imported block", block.Number, block.DeriveHash().String(), "TxCount", len(block.Transactions))

return nil
}
Expand Down
29 changes: 20 additions & 9 deletions dbstore/blockchainDB.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dbstore

import (
"math/big"

"github.com/0xsharma/compact-chain/types"
"github.com/0xsharma/compact-chain/util"
)
Expand All @@ -24,6 +26,22 @@ func (bdb *BlockchainDB) GetBlockByHash(hash *util.Hash) (*types.Block, error) {
return block, nil
}

func (bdb *BlockchainDB) GetBlockByNumber(number *big.Int) (*types.Block, error) {
hashBytes, err := bdb.DB.Get(PrefixKey(BlockNumberKey, number.String()))
if err != nil {
return nil, err
}

hash := util.ByteToHash(hashBytes)
block, err := bdb.GetBlockByHash(hash)

if err != nil {
return nil, err
}

return block, nil
}

func (bdb *BlockchainDB) GetLatestBlock() (*types.Block, error) {
lastBlockHashBytes, err := bdb.DB.Get(LastHashKey)
if err != nil {
Expand All @@ -39,19 +57,12 @@ func (bdb *BlockchainDB) GetBlocksInRange(start uint, end uint) ([]*types.Block,
total := end - start + 1
blocks := make([]*types.Block, total)

lastBlockHashBytes, err := bdb.DB.Get(LastHashKey)
if err != nil {
return nil, err
}

lastHash := util.ByteToHash(lastBlockHashBytes)

latestBlock, err := bdb.GetBlockByHash(lastHash)
endBlock, err := bdb.GetBlockByNumber(big.NewInt(int64(end)))
if err != nil {
return nil, err
}

blocks[total-1] = latestBlock
blocks[total-1] = endBlock

for i := int(total) - 2; i >= 0; i-- {
prevHash := blocks[i+1].ParentHash
Expand Down
Loading

0 comments on commit 8f1bc68

Please sign in to comment.