diff --git a/shyft-cli/postgres_setup/create_tables.psql b/shyft-cli/postgres_setup/create_tables.psql index a477f1e9af..b746384bdc 100644 --- a/shyft-cli/postgres_setup/create_tables.psql +++ b/shyft-cli/postgres_setup/create_tables.psql @@ -39,6 +39,3 @@ CREATE TABLE IF NOT EXISTS accounts ( txCountAccount numeric ); -CREATE TABLE IF NOT EXISTS contracts ( - txHash text -); diff --git a/shyft-cli/postgres_setup/drop_tables.psql b/shyft-cli/postgres_setup/drop_tables.psql index 6316b8109c..41563522dd 100644 --- a/shyft-cli/postgres_setup/drop_tables.psql +++ b/shyft-cli/postgres_setup/drop_tables.psql @@ -1,4 +1,3 @@ DROP TABLE txs; DROP TABLE blocks; DROP TABLE accounts; -DROP TABLE contracts; diff --git a/shyftBlockExplorerApi/app.go b/shyftBlockExplorerApi/app.go new file mode 100644 index 0000000000..56f8b027d2 --- /dev/null +++ b/shyftBlockExplorerApi/app.go @@ -0,0 +1,18 @@ +package main + +//@NOTE SHYFT main func for api, sets up router and spins up a server +//to run server 'go run shyftBlockExplorerApi/*.go' +import ( + "log" + "net/http" + + "github.com/gorilla/handlers" +) + +func main() { + + router := NewRouter() + port := "8080" + log.Printf("Listening on port " + " " + port) + log.Fatal(http.ListenAndServe(":"+port, handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(router))) +} diff --git a/blockExplorerApi/handler.go b/shyftBlockExplorerApi/handler.go similarity index 100% rename from blockExplorerApi/handler.go rename to shyftBlockExplorerApi/handler.go diff --git a/blockExplorerApi/logger.go b/shyftBlockExplorerApi/logger.go similarity index 100% rename from blockExplorerApi/logger.go rename to shyftBlockExplorerApi/logger.go diff --git a/blockExplorerApi/router.go b/shyftBlockExplorerApi/router.go similarity index 100% rename from blockExplorerApi/router.go rename to shyftBlockExplorerApi/router.go diff --git a/blockExplorerApi/routes.go b/shyftBlockExplorerApi/routes.go similarity index 100% rename from blockExplorerApi/routes.go rename to shyftBlockExplorerApi/routes.go diff --git a/shyftDb/db.go b/shyftDb/db.go index 34fd2bebbc..f95871fd28 100644 --- a/shyftDb/db.go +++ b/shyftDb/db.go @@ -3,12 +3,18 @@ package shyftdb import ( "fmt" "database/sql" + "os" ) var blockExplorerDb *sql.DB func InitDB() (*sql.DB, error){ - connStr := "user=postgres dbname=shyftdb sslmode=disable" + var connStr string + if "test" == os.Getenv("SHYFT_ENV") { + connStr = "user=postgres dbname=shyftdbtest sslmode=disable" + } else { + connStr = "user=postgres dbname=shyftdb sslmode=disable" + } db, err := sql.Open("postgres", connStr) if err != nil { fmt.Println("ERROR OPENING DB, NOT INITIALIZING") diff --git a/shyftDb/postgres_setup_test/create_shyftdb_test.psql b/shyftDb/postgres_setup_test/create_shyftdb_test.psql new file mode 100644 index 0000000000..96a3d28af5 --- /dev/null +++ b/shyftDb/postgres_setup_test/create_shyftdb_test.psql @@ -0,0 +1 @@ +CREATE DATABASE shyftdbTest diff --git a/shyftDb/postgres_setup_test/create_tables_test.psql b/shyftDb/postgres_setup_test/create_tables_test.psql new file mode 100644 index 0000000000..2cd9bc5176 --- /dev/null +++ b/shyftDb/postgres_setup_test/create_tables_test.psql @@ -0,0 +1,40 @@ +CREATE TABLE IF NOT EXISTS blocks ( + hash text primary key, + coinbase text, + gasUsed numeric, + gasLimit numeric, + txCount numeric, + uncleCount numeric, + age timestamp, + parentHash text, + uncleHash text, + difficulty bigint, + size text, + nonce numeric, + rewards numeric, + number bigint +); + +CREATE TABLE IF NOT EXISTS txs ( + txHash text, + to_addr text, + from_addr text, + blockhash text references blocks(hash), + blocknumber text, + amount numeric, + gasprice numeric, + gas numeric, + gasLimit numeric, + txFee numeric, + nonce numeric, + txStatus text, + isContract bool, + age timestamp, + data bytea +); + +CREATE TABLE IF NOT EXISTS accounts ( + addr text primary key unique, + balance numeric, + txCountAccount numeric +); \ No newline at end of file diff --git a/shyftDb/postgres_setup_test/drop_tables_test.psql b/shyftDb/postgres_setup_test/drop_tables_test.psql new file mode 100644 index 0000000000..80625a022b --- /dev/null +++ b/shyftDb/postgres_setup_test/drop_tables_test.psql @@ -0,0 +1,3 @@ +DROP TABLE txs; +DROP TABLE blocks; +DROP TABLE accounts; \ No newline at end of file diff --git a/shyftDb/postgres_setup_test/drop_tables_test.sh b/shyftDb/postgres_setup_test/drop_tables_test.sh new file mode 100644 index 0000000000..c46031aee9 --- /dev/null +++ b/shyftDb/postgres_setup_test/drop_tables_test.sh @@ -0,0 +1 @@ +psql -U postgres -d shyftdbtest -f drop_tables_test.psql \ No newline at end of file diff --git a/shyftDb/postgres_setup_test/initTestdb.sh b/shyftDb/postgres_setup_test/initTestdb.sh new file mode 100644 index 0000000000..f41fc809c6 --- /dev/null +++ b/shyftDb/postgres_setup_test/initTestdb.sh @@ -0,0 +1 @@ +psql -U postgres -f create_shyftdb_test.psql \ No newline at end of file diff --git a/shyftDb/postgres_setup_test/init_tables_test.sh b/shyftDb/postgres_setup_test/init_tables_test.sh new file mode 100644 index 0000000000..aad56f6307 --- /dev/null +++ b/shyftDb/postgres_setup_test/init_tables_test.sh @@ -0,0 +1 @@ +psql -U postgres -d shyftdbtest -f create_tables_test.psql \ No newline at end of file diff --git a/shyftDb/postgres_test.go b/shyftDb/postgres_test.go new file mode 100644 index 0000000000..7a652301a5 --- /dev/null +++ b/shyftDb/postgres_test.go @@ -0,0 +1,42 @@ +package shyftdb + +import ( + "database/sql" + "fmt" +) + +func InitTestDB() *sql.DB { + connStr := "user=postgres dbname=shyftdbtest sslmode=disable" + blockExplorerDbTest, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + } + + return blockExplorerDbTest +} + +func ClearTables() { + connStr := "user=postgres dbname=shyftdbtest sslmode=disable" + blockExplorerDbTest, err := sql.Open("postgres", connStr) + if err != nil { + fmt.Println(err) + } + + sqlStatementTx:= `DELETE FROM txs` + _, err = blockExplorerDbTest.Exec(sqlStatementTx) + if err != nil { + panic(err) + } + + sqlStatementAcc:= `DELETE FROM accounts` + _, err = blockExplorerDbTest.Exec(sqlStatementAcc) + if err != nil { + panic(err) + } + + sqlStatement := `DELETE FROM blocks` + _, err = blockExplorerDbTest.Exec(sqlStatement) + if err != nil { + panic(err) + } +} \ No newline at end of file diff --git a/shyftDb/shyft_database_util.go b/shyftDb/shyft_database_util.go index 93d012a4bb..658abe6e07 100644 --- a/shyftDb/shyft_database_util.go +++ b/shyftDb/shyft_database_util.go @@ -20,16 +20,16 @@ type SBlock struct { Hash string Coinbase string Number string - GasUsed string - GasLimit string - TxCount string - UncleCount string + GasUsed uint64 + GasLimit uint64 + TxCount int + UncleCount int Age string ParentHash string UncleHash string Difficulty string Size string - Nonce string + Nonce uint64 Rewards string } @@ -80,7 +80,7 @@ type ShyftTxEntryPretty struct { Amount string GasPrice uint64 Gas uint64 - GasLimit string + GasLimit uint64 Cost uint64 Nonce uint64 Status string @@ -144,7 +144,6 @@ func WriteBlock(block *types.Block, receipts []*types.Receipt) error { } if block.Transactions()[0].To() == nil { writeContractBalance(sqldb, tx) - writeContractsTxHashReferences(sqldb, tx) } } } @@ -223,22 +222,15 @@ func writeTransactions(sqldb *sql.DB, tx *types.Transaction, blockHash common.Ha return nil } -func writeContractsTxHashReferences(sqldb *sql.DB, tx *types.Transaction) error { - txHash := tx.Hash().Hex() - - sqlStatement := `INSERT INTO contracts(txHash) VALUES(($1)) RETURNING txHash` - insertErr := sqldb.QueryRow(sqlStatement, txHash).Scan(&txHash) - if insertErr != nil { - panic(insertErr) - } - return nil -} - func writeContractBalance(sqldb *sql.DB, tx *types.Transaction) error { - sendAndReceiveData,balanceSen,accountNonceSen := writeContractBalanceHelper(sqldb, tx) + sendAndReceiveData := SendAndReceive{ + From: tx.From().Hex(), + Amount: tx.Value().String(), + } + fromAddr := sendAndReceiveData.From amount := sendAndReceiveData.Amount - balanceSender := balanceSen + accountNonceSen := tx.Nonce() var response string sqlExistsStatement := `SELECT balance from accounts WHERE addr = ($1)` @@ -250,9 +242,14 @@ func writeContractBalance(sqldb *sql.DB, tx *types.Transaction) error { if insertErr != nil { panic(insertErr) } - case err != nil: - log.Fatal(err) default: + getAccountBalanceSender:= GetAccount(sqldb, fromAddr) + var senderBalance SendAndReceive + if err := json.Unmarshal([]byte(getAccountBalanceSender), &senderBalance); err != nil { + log.Fatal(err) + } + + balanceSender := senderBalance.Balance var newBalanceSender big.Int var newAccountNonceSender big.Int var nonceIncrement = big.NewInt(1) @@ -264,16 +261,12 @@ func writeContractBalance(sqldb *sql.DB, tx *types.Transaction) error { log.Println("error scanning value:", error) } - accountS := new(big.Int) - _, errors := fmt.Sscan(accountNonceSen, accountS) - if errors != nil { - log.Println("error scanning value:", error) - } + senderAccountNonce := new(big.Int).SetUint64(accountNonceSen) newBalanceSender.Sub(s, tx.Value()) - newAccountNonceSender.Add(accountS, nonceIncrement) + newAccountNonceSender.Add(senderAccountNonce, nonceIncrement) - _, err = sqldb.Exec(updateSQLStatement, fromAddr, newBalanceSender.String(), newAccountNonceSender.String()) + _, err := sqldb.Exec(updateSQLStatement, fromAddr, newBalanceSender.String(), newAccountNonceSender.String()) if err != nil { panic(err) } @@ -281,25 +274,6 @@ func writeContractBalance(sqldb *sql.DB, tx *types.Transaction) error { return nil } -func writeContractBalanceHelper(sqldb *sql.DB, tx *types.Transaction) (SendAndReceive, string, string) { - sendAndReceiveData := SendAndReceive{ - From: tx.From().Hex(), - Amount: tx.Value().String(), - } - - fromAddr := sendAndReceiveData.From - getAccountBalanceSender:= GetAccount(sqldb, fromAddr) - - var senderBalance SendAndReceive - if err := json.Unmarshal([]byte(getAccountBalanceSender), &senderBalance); err != nil { - log.Fatal(err) - } - balanceSender := senderBalance.Balance - accountNonceSender := senderBalance.TxCountAccount - - return sendAndReceiveData, balanceSender, accountNonceSender -} - //writeFromBalance writes senders balance to accounts db func writeFromBalance(sqldb *sql.DB, tx *types.Transaction) error { sendAndReceiveData, balanceRec, balanceSen, accountNonceRec, accountNonceSen := writeBalanceHelper(sqldb, tx) @@ -312,14 +286,12 @@ func writeFromBalance(sqldb *sql.DB, tx *types.Transaction) error { var response string sqlExistsStatement := `SELECT balance from accounts WHERE addr = ($1)` err := sqldb.QueryRow(sqlExistsStatement, toAddr).Scan(&response) + switch { case err == sql.ErrNoRows: - i, err := strconv.Atoi(accountNonceRec) - if err != nil { - fmt.Println(err) - } + txCountAccount := strconv.FormatUint(tx.Nonce(), 10) sqlStatement := `INSERT INTO accounts(addr, balance, txCountAccount) VALUES(($1), ($2), ($3)) RETURNING addr` - insertErr := sqldb.QueryRow(sqlStatement, toAddr, amount, i).Scan(&toAddr) + insertErr := sqldb.QueryRow(sqlStatement, toAddr, amount, txCountAccount).Scan(&toAddr) if insertErr != nil { panic(insertErr) } @@ -385,7 +357,6 @@ func writeBalanceHelper(sqldb *sql.DB, tx *types.Transaction) (SendAndReceive, s toAddr := sendAndReceiveData.To fromAddr := sendAndReceiveData.From - getAccountBalanceReceiver := GetAccount(sqldb, toAddr) getAccountBalanceSender:= GetAccount(sqldb, fromAddr) @@ -401,7 +372,6 @@ func writeBalanceHelper(sqldb *sql.DB, tx *types.Transaction) (SendAndReceive, s balanceReceiver := receiverBalance.Balance balanceSender := senderBalance.Balance - accountNonceReceiver := receiverBalance.TxCountAccount accountNonceSender := senderBalance.TxCountAccount @@ -503,6 +473,10 @@ func storeReward(sqldb *sql.DB, address string, reward *big.Int) { // Getters ////////// //GetAllBlocks returns []SBlock blocks for API + +//Look into postgres functions array_to_json(array_agg(lap)) +//Example select array_to_json(array_agg(lap)) +//from ( select * from blocks)lap; func GetAllBlocks(sqldb *sql.DB) string { var arr blockRes var blockArr string @@ -516,16 +490,16 @@ func GetAllBlocks(sqldb *sql.DB) string { for rows.Next() { var hash string var coinbase string - var gasUsed string - var gasLimit string - var txCount string - var uncleCount string + var gasUsed uint64 + var gasLimit uint64 + var txCount int + var uncleCount int var age string var parentHash string var uncleHash string var difficulty string var size string - var nonce string + var nonce uint64 var rewards string var num string @@ -576,16 +550,16 @@ func GetBlock(sqldb *sql.DB, blockNumber string) string { row := sqldb.QueryRow(sqlStatement, blockNumber) var hash string var coinbase string - var gasUsed string - var gasLimit string - var txCount string - var uncleCount string + var gasUsed uint64 + var gasLimit uint64 + var txCount int + var uncleCount int var age string var parentHash string var uncleHash string var difficulty string var size string - var nonce string + var nonce uint64 var rewards string var num string row.Scan( @@ -629,16 +603,16 @@ func GetRecentBlock(sqldb *sql.DB) string { row := sqldb.QueryRow(sqlStatement) var hash string var coinbase string - var gasUsed string - var gasLimit string - var txCount string - var uncleCount string + var gasUsed uint64 + var gasLimit uint64 + var txCount int + var uncleCount int var age string var parentHash string var uncleHash string var difficulty string var size string - var nonce string + var nonce uint64 var rewards string var num string row.Scan( @@ -695,7 +669,7 @@ func GetAllTransactionsFromBlock(sqldb *sql.DB, blockNumber string) string { var amount string var gasprice uint64 var gas uint64 - var gasLimit string + var gasLimit uint64 var txfee uint64 var nonce uint64 var status string @@ -758,16 +732,16 @@ func GetAllBlocksMinedByAddress(sqldb *sql.DB, coinbase string) string { for rows.Next() { var hash string var coinbase string - var gasUsed string - var gasLimit string - var txCount string - var uncleCount string + var gasUsed uint64 + var gasLimit uint64 + var txCount int + var uncleCount int var age string var parentHash string var uncleHash string var difficulty string var size string - var nonce string + var nonce uint64 var rewards string var num string @@ -830,7 +804,7 @@ func GetAllTransactions(sqldb *sql.DB) string { var amount string var gasprice uint64 var gas uint64 - var gasLimit string + var gasLimit uint64 var txfee uint64 var nonce uint64 var status string @@ -892,7 +866,7 @@ func GetTransaction(sqldb *sql.DB, txHash string) string { var amount string var gasprice uint64 var gas uint64 - var gasLimit string + var gasLimit uint64 var txfee uint64 var nonce uint64 var status string @@ -1017,7 +991,7 @@ func GetAccountTxs(sqldb *sql.DB, address string) string { var amount string var gasprice uint64 var gas uint64 - var gasLimit string + var gasLimit uint64 var txfee uint64 var nonce uint64 var status string diff --git a/shyftDb/shyft_database_util_test.go b/shyftDb/shyft_database_util_test.go new file mode 100644 index 0000000000..5e76048fc1 --- /dev/null +++ b/shyftDb/shyft_database_util_test.go @@ -0,0 +1,458 @@ +package shyftdb + +import ( + "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "math/big" + //"time" + "encoding/json" + "github.com/ethereum/go-ethereum/crypto" + "strconv" +) + +func TestBlockToReturnBlock(t *testing.T) { + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer := types.NewEIP155Signer(big.NewInt(2147483647)) + + //Nonce, To Address,Value, GasLimit, Gasprice, data + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + mytx,_ := types.SignTx(tx1, signer, key) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + mytx2,_ := types.SignTx(tx2, signer, key) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + mytx3,_ := types.SignTx(tx3, signer, key) + txs := []*types.Transaction{mytx, mytx2, mytx3} + + receipt := &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 1, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: common.BytesToHash([]byte{0x11, 0x11}), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + + receipts := []*types.Receipt{receipt} + block := types.NewBlock(&types.Header{Number: big.NewInt(315)}, txs, nil, receipts) + + // Write and verify the block in the database + if err := WriteBlock(block, receipts); err != nil { + t.Fatalf("Failed to write block into database: %v", err) + } + + sqldb, err := DBConnection() + if (err != nil) { + panic(err) + } + + entry := GetBlock(sqldb, block.Number().String()) + byt := []byte(entry) + var data SBlock + json.Unmarshal(byt, &data) + + //TODO Difficulty, rewards, age + if block.Hash().String() != data.Hash { + t.Fatalf("Block Hash [%v]: Block hash not found", block.Hash().String()) + } + if block.Coinbase().String() != data.Coinbase { + t.Fatalf("Block coinbase [%v]: Block coinbase not found", block.Coinbase().String()) + } + if block.Number().String() != data.Number { + t.Fatalf("Block number [%v]: Block number not found", block.Number().String()) + } + if block.GasUsed() != data.GasUsed { + t.Fatalf("Gas Used [%v]: Gas used not found", block.GasUsed()) + } + if block.GasLimit() != data.GasLimit { + t.Fatalf("Gas Limit [%v]: Gas limit not found", block.GasLimit()) + } + if block.Transactions().Len() != data.TxCount { + t.Fatalf("Tx Count [%v]: Tx Count not found", block.Transactions().Len()) + } + if len(block.Uncles()) != data.UncleCount { + t.Fatalf("Uncle count [%v]: Uncle count not found", len(block.Uncles())) + } + if block.ParentHash().String() != data.ParentHash { + t.Fatalf("Parent hash [%v]: Parent hash not found", block.ParentHash().String()) + } + if block.UncleHash().String() != data.UncleHash { + t.Fatalf("Uncle hash [%v]: Uncle hash not found", block.UncleHash().String()) + } + if block.Size().String() != data.Size { + t.Fatalf("Size [%v]: Size not found", block.Size().String()) + } + if block.Nonce() != data.Nonce { + t.Fatalf("Block nonce [%v]: Block nonce not found", block.Nonce()) + } + + if getAllBlocks := GetAllBlocks(sqldb); len(getAllBlocks) == 0 { + t.Fatalf("GetAllBlocks [%v]: GetAllBlocks did not return correctly", getAllBlocks) + } + + if getAllBlocksMinedByAddress := GetAllBlocksMinedByAddress(sqldb, block.Coinbase().String()); len(getAllBlocksMinedByAddress) == 0 { + t.Fatalf("GetAllBlocksMinedByAddress [%v]: GetAllBlocksMinedByAddress did not return correctly", getAllBlocksMinedByAddress) + } + + ClearTables() +} + +func TestGetRecentBlock(t *testing.T) { + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer := types.NewEIP155Signer(big.NewInt(2147483647)) + + //Nonce, To Address,Value, GasLimit, Gasprice, data + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + mytx,_ := types.SignTx(tx1, signer, key) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + mytx2,_ := types.SignTx(tx2, signer, key) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + mytx3,_ := types.SignTx(tx3, signer, key) + txs := []*types.Transaction{mytx, mytx2} + txs1 := []*types.Transaction{mytx3} + + receipt1 := &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 1, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: common.BytesToHash([]byte{0x11, 0x11}), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + + receipts := []*types.Receipt{receipt1} + block := types.NewBlock(&types.Header{Number: big.NewInt(322)}, txs, nil, receipts) + block2 := types.NewBlock(&types.Header{Number: big.NewInt(320)}, txs1, nil, receipts) + blocks := []*types.Block{block, block2} + + for _, bc := range blocks { + // Write and verify the block in the database + if err := WriteBlock(bc, receipts); err != nil { + t.Fatalf("Failed to write block into database: %v", err) + } + } + + sqldb, err := DBConnection() + if (err != nil) { + panic(err) + } + + response := GetRecentBlock(sqldb) + byteRes := []byte(response) + var recentBlock SBlock + json.Unmarshal(byteRes, &recentBlock) + + if block.Hash().String() != recentBlock.Hash { + t.Fatalf("Block Hash [%v]: Block hash not found", block.Hash().String()) + } + if block.Coinbase().String() != recentBlock.Coinbase { + t.Fatalf("Block coinbase [%v]: Block coinbase not found", block.Coinbase().String()) + } + if block.Number().String() != recentBlock.Number { + t.Fatalf("Block number [%v]: Block number not found", block.Number().String()) + } + if block.GasUsed() != recentBlock.GasUsed { + t.Fatalf("Gas Used [%v]: Gas used not found", block.GasUsed()) + } + if block.GasLimit() != recentBlock.GasLimit { + t.Fatalf("Gas Limit [%v]: Gas limit not found", block.GasLimit()) + } + if block.Transactions().Len() != recentBlock.TxCount { + t.Fatalf("Tx Count [%v]: Tx Count not found", block.Transactions().Len()) + } + if len(block.Uncles()) != recentBlock.UncleCount { + t.Fatalf("Uncle count [%v]: Uncle count not found", len(block.Uncles())) + } + if block.ParentHash().String() != recentBlock.ParentHash { + t.Fatalf("Parent hash [%v]: Parent hash not found", block.ParentHash().String()) + } + if block.UncleHash().String() != recentBlock.UncleHash { + t.Fatalf("Uncle hash [%v]: Uncle hash not found", block.UncleHash().String()) + } + if block.Size().String() != recentBlock.Size { + t.Fatalf("Size [%v]: Size not found", block.Size().String()) + } + if block.Nonce() != recentBlock.Nonce { + t.Fatalf("Block nonce [%v]: Block nonce not found", block.Nonce()) + } + + if allTxsFromBlock:= GetAllTransactionsFromBlock(sqldb, block2.Number().String()); len(allTxsFromBlock) == 0 { + t.Fatalf("GetAllTransactionsFromBlock [%v]: GetAllTransactionsFromBlock did not return correctly", allTxsFromBlock) + } + ClearTables() +} + +func TestContractCreationTx(t *testing.T) { + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer := types.NewEIP155Signer(big.NewInt(2147483647)) + + //Nonce,Value, GasLimit, Gasprice, data + contractCreation := types.NewContractCreation(1, big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + mytx,_ := types.SignTx(contractCreation, signer, key) + txs := []*types.Transaction{mytx} + + receipt2 := &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 1, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: common.BytesToHash([]byte{0x11, 0x11}), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + + receipts := []*types.Receipt{receipt2} + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, receipts) + + if err := WriteBlock(block, receipts); err != nil { + t.Fatalf("Failed to write block into database: %v", err) + } + + var contractAddressFromReciept string + for _, receipt := range receipts { + contractAddressFromReciept = (*types.ReceiptForStorage)(receipt).ContractAddress.String() + } + + sqldb, err := DBConnection() + if (err != nil) { + panic(err) + } + + for _, tx := range txs { + txn := GetTransaction(sqldb, tx.Hash().String()) + byt := []byte(txn) + var data ShyftTxEntryPretty + json.Unmarshal(byt, &data) + + if tx.Hash().String() != data.TxHash { + t.Fatalf("txHash [%v]: tx Hash not found", tx.Hash().String()) + } + if contractAddressFromReciept != data.To { + t.Fatalf("Contract Addr [%v]: Contract addr not found", contractAddressFromReciept) + } + if tx.From().String() != data.From { + t.Fatalf("From Addr [%v]: From addr not found", tx.From().String()) + } + if tx.Nonce() != data.Nonce { + t.Fatalf("Nonce [%v]: Nonce not found", tx.Nonce()) + } + if tx.Gas() != data.Gas { + t.Fatalf("Gas [%v]: Gas not found", tx.Gas()) + } + if tx.GasPrice().Uint64() != data.GasPrice { + t.Fatalf("Gas Price [%v]: Gas price not found", tx.GasPrice().String()) + } + if block.GasLimit() != data.GasLimit { + t.Fatalf("Gas Limit [%v]: Gas limit not found", block.GasLimit()) + } + if block.Hash().String() != data.BlockHash { + t.Fatalf("Block Hash [%v]: Block hash not found", block.Hash().String()) + } + if block.Number().String() != data.BlockNumber { + t.Fatalf("Block Number [%v]: Block number not found", block.Number().String()) + } + if tx.Value().String() != data.Amount { + t.Fatalf("Amount [%v]: Amount not found", tx.Value().String()) + } + if tx.Cost().Uint64() != data.Cost { + t.Fatalf("Cost [%v]: Cost not found", tx.Cost().String()) + } + var status string + if receipt2.Status == 1 { + status = "SUCCESS" + } + if receipt2.Status == 0 { + status = "FAIL" + } + if status != data.Status { + t.Fatalf("Receipt status [%v]: Receipt status not found", status) + } + var isContract bool + if tx.To() != nil { + isContract = false + } else { + isContract = true + } + if isContract != data.IsContract { + t.Fatalf("isContract [%v]: isContract bool is incorrect", isContract) + } + } + ClearTables() +} + +func TestTransactionsToReturnTransactions(t *testing.T) { + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer := types.NewEIP155Signer(big.NewInt(2147483647)) + + //Nonce, To Address,Value, GasLimit, Gasprice, data + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + mytx,_ := types.SignTx(tx1, signer, key) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + mytx2,_ := types.SignTx(tx2, signer, key) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + mytx3,_ := types.SignTx(tx3, signer, key) + txs := []*types.Transaction{mytx, mytx2, mytx3} + + receipt1 := &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 1, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: common.BytesToHash([]byte{0x11, 0x11}), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + + receipts := []*types.Receipt{receipt1} + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, receipts) + + if err := WriteBlock(block, receipts); err != nil { + t.Fatalf("Failed to write block into database: %v", err) + } + sqldb, err := DBConnection() + if (err != nil) { + panic(err) + } + + for _, tx := range txs { + txn := GetTransaction(sqldb, tx.Hash().String()) + byt := []byte(txn) + var data ShyftTxEntryPretty + json.Unmarshal(byt, &data) + + //TODO age, data + if tx.Hash().String() != data.TxHash { + t.Fatalf("txHash [%v]: tx Hash not found", tx.Hash().String()) + } + if tx.From().String() != data.From { + t.Fatalf("From Addr [%v]: From addr not found", tx.From().String()) + } + if tx.To().String() != data.To { + t.Fatalf("To Addr [%v]: To addr not found", tx.To().String()) + } + if tx.Nonce() != data.Nonce { + t.Fatalf("Nonce [%v]: Nonce not found", tx.Nonce()) + } + if tx.Gas() != data.Gas { + t.Fatalf("Gas [%v]: Gas not found", tx.Gas()) + } + if tx.GasPrice().Uint64() != data.GasPrice { + t.Fatalf("Gas Price [%v]: Gas price not found", tx.GasPrice().String()) + } + if block.GasLimit() != data.GasLimit { + t.Fatalf("Gas Limit [%v]: Gas limit not found", block.GasLimit()) + } + if block.Hash().String() != data.BlockHash { + t.Fatalf("Block Hash [%v]: Block hash not found", block.Hash().String()) + } + if block.Number().String() != data.BlockNumber { + t.Fatalf("Block Number [%v]: Block number not found", block.Number().String()) + } + if tx.Value().String() != data.Amount { + t.Fatalf("Amount [%v]: Amount not found", tx.Value().String()) + } + if tx.Cost().Uint64() != data.Cost { + t.Fatalf("Cost [%v]: Cost not found", tx.Cost().String()) + } + var status string + if receipt1.Status == 1 { + status = "SUCCESS" + } + if receipt1.Status == 0 { + status = "FAIL" + } + if status != data.Status { + t.Fatalf("Receipt status [%v]: Receipt status not found", status) + } + var isContract bool + if tx.To() != nil { + isContract = false + } else { + isContract = true + } + if isContract != data.IsContract { + t.Fatalf("isContract [%v]: isContract bool is incorrect", isContract) + } + } + + if getAllTx := GetAllTransactions(sqldb); len(getAllTx) == 0 { + t.Fatalf("GetAllTransactions [%v]: GetAllTransactions did not return correctly", getAllTx) + } + ClearTables() +} + +func TestAccountsToReturnAccounts(t *testing.T) { + key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + signer := types.NewEIP155Signer(big.NewInt(2147483647)) + + //Nonce, To Address,Value, GasLimit, Gasprice, data + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + mytx,_ := types.SignTx(tx1, signer, key) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + mytx2,_ := types.SignTx(tx2, signer, key) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + mytx3,_ := types.SignTx(tx3, signer, key) + txs := []*types.Transaction{mytx, mytx2, mytx3} + + receipt1 := &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 1, + Logs: []*types.Log{ + {Address: common.BytesToAddress([]byte{0x11})}, + {Address: common.BytesToAddress([]byte{0x01, 0x11})}, + }, + TxHash: common.BytesToHash([]byte{0x11, 0x11}), + ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), + GasUsed: 111111, + } + + receipts := []*types.Receipt{receipt1} + block := types.NewBlock(&types.Header{Number: big.NewInt(315)}, txs, nil, receipts) + if err := WriteBlock(block, receipts); err != nil { + t.Fatalf("Failed to write block into database: %v", err) + } + + sqldb, err := DBConnection() + if (err != nil) { + panic(err) + } + + + for _, tx := range txs { + accountAddrTo := GetAccount(sqldb, tx.To().String()) + byts := []byte(accountAddrTo) + var accountDataTo SAccounts + json.Unmarshal(byts, &accountDataTo) + + if tx.To().String() != accountDataTo.Addr { + t.Fatalf("To address [%v]: To address not found", accountDataTo.Addr) + } + if tx.Value().String() != accountDataTo.Balance { + t.Fatalf("To address balance [%v]: To address balance not found", accountDataTo.Balance) + } + if strconv.FormatUint(tx.Nonce(), 10) != accountDataTo.TxCountAccount { + t.Fatalf("To account nonce [%v]: To account nonce not found", accountDataTo.TxCountAccount) + } + if getAllAccountTxs := GetAccountTxs(sqldb, tx.To().String()); len(getAllAccountTxs) == 0 { + t.Fatalf("GetAccountTxs [%v]: GetAccountTxs did not return correctly", getAllAccountTxs) + } + } + + if getAllAccounts := GetAllAccounts(sqldb); len(getAllAccounts) == 0 { + t.Fatalf("GetAllAccounts [%v]: GetAllAccounts did not return correctly", getAllAccounts) + } + ClearTables() +} + + +