Skip to content

Commit

Permalink
DERO-HE STARGATE Testnet Release42
Browse files Browse the repository at this point in the history
  • Loading branch information
CaptainDero committed Feb 6, 2022
1 parent fb76ca9 commit 5be5777
Show file tree
Hide file tree
Showing 82 changed files with 2,500 additions and 716 deletions.
14 changes: 14 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ func Blockchain_Start(params map[string]interface{}) (*Blockchain, error) {
func (chain *Blockchain) IntegratorAddress() rpc.Address {
return chain.integrator_address
}
func (chain *Blockchain) SetIntegratorAddress(addr rpc.Address) {
chain.integrator_address = addr
}

// this function is called to read blockchain state from DB
// It is callable at any point in time
Expand Down Expand Up @@ -615,6 +618,11 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro
block_logger.Error(fmt.Errorf("Double Registration TX"), "duplicate registration", "txid", cbl.Txs[i].GetHash())
return errormsg.ErrTXDoubleSpend, false
}

tx_hash := cbl.Txs[i].GetHash()
if chain.simulator == false && tx_hash[0] != 0 && tx_hash[1] != 0 {
return fmt.Errorf("Registration TX has not solved PoW"), false
}
reg_map[string(cbl.Txs[i].MinerAddress[:])] = true
}
}
Expand Down Expand Up @@ -1112,6 +1120,12 @@ func (chain *Blockchain) Add_TX_To_Pool(tx *transaction.Transaction) error {
return fmt.Errorf("premine tx not mineable")
}
if tx.IsRegistration() { // registration tx will not go any forward

tx_hash := tx.GetHash()
if chain.simulator == false && tx_hash[0] != 0 && tx_hash[1] != 0 {
return fmt.Errorf("TX doesn't solve Pow")
}

// ggive regpool a chance to register
if ss, err := chain.Store.Balance_store.LoadSnapshot(0); err == nil {
if balance_tree, err := ss.GetTree(config.BALANCE_TREE); err == nil {
Expand Down
8 changes: 5 additions & 3 deletions blockchain/difficulty.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,19 @@ type DiffProvider interface {

func Get_Difficulty_At_Tips(source DiffProvider, tips []crypto.Hash) *big.Int {
var MinimumDifficulty *big.Int
GenesisDifficulty := new(big.Int).SetUint64(1)

if globals.IsMainnet() {
MinimumDifficulty = new(big.Int).SetUint64(config.Settings.MAINNET_MINIMUM_DIFFICULTY) // this must be controllable parameter
GenesisDifficulty = new(big.Int).SetUint64(config.Settings.MAINNET_BOOTSTRAP_DIFFICULTY)
} else {
MinimumDifficulty = new(big.Int).SetUint64(config.Settings.TESTNET_MINIMUM_DIFFICULTY) // this must be controllable parameter
GenesisDifficulty = new(big.Int).SetUint64(config.Settings.TESTNET_BOOTSTRAP_DIFFICULTY)
}
GenesisDifficulty := new(big.Int).SetUint64(1)

if chain, ok := source.(*Blockchain); ok {
if chain.simulator == true {
return GenesisDifficulty
return new(big.Int).SetUint64(1)
}
}

Expand All @@ -225,7 +227,7 @@ func Get_Difficulty_At_Tips(source DiffProvider, tips []crypto.Hash) *big.Int {

// until we have atleast 2 blocks, we cannot run the algo
if height < 3 {
return MinimumDifficulty
return GenesisDifficulty
}

tip_difficulty := source.Load_Block_Difficulty(tips[0])
Expand Down
2 changes: 2 additions & 0 deletions blockchain/hardcoded_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,14 @@ func (chain *Blockchain) install_hardcoded_contracts(cache map[crypto.Hash]*grav

if _, _, err = dvm.ParseSmartContract(source_nameservice); err != nil {
logger.Error(err, "error Parsing hard coded sc")
panic(err)
return
}

var name crypto.Hash
name[31] = 1
if err = chain.install_hardcoded_sc(cache, ss, balance_tree, sc_tree, source_nameservice, name); err != nil {
panic(err)
return
}

Expand Down
31 changes: 20 additions & 11 deletions blockchain/storefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ type storefs struct {
basedir string
}

// TODO we need to enable big support or shift to object store at some point in time
func (s *storefs) getpath(h [32]byte) string {
// if you wish to use 3 level indirection, it will cause 16 million inodes to be used, but system will be faster
//return filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
// currently we are settling on 65536 inodes
return filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]))
}

// the filename stores the following information
// hex block id (64 chars).block._ rewards (decimal) _ difficulty _ cumulative difficulty

Expand All @@ -40,7 +48,7 @@ func (s *storefs) ReadBlock(h [32]byte) ([]byte, error) {
return nil, fmt.Errorf("empty block")
}

dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)

files, err := os.ReadDir(dir)
if err != nil {
Expand All @@ -51,7 +59,7 @@ func (s *storefs) ReadBlock(h [32]byte) ([]byte, error) {
for _, file := range files {
if strings.HasPrefix(file.Name(), filename_start) {
//fmt.Printf("Reading block with filename %s\n", file.Name())
file := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]), file.Name())
file := filepath.Join(dir, file.Name())
return os.ReadFile(file)
}
}
Expand All @@ -61,7 +69,7 @@ func (s *storefs) ReadBlock(h [32]byte) ([]byte, error) {

// on windows, we see an odd behaviour where some files could not be deleted, since they may exist only in cache
func (s *storefs) DeleteBlock(h [32]byte) error {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)

files, err := os.ReadDir(dir)
if err != nil {
Expand All @@ -72,7 +80,7 @@ func (s *storefs) DeleteBlock(h [32]byte) error {
var found bool
for _, file := range files {
if strings.HasPrefix(file.Name(), filename_start) {
file := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]), file.Name())
file := filepath.Join(dir, file.Name())
err = os.Remove(file)
if err != nil {
//return err
Expand All @@ -88,7 +96,7 @@ func (s *storefs) DeleteBlock(h [32]byte) error {
}

func (s *storefs) ReadBlockDifficulty(h [32]byte) (*big.Int, error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)

files, err := os.ReadDir(dir)
if err != nil {
Expand Down Expand Up @@ -122,7 +130,7 @@ func (chain *Blockchain) ReadBlockSnapshotVersion(h [32]byte) (uint64, error) {
return chain.Store.Block_tx_store.ReadBlockSnapshotVersion(h)
}
func (s *storefs) ReadBlockSnapshotVersion(h [32]byte) (uint64, error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)

files, err := os.ReadDir(dir) // this always returns the sorted list
if err != nil {
Expand Down Expand Up @@ -167,7 +175,7 @@ func (chain *Blockchain) ReadBlockHeight(h [32]byte) (uint64, error) {
}

func (s *storefs) ReadBlockHeight(h [32]byte) (uint64, error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)

files, err := os.ReadDir(dir)
if err != nil {
Expand All @@ -194,7 +202,7 @@ func (s *storefs) ReadBlockHeight(h [32]byte) (uint64, error) {
}

func (s *storefs) WriteBlock(h [32]byte, data []byte, difficulty *big.Int, ss_version uint64, height uint64) (err error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)
file := filepath.Join(dir, fmt.Sprintf("%x.block_%s_%d_%d", h[:], difficulty.String(), ss_version, height))
if err = os.MkdirAll(dir, 0700); err != nil {
return err
Expand All @@ -203,12 +211,13 @@ func (s *storefs) WriteBlock(h [32]byte, data []byte, difficulty *big.Int, ss_ve
}

func (s *storefs) ReadTX(h [32]byte) ([]byte, error) {
file := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]), fmt.Sprintf("%x.tx", h[:]))
dir := s.getpath(h)
file := filepath.Join(dir, fmt.Sprintf("%x.tx", h[:]))
return ioutil.ReadFile(file)
}

func (s *storefs) WriteTX(h [32]byte, data []byte) (err error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)
file := filepath.Join(dir, fmt.Sprintf("%x.tx", h[:]))

if err = os.MkdirAll(dir, 0700); err != nil {
Expand All @@ -219,7 +228,7 @@ func (s *storefs) WriteTX(h [32]byte, data []byte) (err error) {
}

func (s *storefs) DeleteTX(h [32]byte) (err error) {
dir := filepath.Join(filepath.Join(s.basedir, "bltx_store"), fmt.Sprintf("%02x", h[0]), fmt.Sprintf("%02x", h[1]), fmt.Sprintf("%02x", h[2]))
dir := s.getpath(h)
file := filepath.Join(dir, fmt.Sprintf("%x.tx", h[:]))
return os.Remove(file)
}
21 changes: 14 additions & 7 deletions blockchain/transaction_execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,15 @@ func (chain *Blockchain) process_miner_transaction(bl *block.Block, genesis bool

if genesis == true { // process premine ,register genesis block, dev key
balance := crypto.ConstructElGamal(acckey.G1(), crypto.ElGamal_BASE_G) // init zero balance
balance = balance.Plus(new(big.Int).SetUint64(tx.Value << 1)) // add premine to users balance homomorphically
balance = balance.Plus(new(big.Int).SetUint64(tx.Value)) // add premine to users balance homomorphically
nb := crypto.NonceBalance{NonceHeight: 0, Balance: balance}
balance_tree.Put(tx.MinerAddress[:], nb.Serialize()) // reserialize and store

if globals.IsMainnet() {
return
}

// only testnet/simulator will have dummy accounts to test
// we must process premine list and register and give them balance,
premine_count := 0
scanner := bufio.NewScanner(strings.NewReader(premine.List))
Expand Down Expand Up @@ -119,21 +124,24 @@ func (chain *Blockchain) process_miner_transaction(bl *block.Block, genesis bool
base_reward := CalcBlockReward(uint64(height))
full_reward := base_reward + fees

//full_reward is divided into equal parts for all miner blocks + miner address
integrator_reward := full_reward * 167 / 10000

//full_reward is divided into equal parts for all miner blocks
// integrator only gets 1.67 % of block reward
// since perfect division is not possible, ( see money handling)
// any left over change is delivered to main miner who integrated the full block

share := full_reward / uint64(len(bl.MiniBlocks)) // one block integrator, this is integer division
leftover := full_reward - (share * uint64(len(bl.MiniBlocks))) // only integrator will get this
share := (full_reward - integrator_reward) / uint64(len(bl.MiniBlocks)) // one block integrator, this is integer division
leftover := full_reward - integrator_reward - (share * uint64(len(bl.MiniBlocks))) // only integrator will get this

{ // giver integrator his reward
balance_serialized, err := balance_tree.Get(tx.MinerAddress[:])
if err != nil {
panic(err)
}
nb := new(crypto.NonceBalance).Deserialize(balance_serialized)
nb.Balance = nb.Balance.Plus(new(big.Int).SetUint64(share + leftover)) // add miners reward to miners balance homomorphically
balance_tree.Put(tx.MinerAddress[:], nb.Serialize()) // reserialize and store
nb.Balance = nb.Balance.Plus(new(big.Int).SetUint64(integrator_reward + leftover)) // add miners reward to miners balance homomorphically
balance_tree.Put(tx.MinerAddress[:], nb.Serialize()) // reserialize and store
}

// all the other miniblocks will get their share
Expand Down Expand Up @@ -230,7 +238,6 @@ func (chain *Blockchain) process_transaction(changed map[crypto.Hash]*graviton.T
nb.NonceHeight = height
}
tree.Put(key_compressed, nb.Serialize()) // reserialize and store

}
}

Expand Down
68 changes: 59 additions & 9 deletions cmd/dero-wallet-cli/easymenu_post_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
package main

import "io"

import "os"
import "time"
import "fmt"
import "errors"

//import "io/ioutil"
import "strings"

//import "path/filepath"
//import "encoding/hex"
import "path/filepath"
import "encoding/json"

import "github.com/chzyer/readline"

Expand Down Expand Up @@ -64,6 +64,7 @@ func display_easymenu_post_open_command(l *readline.Instance) {
io.WriteString(w, "\t\033[1m12\033[0m\tTransfer all balance (send DERO) To Another Wallet\n")
io.WriteString(w, "\t\033[1m13\033[0m\tShow transaction history\n")
io.WriteString(w, "\t\033[1m14\033[0m\tRescan transaction history\n")
io.WriteString(w, "\t\033[1m15\033[0m\tExport all transaction history in json format\n")
}

io.WriteString(w, "\n\t\033[1m9\033[0m\tExit menu and start prompt\n")
Expand Down Expand Up @@ -127,10 +128,21 @@ func handle_easymenu_post_open_command(l *readline.Instance, line string) (proce

fmt.Fprintf(l.Stderr(), "Wallet address : "+color_green+"%s"+color_white+" is going to be registered.This is a pre-condition for using the online chain.It will take few seconds to register.\n", wallet.GetAddress())

reg_tx := wallet.GetRegistrationTX()

// at this point we must send the registration transaction
fmt.Fprintf(l.Stderr(), "Wallet address : "+color_green+"%s"+color_white+" is going to be registered.Pls wait till the account is registered.\n", wallet.GetAddress())

fmt.Fprintf(l.Stderr(), "This will take a couple of minutes.Please wait....\n")

var reg_tx *transaction.Transaction
for {

reg_tx = wallet.GetRegistrationTX()
hash := reg_tx.GetHash()

if hash[0] == 0 && hash[1] == 0 {
break
}
}
fmt.Fprintf(l.Stderr(), "Registration TXID %s\n", reg_tx.GetHash())
err := wallet.SendTransaction(reg_tx)
if err != nil {
Expand Down Expand Up @@ -243,6 +255,7 @@ func handle_easymenu_post_open_command(l *readline.Instance, line string) (proce

if a.Arguments.Has(rpc.RPC_COMMENT, rpc.DataString) { // but only it is present
logger.Info("Integrated Message", "comment", a.Arguments.Value(rpc.RPC_COMMENT, rpc.DataString))
arguments = append(arguments, rpc.Argument{rpc.RPC_COMMENT, rpc.DataString, a.Arguments.Value(rpc.RPC_COMMENT, rpc.DataString)})
}
}

Expand Down Expand Up @@ -291,10 +304,12 @@ func handle_easymenu_post_open_command(l *readline.Instance, line string) (proce
amount_to_transfer = a.Arguments.Value(rpc.RPC_VALUE_TRANSFER, rpc.DataUint64).(uint64)
} else {

amount_str := read_line_with_prompt(l, fmt.Sprintf("Enter amount to transfer in DERO (max TODO): "))
mbal, _ := wallet.Get_Balance()
amount_str := read_line_with_prompt(l, fmt.Sprintf("Enter amount to transfer in DERO (current balance %s): ", globals.FormatMoney(mbal)))

if amount_str == "" {
amount_str = ".00001"
logger.Error(nil, "Cannot transfer 0")
break // invalid amount provided, bail out
}
amount_to_transfer, err = globals.ParseAmount(amount_str)
if err != nil {
Expand All @@ -315,8 +330,15 @@ func handle_easymenu_post_open_command(l *readline.Instance, line string) (proce

// if no arguments, use space by embedding a small comment
if len(arguments) == 0 { // allow user to enter Comment
if v, err := ReadUint64(l, "Please enter payment id (or destination port number)", uint64(0)); err == nil {
arguments = append(arguments, rpc.Argument{Name: rpc.RPC_DESTINATION_PORT, DataType: rpc.DataUint64, Value: v})
} else {
logger.Error(err, fmt.Sprintf("%s could not be parsed (type %s),", "Number", rpc.DataUint64))
return
}

if v, err := ReadString(l, "Comment", ""); err == nil {
arguments = append(arguments, rpc.Argument{Name: "Comment", DataType: rpc.DataString, Value: v})
arguments = append(arguments, rpc.Argument{Name: rpc.RPC_COMMENT, DataType: rpc.DataString, Value: v})
} else {
logger.Error(fmt.Errorf("%s could not be parsed (type %s),", "Comment", rpc.DataString), "")
return
Expand Down Expand Up @@ -429,6 +451,34 @@ func handle_easymenu_post_open_command(l *readline.Instance, line string) (proce
case "14":
logger.Info("Rescanning wallet history")
rescan_bc(wallet)
case "15":
if !ValidateCurrentPassword(l, wallet) {
logger.Error(fmt.Errorf("Invalid password"), "")
break
}

if _, err := os.Stat("./history"); errors.Is(err, os.ErrNotExist) {
if err := os.Mkdir("./history", 0700); err != nil {
logger.Error(err, "Error creating directory")
break
}
}

var zeroscid crypto.Hash
account := wallet.GetAccount()
for k, v := range account.EntriesNative {
filename := filepath.Join("./history", k.String()+".json")
if k == zeroscid {
filename = filepath.Join("./history", "dero.json")
}
if data, err := json.Marshal(v); err != nil {
logger.Error(err, "Error exporting data")
} else if err = os.WriteFile(filename, data, 0600); err != nil {
logger.Error(err, "Error exporting data")
} else {
logger.Info("successfully exported history", "file", filename)
}
}

default:
processed = false // just loop
Expand Down
3 changes: 2 additions & 1 deletion cmd/dero-wallet-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Usage:
--rpc-server Run rpc server, so wallet is accessible using api
--rpc-bind=<127.0.0.1:20209> Wallet binds on this ip address and port
--rpc-login=<username:password> RPC server will grant access based on these credentials
--allow-rpc-password-change RPC server will change password if you send "Pass" header with new password
`
var menu_mode bool = true // default display menu mode
//var account_valid bool = false // if an account has been opened, do not allow to create new account in this session
Expand Down Expand Up @@ -119,7 +120,7 @@ func main() {
}

// init the lookup table one, anyone importing walletapi should init this first, this will take around 1 sec on any recent system
walletapi.Initialize_LookupTable(1, 1<<17)
walletapi.Initialize_LookupTable(1, 1<<21)

// We need to initialize readline first, so it changes stderr to ansi processor on windows
l, err := readline.NewEx(&readline.Config{
Expand Down
Loading

0 comments on commit 5be5777

Please sign in to comment.