Esempio n. 1
0
// Return the instance, properly unmarshaled, given the entry in the database, which is
// the hash for the Instance (vv) followed by the source from which to unmarshal (v)
func (d *BoltDB) GetInstance(v []byte) fct.IBlock {

	var vv [32]byte
	copy(vv[:], v[:32])
	v = v[32:]

	var instance fct.IBlock = d.instances[vv]
	if instance == nil {
		vp := fct.NewHash(vv[:])
		fct.Prtln("Object hash: ", vp)
		panic("This should not happen.  Object stored in the database has no IBlock instance")
	}

	r := instance.GetNewInstance()
	if r == nil {
		panic("An IBlock has failed to implement GetNewInstance()")
	}

	datalen, v := binary.BigEndian.Uint32(v[0:4]), v[4:]
	if len(v) != int(datalen) {
		fct.Prtln("Lengths don't match.  Expected ", datalen, " and got ", len(v))
		panic("Data not returned properly")
	}
	err := r.UnmarshalBinary(v)
	if err != nil {
		panic("This should not happen.  IBlock failed to unmarshal.")
	}

	return r
}
Esempio n. 2
0
func Test_SignTransaction_swcallet(test *testing.T) {
	w := new(SCWallet) // make me a wallet
	w.Init()
	w.NewSeed([]byte("lkdfsgjlagkjlasd"))
	h0, err := w.GenerateFctAddress([]byte("test 0"), 1, 1)
	if err != nil {
		test.Fail()
	}
	h1, err := w.GenerateFctAddress([]byte("test 1"), 1, 1)
	if err != nil {
		test.Fail()
	}
	h2, err := w.GenerateFctAddress([]byte("test 2"), 1, 1)
	if err != nil {
		test.Fail()
	}
	h3, err := w.GenerateFctAddress([]byte("test 3"), 1, 1)
	if err != nil {
		test.Fail()
	}
	h4, err := w.GenerateFctAddress([]byte("test 4"), 1, 1)
	if err != nil {
		test.Fail()
	}

	t := w.CreateTransaction(0)

	w.AddInput(t, h1, 1000000)
	w.AddInput(t, h2, 1000000)
	w.AddOutput(t, h3, 1000000)
	w.AddOutput(t, h4, 1000000)
	w.AddInput(t, h0, 0)
	fee, err := t.CalculateFee(1000)
	w.UpdateInput(t, 2, h0, fee)
	signed, err := w.SignInputs(t)

	if !signed || err != nil {
		factoid.Prtln("Signed Fail: ", signed, err)
		test.Fail()
	}

	txt, err := t.CustomMarshalText()
	fct.Prtln(string(txt), "\n ", fee)

	err = w.ValidateSignatures(t)
	if err != nil {
		factoid.Prtln(err)
		test.Fail()
	}

}
Esempio n. 3
0
func (fs *Test_state) Init(test *testing.T) {
	fs.stats.errors = make(map[string]int, 100)
	fs.stats.full = make(map[string]string, 100)

	fs.inputAddresses = make([]fct.IAddress, 0, 10)
	fs.outputAddresses = make([]fct.IAddress, 0, 10)
	fs.ecoutputAddresses = make([]fct.IAddress, 0, 10)
	fs.twallet = new(wallet.SCWallet) // Wallet for our tests
	fs.twallet.Init()

	for i := 0; i < 10; i++ {
		addr, err := fs.twallet.GenerateFctAddress([]byte("testin_"+cv.Itoa(i)), 1, 1)
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.inputAddresses = append(fs.inputAddresses, addr)
		fs.outputAddresses = append(fs.outputAddresses, addr)
	}

	fs.twallet.NewSeed([]byte("Test State and Balances"))

	for i := 0; i < 500; i++ {
		addr, err := fs.twallet.GenerateFctAddress([]byte("testout_"+cv.Itoa(i)), 1, 1)
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.outputAddresses = append(fs.outputAddresses, addr)
	}
	for i := 0; i < 1000; i++ {
		addr, err := fs.twallet.GenerateECAddress([]byte("testecout_" + cv.Itoa(i)))
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.ecoutputAddresses = append(fs.ecoutputAddresses, addr)
	}
	fs.stats.begin()
}
Esempio n. 4
0
// sets up teststate.go
func Test_setup_FactoidState(test *testing.T) {
	// Create a Test State
	fs = new(Test_state)
	fs.stats.errors = make(map[string]int, 100)
	fs.stats.full = make(map[string]string, 100)

	fs.inputAddresses = make([]fct.IAddress, 0, 10)
	fs.outputAddresses = make([]fct.IAddress, 0, 10)
	fs.ecoutputAddresses = make([]fct.IAddress, 0, 10)
	fs.twallet = new(wallet.SCWallet) // Wallet for our tests
	fs.twallet.Init()

	for i := 0; i < 10; i++ {
		addr, err := fs.twallet.GenerateFctAddress([]byte("testin_"+cv.Itoa(i)), 1, 1)
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.inputAddresses = append(fs.inputAddresses, addr)
		fs.outputAddresses = append(fs.outputAddresses, addr)
	}
	for i := 0; i < 500; i++ {
		addr, err := fs.twallet.GenerateFctAddress([]byte("testout_"+cv.Itoa(i)), 1, 1)
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.outputAddresses = append(fs.outputAddresses, addr)
	}
	for i := 0; i < 50; i++ {
		addr, err := fs.twallet.GenerateECAddress([]byte("testecout_" + cv.Itoa(i)))
		if err != nil {
			fct.Prtln(err)
			test.Fail()
		}
		fs.ecoutputAddresses = append(fs.outputAddresses, addr)
	}
}
Esempio n. 5
0
func Test_CreateTransaction_swcallet(test *testing.T) {
	w := new(SCWallet) // make me a wallet
	w.Init()
	w.NewSeed([]byte("lkdfsgjlagkjlasd"))
	h1, err := w.GenerateFctAddress([]byte("test 1"), 1, 1)
	if err != nil {
		test.Fail()
	}
	h2, err := w.GenerateFctAddress([]byte("test 2"), 1, 1)
	if err != nil {
		test.Fail()
	}

	t := w.CreateTransaction(0)

	w.AddInput(t, h1, 1000000)
	w.AddOutput(t, h2, 1000000-12000)

	signed, err := w.SignInputs(t)
	if !signed || err != nil {
		factoid.Prtln("Signed Fail: ", signed, err)
		test.Fail()
	}

	fee, err := t.CalculateFee(1000)
	if fee != 12000 || err != nil {
		factoid.Prtln("Fee Calculation Failed", fee, err)
		test.Fail()
	}

	err2 := w.Validate(1, t)
	if err2 != nil {
		factoid.Prtln(err2)
		test.Fail()
	}

}
Esempio n. 6
0
func Test_create_scwallet(test *testing.T) {
	w := new(SCWallet) // make me a wallet
	w.Init()
	w.NewSeed([]byte("lkdfsgjlagkjlasd"))
	we := new(WalletEntry)
	rcd := new(factoid.RCD_1)
	name := "John Smith"
	pub, pri, err := w.generateKey()

	if err != nil {
		factoid.Prtln("Generate Failed")
		test.Fail()
	}

	we.SetRCD(rcd)
	we.AddKey(pub, pri)
	we.SetName([]byte(name))

	txt, err := we.CustomMarshalText()
	var _ = txt
	// factoid.Prtln(string(txt))

}
Esempio n. 7
0
func Test_create_walletentry(test *testing.T) {
	w := new(SCWallet) // make me a wallet
	w.Init()
	w.NewSeed([]byte("lkdfsgjlagkjlasd"))
	we := new(WalletEntry)
	rcd := new(factoid.RCD_1)
	name := "John Smith"
	adrtype := "fct"
	pub, pri, err := w.generateKey()

	if err != nil {
		factoid.Prtln("Generate Failed")
		test.Fail()
	}

	we.SetRCD(rcd)
	we.AddKey(pub, pri)
	we.SetName([]byte(name))
	we.SetType(adrtype)

	data, err := we.MarshalBinary()
	if err != nil {
		test.Fail()
	}

	w2 := new(WalletEntry)

	data, err = w2.UnmarshalBinaryData(data)
	if err != nil {
		test.Fail()
	}

	if we.IsEqual(w2) != nil {
		test.Fail()
	}
}
Esempio n. 8
0
// Run a simulation of Transactions and blocks designed to test a pseudo random transaction set.
// If randomize = 0, then we will use the clock to seed the random number generator, and print the
// 64 bit seed used.  If randomize is set to some value, we use that vaule (allowing us to repeat
// tests if we like.
func Test_create_genesis_FactoidState(test *testing.T) {
	randomize := int64(0)
	numBlocks := 5
	numTransactions := 2 // Maximum Transactions
	maxIn := 1
	maxOut := 1
	if testing.Short() {
		fmt.Print("\nDoing Short Tests\n")
		numBlocks = 5
		numTransactions = 20
		maxIn = 5
		maxOut = 5
	}

	if randomize == 0 {
		randomize = time.Now().UnixNano()
		rand.Seed(randomize)
		randomize = rand.Int63()
		rand.Seed(randomize)
	} else {
		rand.Seed(randomize)
	}

	fmt.Println("Randomize Seed Used: ", randomize)

	cp.CP.AddUpdate(
		"Test Parms",
		"status", // Category
		fmt.Sprintf("Number of Blocks %d Max number Transactions %d",
			numBlocks, numTransactions),
		fmt.Sprintf("Randomize Seed: %v", randomize),
		0)

	// Use Bolt DB
	if !testing.Short() {
		fs.SetDB(new(database.MapDB))
		fs.GetDB().Init()
		db := stateinit.GetDatabase("./fct_test.db")
		fs.GetDB().SetPersist(db)
		fs.GetDB().SetBacker(db)

		fs.GetDB().DoNotPersist(fct.DB_F_BALANCES)
		fs.GetDB().DoNotPersist(fct.DB_EC_BALANCES)
		fs.GetDB().DoNotPersist(fct.DB_BUILD_TRANS)
		fs.GetDB().DoNotCache(fct.DB_FACTOID_BLOCKS)
		fs.GetDB().DoNotCache(fct.DB_BAD_TRANS)
		fs.GetDB().DoNotCache(fct.DB_TRANSACTIONS)
	} else {
		fs.SetDB(new(database.MapDB))
		fs.GetDB().Init()
	}
	// Make the coinbase very generous
	block.UpdateAmount(10000000)

	// Set the price for Factoids
	fs.SetFactoshisPerEC(100000)
	err := fs.LoadState()
	if err != nil {
		fmt.Println("Faid to initialize: ", err)
		os.Exit(1)
	}
	pre := fs.GetTransactionBlock(fs.GetCurrentBlock().GetPrevKeyMR())
	if !bytes.Equal(pre.GetHash().Bytes(), fs.GetCurrentBlock().GetPrevKeyMR().Bytes()) {
		fmt.Printf("Something is ill!")
		test.Fail()
		return
	}

	// Print the Genesis Block.  If we don't know the past, then print it.
	past := fs.GetTransactionBlock(pre.GetPrevKeyMR())
	if past == nil {
		for _, trans := range pre.GetTransactions() {
			PrtTrans(trans)
		}
	}

	if err != nil {
		fct.Prtln("Failed to load:", err)
		test.Fail()
		return
	}

	var max, min, maxblk int
	min = 100000
	// Create a number of blocks (i)
	for i := 0; i < numBlocks; i++ {

		fmt.Println("Block", fs.GetCurrentBlock().GetDBHeight())

		PrtTrans(fs.GetCurrentBlock().GetTransactions()[0])

		thisRunLimit := (rand.Int() % numTransactions) + 1

		cp.CP.AddUpdate(
			"This Block",
			"status", // Category
			fmt.Sprintf("Number of Transactions in this block: %d",
				thisRunLimit),
			"",
			0)

		var transCnt int
		periodMark := 1
		// Create a new block
		for j := fs.stats.transactions; fs.stats.transactions < j+thisRunLimit; { // Execute for some number RECORDED transactions
			transCnt++
			periodvalue := thisRunLimit / 10
			if periodvalue == 0 {
				periodvalue = 1
			}

			if periodMark <= 10 && transCnt%(periodvalue) == 0 {
				fs.EndOfPeriod(periodMark)
				periodMark++
			}

			tx := fs.newTransaction(maxIn, maxOut)

			addtest := true
			flip := rand.Int() % 100
			if rand.Int()%100 < 5 { // Mess up the timestamp on 5 percent of the transactions
				addtest = false
				blkts := uint64(fs.GetCurrentBlock().GetCoinbaseTimestamp())
				if flip < 49 { // Flip a coin
					tx.SetMilliTimestamp(blkts - uint64(fct.TRANSACTION_PRIOR_LIMIT) - 1)
					fs.stats.errors["trans too early"] += 1
					fs.stats.full["trans too early"] = "trans too early"
				} else {
					tx.SetMilliTimestamp(blkts + uint64(fct.TRANSACTION_POST_LIMIT) + 1)
					fs.stats.errors["trans too late"] += 1
					fs.stats.full["trans too late"] = "trans too late"
				}
				fs.twallet.SignInputs(tx)
			}

			// Test Marshal/UnMarshal
			m, err := tx.MarshalBinary()
			if err != nil {
				fmt.Println("\n Failed to Marshal: ", err)
				test.Fail()
				return
			}
			if len(m) > max {
				max = len(m)
				cp.CP.AddUpdate(
					"max transaction size", // tag
					"info",                 // Category
					fmt.Sprintf("Max Transaction Size %d", max), // Title
					fmt.Sprintf("<pre>#inputs = %-3d  #outputs = %-3d  #ecoutputs = %-3d<pre>",
						len(tx.GetInputs()), len(tx.GetOutputs()), len(tx.GetECOutputs())), // Msg
					0) // Expire
			}
			if len(m) < min {
				min = len(m)
				cp.CP.AddUpdate(
					"min transaction size", // tag
					"info",                 // Category
					fmt.Sprintf("Min Transaction Size %d", min), // Title
					fmt.Sprintf("<pre>#inputs = %-3d  #outputs = %-3d  #ecoutputs = %-3d<pre>",
						len(tx.GetInputs()), len(tx.GetOutputs()), len(tx.GetECOutputs())), // Msg
					0) // Expire
			}

			k := rand.Int() % (len(m) - 2)
			k++
			good := true
			flip = rand.Int() % 100
			// To simulate bad data, I mess up some of the data here.
			if rand.Int()%100 < 5 { // Mess up 5 percent of the transactions
				good = false
				if flip < 49 { // Flip a coin
					m = m[k:]
					fs.stats.errors["lost start of trans"] += 1
					fs.stats.full["lost start of trans"] = "lost start of trans"
				} else {
					m = m[:k]
					fs.stats.errors["lost end of trans"] += 1
					fs.stats.full["lost end of trans"] = "lost end of trans"
				}
			}

			t := new(fct.Transaction)
			err = t.UnmarshalBinary(m)

			if good && tx.IsEqual(t) != nil {
				fmt.Println("Fail valid Unmarshal")
				test.Fail()
				return
			}
			if err == nil {
				if good && err != nil {
					fmt.Println("Added a transaction that should have failed to be added")
					fmt.Println(err)
					test.Fail()
					return
				}
				if !good {
					fmt.Println("Failed to add a transaction that should have added")
					test.Fail()
					return
				}
			}

			if good {
				err = fs.AddTransaction(j+1, t)
			}
			if !addtest && err == nil {
				ts := int64(t.GetMilliTimestamp())
				bts := int64(fs.GetCurrentBlock().GetCoinbaseTimestamp())
				fmt.Println("timestamp failure ", ts, bts, ts-bts, fct.TRANSACTION_POST_LIMIT)
				test.Fail()
				return
			}
			if !addtest && err == nil {
				fmt.Println("failed to catch error")
				test.Fail()
				return
			}

			if addtest && good && err != nil {
				fmt.Println(err)
				fmt.Println("Unmarshal Failed. trans is good",
					"\nand the error detected: ", err,
					"\nand k:", k, "and flip:", flip)
				test.Fail()
				return
			}

			if good && addtest {

				PrtTrans(t)
				fs.stats.transactions += 1

				title := fmt.Sprintf("Bad Transactions: %d  Total transaactions %d",
					fs.stats.badAddresses, fs.stats.transactions)
				cp.CP.AddUpdate("Bad Transaction", "status", title, "", 0)

				time.Sleep(time.Second / 100)
			} else {
				fs.stats.badAddresses += 1
			}

		}
		//
		// Serialization deserialization tests for blocks
		//
		blkdata, err := fs.GetCurrentBlock().MarshalBinary()
		if err != nil {
			test.Fail()
			return
		}
		blk := fs.GetCurrentBlock().GetNewInstance().(block.IFBlock)
		err = blk.UnmarshalBinary(blkdata)
		if err != nil {
			test.Fail()
			return
		}
		if len(blkdata) > maxblk {
			maxblk = len(blkdata)
			cp.CP.AddUpdate(
				"maxblocksize", // tag
				"info",         // Category
				fmt.Sprintf("Max Block Size: %dK", maxblk/1024), // Title
				"", // Msg
				0)  // Expires
		}
		sec1 := fs.stats.TransactionsPerSec()
		sec2 := fs.stats.TotalTransactionsPerSec()
		cp.CP.AddUpdate(
			"transpersec", // tag
			"info",        // Category
			fmt.Sprintf("Transactions per second %4.2f, (+ bad) %4.2f", sec1, sec2), // Title
			"", // Msg
			0)  // Expires
		fmt.Println("Block Check")
		blk1 := fs.GetCurrentBlock()
		blk1MR := fs.GetCurrentBlock().GetHash()
		fmt.Println("ProcessEndOfBlock")
		fs.ProcessEndOfBlock() // Process the block.
		fmt.Println("Check ProcessEndOfBlock")
		blk2PMR := fs.GetCurrentBlock().GetPrevKeyMR()
		if !bytes.Equal(blk1MR.Bytes(), blk2PMR.Bytes()) {
			fmt.Println("MR's don't match")
			test.Fail()
			return
		}
		data, err := blk1.MarshalBinary()
		if err != nil {
			fmt.Println("Failed to Marshal")
			test.Fail()
			return
		}
		blk1b := new(block.FBlock)
		err = blk1b.UnmarshalBinary(data)
		if err != nil {
			fmt.Println("Failed to Unmarshal")
			test.Fail()
			return
		}
		if !bytes.Equal(blk2PMR.Bytes(), blk1b.GetKeyMR().Bytes()) {
			fmt.Println("Unmarshaled MR doesn't match")
			test.Fail()
			return
		}

		c := 1
		keys := make([]string, 0, len(fs.stats.errors))
		for k := range fs.stats.errors {
			keys = append(keys, k)
		}
		for i := 0; i < len(keys)-1; i++ {
			for j := 0; j < len(keys)-i-1; j++ {
				if keys[j] < keys[j+1] {
					t := keys[j]
					keys[j] = keys[j+1]
					keys[j+1] = t
				}
			}
		}
		var out bytes.Buffer
		for _, key := range keys {
			ecnt := fs.stats.errors[key]
			by := []byte(fs.stats.full[key])
			prt := string(by)
			if len(prt) > 80 {
				prt = string(by[:80]) + "..."
			}
			prt = strings.Replace(prt, "\n", " ", -1)
			out.WriteString(fmt.Sprintf("%6d %s\n", ecnt, prt))
			c++
		}
		cp.CP.AddUpdate(
			"transerrors",                        // tag
			"errors",                             // Category
			"Transaction Errors Detected:",       // Title
			"<pre>"+string(out.Bytes())+"</pre>", // Msg
			0) // Expires

	}
	fmt.Println("\nDone")
	//     // Get the head of the Factoid Chain
	//     blk := fs.GetTransactionBlock(fct.FACTOID_CHAINID_HASH)
	//     hashes := make([]fct.IHash,0,10)
	//     // First run back from the head back to the genesis block, collecting hashes.
	//     for {
	//         h := blk.GetHash()
	//         hashes = append(hashes,h)
	//         if bytes.Compare(blk.GetPrevKeyMR().Bytes(),fct.ZERO) == 0 {
	//             break
	//         }
	//         tblk := fs.GetTransactionBlock(blk.GetPrevKeyMR())
	//         blk = tblk
	//         time.Sleep(time.Second/100)
	//     }
	//
	//     // Now run forward, and build our accounting
	//     for i := len(hashes)-1; i>=0; i-- {
	//         blk = fs.GetTransactionBlock(hashes[i])
	//         fmt.Println("Block",blk.GetDBHeight())
	//         for _,trans := range blk.GetTransactions() {
	//             PrtTrans(trans)
	//         }
	//     }
}
Esempio n. 9
0
func (fs *Test_state) newTransaction(maxIn, maxOut int) fct.ITransaction {
	var max, sum uint64
	fs.inputAddresses = make([]fct.IAddress, 0, 20)
	for _, output := range fs.outputAddresses {
		bal := fs.GetBalance(output)
		if bal > 10000000 {
			fs.inputAddresses = append(fs.inputAddresses, output)
			sum += bal
		}
		if max < bal {
			max = bal
		}
	}

	cp.CP.AddUpdate(
		"Test max min inputs", // tag
		"info",                // Category
		"Tests generation",    // Title
		fmt.Sprintf("Input Addresses %d\nMax balance %s, Average Balance %s",
			len(fs.inputAddresses),
			strings.TrimSpace(fct.ConvertDecimal(max)),
			strings.TrimSpace(fct.ConvertDecimal(sum/uint64(len(fs.inputAddresses))))), // Msg
		60) // Expire

	// The following code is a function that creates an array
	// of addresses pulled from some source array of addresses
	// selected randomly.
	var makeList = func(source []fct.IAddress, cnt int) []fct.IAddress {
		adrs := make([]fct.IAddress, 0, cnt)
		for len(adrs) < cnt {
			i := rand.Int() % len(source)
			adr := source[i]
			adrs = append(adrs, adr)
		}
		return adrs
	}

	mIn := maxIn
	mOut := maxOut
	mEc := maxOut

	// Distribute our randomness over various spaces.  This doesn't
	// make for realistic transactions, but we don't care so much.
	joker := rand.Int() % 100
	if joker < 1 {
		mIn = maxIn * 2
	}
	if joker < 2 {
		mIn = maxIn * 4
	}
	if joker < 3 {
		mIn = maxIn * 8
	}
	if joker < 4 {
		mIn = maxIn * 16
	}
	if joker < 5 {
		mIn = maxIn * 32
	}
	if joker < 6 {
		mIn = maxIn * 64
	}
	joker = rand.Int() % 100
	if joker < 1 {
		mOut = maxOut * 2
	}
	if joker < 2 {
		mOut = maxOut * 4
	}
	if joker < 3 {
		mOut = maxOut * 8
	}
	if joker < 4 {
		mOut = maxOut * 16
	}
	if joker < 5 {
		mOut = maxOut * 32
	}
	if joker < 6 {
		mOut = maxOut * 64
	}
	joker = rand.Int() % 100
	if joker < 1 {
		mEc = maxOut * 2
	}
	if joker < 2 {
		mEc = maxOut * 4
	}
	if joker < 3 {
		mEc = maxOut * 8
	}
	if joker < 4 {
		mEc = maxOut * 16
	}
	if joker < 5 {
		mEc = maxOut * 32
	}
	if joker < 6 {
		mEc = maxOut * 64
	}

	// Get one to five inputs, and one to five outputs
	numInputs := rand.Int()%mIn + 1
	numOutputs := rand.Int() % mOut
	mumECOutputs := rand.Int() % mEc

	numInputs = (numInputs % (len(fs.inputAddresses) - 2)) + 1

	// fmt.Println("inputs outputs",numInputs,numOutputs, "limits",len(fs.inputAddresses),len(fs.outputAddresses))

	// Get my input and output addresses
	inputs := makeList(fs.inputAddresses, numInputs)
	outputs := makeList(fs.outputAddresses, numOutputs)
	ecoutputs := makeList(fs.ecoutputAddresses, mumECOutputs)
	var paid uint64
	t := fs.twallet.CreateTransaction(fs.GetTimeMilli())
	for _, adr := range inputs {
		balance := fs.GetBalance(adr)
		toPay := uint64(rand.Int63()) % (balance / 2)
		paid = toPay + paid
		fs.twallet.AddInput(t, adr, toPay)
	}

	paid = paid - fs.GetFactoshisPerEC()*uint64(len(ecoutputs))

	for _, adr := range outputs {
		fs.twallet.AddOutput(t, adr, paid/uint64(len(outputs)))
	}

	for _, adr := range ecoutputs {
		fs.twallet.AddECOutput(t, adr, fs.GetFactoshisPerEC())
	}

	fee, _ := t.CalculateFee(fs.GetFactoshisPerEC())
	toPay := t.GetInputs()[0].GetAmount()
	fs.twallet.UpdateInput(t, 0, inputs[0], toPay+fee)

	valid, err1 := fs.twallet.SignInputs(t)
	if err1 != nil {
		fct.Prtln("Failed to sign transaction")
	}
	if !valid {
		fct.Prtln("Transaction is not valid")
	}
	if err := fs.Validate(len(fs.GetCurrentBlock().GetTransactions()), t); err != nil || err1 != nil {

		fs.GetDB().Put(fct.DB_BAD_TRANS, t.GetHash(), t)

		fs.stats.badAddresses += 1

		str := []byte(err.Error())[:10]
		if bytes.Compare(str, []byte("The inputs")) != 0 {
			str = []byte(err.Error())[:30]
		}
		fs.stats.errors[string(str)] += 1
		fs.stats.full[string(str)] = err.Error()

		return fs.newTransaction(maxIn, maxOut)
	}
	return t
}
Esempio n. 10
0
func (fs *Test_state) newTransaction() fct.ITransaction {
	var maxBal, sum uint64
	fs.inputAddresses = make([]fct.IAddress, 0, 20)

	for _, output := range fs.outputAddresses {
		bal := fs.GetBalance(output)
		if bal > 100000000 {
			fs.inputAddresses = append(fs.inputAddresses, output)
			sum += bal
		}
		if maxBal < bal {
			maxBal = bal
		}
	}

	avgBal := sum / uint64(len(fs.inputAddresses))

	if fs.stats.transactions == 0 {
		fs.stats.MaxBal = maxBal
		fs.stats.AvgBal = avgBal
	} else {
		fs.stats.MaxBal = (fs.stats.MaxBal*uint64(fs.stats.transactions) + maxBal) / uint64(fs.stats.transactions+1)
		fs.stats.AvgBal = (fs.stats.AvgBal*uint64(fs.stats.transactions) + avgBal) / uint64(fs.stats.transactions+1)
	}

	cp.CP.AddUpdate(
		"Test max min inputs", // tag
		"info",                // Category
		"Tests generation",    // Title
		fmt.Sprintf("Input Addresses %d\n"+
			"Total Max balance %15s, Average Balance %15s\n"+
			"Last  Max balance %15s, Average Balance %16s",
			len(fs.inputAddresses),
			strings.TrimSpace(fct.ConvertDecimal(fs.stats.MaxBal)),
			strings.TrimSpace(fct.ConvertDecimal(fs.stats.AvgBal)),
			strings.TrimSpace(fct.ConvertDecimal(maxBal)),
			strings.TrimSpace(fct.ConvertDecimal(avgBal))), // Msg
		0) // Expire

	// The following code is a function that creates an array
	// of addresses pulled from some source array of addresses
	// selected randomly.
	var makeList = func(source []fct.IAddress, cnt int) []fct.IAddress {
		adrs := make([]fct.IAddress, 0, cnt)
		for len(adrs) < cnt {
			var i int
			if len(source) == 0 {
				return adrs
			}
			i = rand.Int() % len(source)
			adr := source[i]
			adrs = append(adrs, adr)
		}
		return adrs
	}

	// Get one to five inputs, and one to five outputs
	numInputs := fs.getRnd()
	numOutputs := fs.getRnd()
	mumECOutputs := fs.getRnd()

	if avgBal > 10000000000 {
		numOutputs = 0
	} // Throw away Factoids if too much money in the system

	lim := len(fs.inputAddresses) - 2
	if lim <= 0 {
		lim = 1
	}
	numInputs = (numInputs % (lim)) + 1

	// fmt.Println("inputs outputs",numInputs,numOutputs, "limits",len(fs.inputAddresses),len(fs.outputAddresses))

	// Get my input and output addresses
	inputs := makeList(fs.inputAddresses, numInputs)
	outputs := makeList(fs.outputAddresses, numOutputs)
	ecoutputs := makeList(fs.ecoutputAddresses, mumECOutputs)
	var paid uint64
	t := fs.twallet.CreateTransaction(fs.GetTimeMilli())
	for _, adr := range inputs {
		balance := fs.GetBalance(adr)
		toPay := uint64(rand.Int63()) % (balance / 2)
		paid = toPay + paid
		fs.twallet.AddInput(t, adr, toPay)
	}

	paid = paid - fs.GetFactoshisPerEC()*uint64(len(ecoutputs))

	for _, adr := range outputs {
		fs.twallet.AddOutput(t, adr, paid/uint64(len(outputs)))
	}

	for _, adr := range ecoutputs {
		fs.twallet.AddECOutput(t, adr, fs.GetFactoshisPerEC())
	}

	fee, _ := t.CalculateFee(fs.GetFactoshisPerEC())
	toPay := t.GetInputs()[0].GetAmount()
	fs.twallet.UpdateInput(t, 0, inputs[0], toPay+fee)

	valid, err1 := fs.twallet.SignInputs(t)
	if err1 != nil {
		fct.Prtln("Failed to sign transaction")
	}
	if !valid {
		fct.Prtln("Transaction is not valid")
	}
	if err := fs.Validate(len(fs.GetCurrentBlock().GetTransactions()), t); err != nil || err1 != nil {

		fs.GetDB().Put(fct.DB_BAD_TRANS, t.GetHash(), t)

		fs.stats.badAddresses += 1

		str := []byte(err.Error())[:10]
		if bytes.Compare(str, []byte("The inputs")) != 0 {
			str = []byte(err.Error())[:30]
		}
		fs.stats.errors[string(str)] += 1
		fs.stats.full[string(str)] = err.Error()

		return fs.newTransaction()
	}
	return t
}
Esempio n. 11
0
func Test_create_block(test *testing.T) {
	w := new(wallet.SCWallet) // make me a wallet
	w.Init()
	w.NewSeed([]byte("slfkjasdlfjasflajsfl"))
	scb := block.NewFBlock(1000, 0)
	cb := w.CreateTransaction(uint64(time.Now().UnixNano() / 1000000))
	scb.AddCoinbase(cb)

	for i := 0; i < 3; i++ {
		h0, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-0"), 1, 1)
		if err != nil {
			sc.Prtln("Error 1")
			test.Fail()
		}
		h1, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-1"), 1, 1)
		if err != nil {
			sc.Prtln("Error 2")
			test.Fail()
		}
		h2, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-2"), 1, 1)
		if err != nil {
			sc.Prtln("Error 3")
			test.Fail()
		}
		h3, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-3"), 1, 1)
		if err != nil {
			sc.Prtln("Error 4")
			test.Fail()
		}
		h4, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-4"), 1, 1)
		if err != nil {
			sc.Prtln("Error 5")
			test.Fail()
		}
		h5, err := w.GenerateFctAddress([]byte("test "+cv.Itoa(i)+"-5"), 1, 1)
		if err != nil {
			sc.Prtln("Error 6")
			test.Fail()
		}

		t := w.CreateTransaction(uint64(time.Now().UnixNano() / 1000000))

		w.AddInput(t, h1, 1000000)
		w.AddInput(t, h2, 1000000)
		w.AddOutput(t, h3, 1000000)
		w.AddOutput(t, h4, 500000)
		w.AddECOutput(t, h5, 500000)
		w.AddInput(t, h0, 0)
		fee, err := t.CalculateFee(1000)
		w.UpdateInput(t, 2, h0, fee)

		signed, err := w.SignInputs(t)
		if err != nil {
			sc.Prtln("Error found: ", err)
			test.Fail()
			return
		}
		if !signed {
			sc.Prtln("Not valid")
			test.Fail()
			return
		}

		err = scb.AddTransaction(t)
		if err != nil {
			sc.Prtln("Error found: ", err)
			test.Fail()
			return
		}
	}
	data, err := scb.MarshalBinary()
	if err != nil {
		fmt.Println(err)
		test.Fail()
		return
	}
	scb2 := new(block.FBlock)
	_, err = scb2.UnmarshalBinaryData(data)

	fmt.Println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n", scb2)

	if err != nil {
		fmt.Println(err)
		test.Fail()
		return
	}
	//sc.Prtln("FIRST\n",scb,"SECOND\n",scb2)
	if scb.IsEqual(scb2) != nil {
		fmt.Println(err)
		test.Fail()
		return
	}

}
Esempio n. 12
0
func (fs *FactoidState) LoadState() error {
	var hashes []fct.IHash
	cblk := fs.GetTransactionBlock(fct.FACTOID_CHAINID_HASH)
	// If there is no head for the Factoids in the database, we have an
	// uninitialized database.  We need to add the Genesis Block. TODO
	if cblk == nil {
		cp.CP.AddUpdate(
			"Creating Factoid Genesis Block", // tag
			"info", // Category
			"Creating the Factoid Genesis Block", // Title
			"", // Msg
			60) // Expire
		//gb := block.GetGenesisFBlock(fs.GetTimeMilli(), 1000000,10,200000000000)
		gb := block.GetGenesisFBlock()
		fs.PutTransactionBlock(gb.GetHash(), gb)
		fs.PutTransactionBlock(fct.FACTOID_CHAINID_HASH, gb)
		err := fs.AddTransactionBlock(gb)
		if err != nil {
			fct.Prtln("Failed to build initial state.\n", err)
			return err
		}
		fs.ProcessEndOfBlock()
		return nil
	}
	blk := cblk
	// First run back from the head back to the genesis block, collecting hashes.
	for {
		if blk == nil {
			return fmt.Errorf("Block not found or not formated properly")

		}
		h := blk.GetHash()
		for _, hash := range hashes {
			if bytes.Compare(hash.Bytes(), h.Bytes()) == 0 {
				return fmt.Errorf("Corrupted database; same hash found twice")
			}
		}
		hashes = append(hashes, h)
		if bytes.Compare(blk.GetPrevKeyMR().Bytes(), fct.ZERO_HASH) == 0 {
			break
		}
		tblk := fs.GetTransactionBlock(blk.GetPrevKeyMR())
		if tblk == nil {
			return fmt.Errorf("Failed to find the block at height: %d", blk.GetDBHeight()-1)
		}
		if !bytes.Equal(tblk.GetHash().Bytes(), blk.GetPrevKeyMR().Bytes()) {
			return fmt.Errorf("Hash Failure!  Database must be rebuilt")
		}

		blk = tblk
		time.Sleep(time.Second / 100)
		cp.CP.AddUpdate(
			"loadState",
			"status", // Category
			"Loading State",
			fmt.Sprintf("Scanning backwards. Block: %d", blk.GetDBHeight()),
			0)
	}

	// Now run forward, and build our accounting
	for i := len(hashes) - 1; i >= 0; i-- {
		blk = fs.GetTransactionBlock(hashes[i])
		if blk == nil {

			return fmt.Errorf("Should never happen.  Block not found in the Database\n"+
				"No block found for: %s", hashes[i].String())

		}

		err := fs.AddTransactionBlock(blk) // updates accounting for this block
		if err != nil {
			fct.Prtln("Failed to rebuild state.\n", err)
			return err
		}
		time.Sleep(time.Second / 100)
		cp.CP.AddUpdate(
			"loadState",
			"status", // Category
			"Loading State",
			fmt.Sprintf("Loading and Processing. Block: %d", blk.GetDBHeight()),
			0)
	}

	fs.dbheight = blk.GetDBHeight()
	fs.ProcessEndOfBlock()
	return nil
}
Esempio n. 13
0
func Test_create_genesis_FactoidState(test *testing.T) {
	fmt.Print("\033[2J")

	numBlocks := 5000
	numTransactions := 500
	maxIn := 5
	maxOut := 20
	if testing.Short() {
		fmt.Print("\nDoing Short Tests\n")
		numBlocks = 5
		numTransactions = 20
		maxIn = 5
		maxOut = 5
	}

	// Use Bolt DB
	if !testing.Short() {
		fs.SetDB(new(database.MapDB))
		fs.GetDB().Init()
		db := stateinit.GetDatabase("/tmp/fct_test.db")
		fs.GetDB().SetPersist(db)
		fs.GetDB().SetBacker(db)

		fs.GetDB().DoNotPersist(fct.DB_F_BALANCES)
		fs.GetDB().DoNotPersist(fct.DB_EC_BALANCES)
		fs.GetDB().DoNotPersist(fct.DB_BUILD_TRANS)
		fs.GetDB().DoNotCache(fct.DB_FACTOID_BLOCKS)
		fs.GetDB().DoNotCache(fct.DB_BAD_TRANS)
		fs.GetDB().DoNotCache(fct.DB_TRANSACTIONS)
	} else {
		fs.SetDB(new(database.MapDB))
		fs.GetDB().Init()
	}
	// Set the price for Factoids
	fs.SetFactoshisPerEC(100000)
	err := fs.LoadState()
	if err != nil {
		fct.Prtln("Failed to load:", err)
		test.Fail()
		return
	}
	fs.ProcessEndOfBlock()

	// Make the coinbase very generous
	block.UpdateAmount(100000000000)

	var cnt, max, min, maxblk int
	min = 100000
	// Create a number of blocks (i)
	for i := 0; i < numBlocks; i++ {

		periodMark := 1
		// Create a new block
		for j := cnt; cnt < j+numTransactions; { // Execute for some number RECORDED transactions

			if periodMark <= 10 && cnt%(numTransactions/10) == 0 {
				fs.EndOfPeriod(periodMark)
				periodMark++
			}

			tx := fs.newTransaction(maxIn, maxOut)

			addtest := true
			flip := rand.Int() % 100
			if rand.Int()%100 < 5 { // Mess up the timestamp on 5 percent of the transactions
				addtest = false
				blkts := uint64(fs.GetCurrentBlock().GetCoinbaseTimestamp())
				if flip < 49 { // Flip a coin
					tx.SetMilliTimestamp(blkts - uint64(fct.TRANSACTION_PRIOR_LIMIT) - 1)
					fs.stats.errors["trans too early"] += 1
					fs.stats.full["trans too early"] = "trans too early"
				} else {
					tx.SetMilliTimestamp(blkts + uint64(fct.TRANSACTION_POST_LIMIT) + 1)
					fs.stats.errors["trans too late"] += 1
					fs.stats.full["trans too late"] = "trans too late"
				}
				fs.twallet.SignInputs(tx)
			}

			// Test Marshal/UnMarshal
			m, err := tx.MarshalBinary()
			if err != nil {
				fmt.Println("\n Failed to Marshal: ", err)
				test.Fail()
				return
			}
			if len(m) > max {
				fmt.Print("\033[33;0H")
				max = len(m)
				fmt.Println("Max Transaction", cnt, "is", len(m), "Bytes long. ",
					len(tx.GetInputs()), "inputs and",
					len(tx.GetOutputs()), "outputs and",
					len(tx.GetECOutputs()), "ecoutputs                       ")
				fmt.Print("\033[41;0H")
			}
			if len(m) < min {
				fmt.Print("\033[34;0H")
				min = len(m)
				fmt.Println("Min Transaction", cnt, "is", len(m), "Bytes long. ",
					len(tx.GetInputs()), "inputs and",
					len(tx.GetOutputs()), "outputs and",
					len(tx.GetECOutputs()), "ecoutputs                       ")
				fmt.Print("\033[41;0H")
			}

			k := rand.Int() % (len(m) - 2)
			k++
			good := true
			flip = rand.Int() % 100
			// To simulate bad data, I mess up some of the data here.
			if rand.Int()%100 < 5 { // Mess up 5 percent of the transactions
				good = false
				if flip < 49 { // Flip a coin
					m = m[k:]
					fs.stats.errors["lost start of trans"] += 1
					fs.stats.full["lost start of trans"] = "lost start of trans"
				} else {
					m = m[:k]
					fs.stats.errors["lost end of trans"] += 1
					fs.stats.full["lost end of trans"] = "lost end of trans"
				}
			}

			t := new(fct.Transaction)
			err = t.UnmarshalBinary(m)

			if good && tx.IsEqual(t) != nil {
				fmt.Println("\n\n\n\n\n\nFail valid Unmarshal")
				test.Fail()
				return
			}
			if err == nil {
				if good && err != nil {
					fmt.Println("\n\n\n\n\n\n\nAdded a transaction that should have failed to be added")
					fmt.Println(err)
					test.Fail()
					return
				}
				if !good {
					fmt.Println("\n\n\n\n\n\n\nFailed to add a transaction that should have added")
					test.Fail()
					return
				}
			}

			if good {
				err = fs.AddTransaction(t)
			}
			if !addtest && err == nil {
				ts := int64(t.GetMilliTimestamp())
				bts := int64(fs.GetCurrentBlock().GetCoinbaseTimestamp())
				fmt.Println("\n\n\n\n\n\n\ntimestamp failure ", ts, bts, ts-bts, fct.TRANSACTION_POST_LIMIT)
				test.Fail()
				return
			}
			if !addtest && err == nil {
				fmt.Println("\n\n\n\n\n\n\nfailed to catch error")
				test.Fail()
				return
			}

			if addtest && good && err != nil {
				fmt.Println(err)
				fmt.Println("\n\n\n\n\n\n\n\n\n\nUnmarshal Failed. trans is good",
					"\nand the error detected: ", err,
					"\nand k:", k, "and flip:", flip)
				test.Fail()
				return
			}

			if good && addtest {
				fmt.Print("\033[32;0H")
				fmt.Println("Bad Transactions: ", fs.stats.badAddresses, "   Total transactions: ", cnt, "\r")
				fmt.Print("\033[42;0H")
				time.Sleep(9000)
				cnt += 1
			} else {
				fs.stats.badAddresses += 1
			}

		}
		//
		// Serialization deserialization tests for blocks
		//
		blkdata, err := fs.GetCurrentBlock().MarshalBinary()
		if err != nil {
			test.Fail()
			return
		}
		blk := fs.GetCurrentBlock().GetNewInstance().(block.IFBlock)
		err = blk.UnmarshalBinary(blkdata)
		if err != nil {
			test.Fail()
			return
		}
		if len(blkdata) > maxblk {
			fmt.Printf("\033[%d;%dH", (blk.GetDBHeight())%30+1, (((blk.GetDBHeight())/30)%1)*25+1)
			fmt.Printf("Blk:%6d %8d B ", blk.GetDBHeight(), len(blkdata))
			fmt.Printf("\033[%d;%dH", (blk.GetDBHeight())%30+2, (((blk.GetDBHeight())/30)%1)*25+1)
			fmt.Printf("%24s", "=====================    ")
		}
		//         blk:=fs.GetCurrentBlock()       // Get Current block, but hashes are set by processing.
		fs.ProcessEndOfBlock() // Process the block.
		//         fmt.Println(blk)                // Now print it.

		c := 1
		keys := make([]string, 0, len(fs.stats.errors))
		for k := range fs.stats.errors {
			keys = append(keys, k)
		}
		for i := 0; i < len(keys)-1; i++ {
			for j := 0; j < len(keys)-i-1; j++ {
				if keys[j] < keys[j+1] {
					t := keys[j]
					keys[j] = keys[j+1]
					keys[j+1] = t
				}
			}
		}
		for _, key := range keys {
			cnt := fs.stats.errors[key]
			by := []byte(fs.stats.full[key])
			prt := string(by)
			if len(prt) > 80 {
				prt = string(by[:80]) + "..."
			}
			prt = strings.Replace(prt, "\n", " ", -1)
			fmt.Printf("\033[%d;30H %5d %-83s", c, cnt, prt)
			c++
		}
	}
	fmt.Println("\nDone")
}
Esempio n. 14
0
func (fs *Test_state) newTransaction(maxIn, maxOut int) fct.ITransaction {
	var max, max2 uint64
	fs.inputAddresses = make([]fct.IAddress, 0, 20)
	for _, output := range fs.outputAddresses {
		bal := fs.GetBalance(output)
		if bal > 100000 {
			fs.inputAddresses = append(fs.inputAddresses, output)
		}
		if max < bal {
			max2 = max
			max = bal
		} else {
			if max2 < bal {
				max2 = bal
			}
		}
	}

	// The following code is a function that creates an array
	// of addresses pulled from some source array of addresses
	// selected randomly.
	var makeList = func(source []fct.IAddress, cnt int) []fct.IAddress {
		adrs := make([]fct.IAddress, 0, cnt)
		for len(adrs) < cnt {
			i := rand.Int() % len(source)
			adr := source[i]
			adrs = append(adrs, adr)
		}
		return adrs
	}

	mIn := maxIn
	mOut := maxOut

	joker := rand.Int() % 100
	if joker < 1 {
		mIn = maxIn * 100
	}
	joker = rand.Int() % 100
	if joker < 1 {
		mOut = maxOut * 200
	}

	// Get one to five inputs, and one to five outputs
	numInputs := rand.Int()%mIn + 1
	numOutputs := rand.Int() % mOut
	mumECOutputs := rand.Int() % mOut

	numInputs = (numInputs % (len(fs.inputAddresses) - 2)) + 1

	// fmt.Println("inputs outputs",numInputs,numOutputs, "limits",len(fs.inputAddresses),len(fs.outputAddresses))

	// Get my input and output addresses
	inputs := makeList(fs.inputAddresses, numInputs)
	outputs := makeList(fs.outputAddresses, numOutputs)
	ecoutputs := makeList(fs.ecoutputAddresses, mumECOutputs)
	var paid uint64
	t := fs.twallet.CreateTransaction(fs.GetTimeMilli())
	for _, adr := range inputs {
		balance := fs.GetBalance(adr)
		toPay := uint64(rand.Int63()) % (balance)
		paid = toPay + paid
		fs.twallet.AddInput(t, adr, toPay)
		//fmt.Print("\033[10;3H")
		//fmt.Printf("%s %s    \n",adr.String(),fct.ConvertDecimal(toPay))
		//fmt.Print("\033[40;3H")
	}

	paid = paid - fs.GetFactoshisPerEC()*uint64(len(ecoutputs))

	for _, adr := range outputs {
		fs.twallet.AddOutput(t, adr, paid/uint64(len(outputs)))
	}

	for _, adr := range ecoutputs {
		fs.twallet.AddECOutput(t, adr, fs.GetFactoshisPerEC())
	}

	fee, _ := t.CalculateFee(fs.GetFactoshisPerEC())
	toPay := t.GetInputs()[0].GetAmount()
	fs.twallet.UpdateInput(t, 0, inputs[0], toPay+fee)

	valid, err1 := fs.twallet.SignInputs(t)
	if err1 != nil {
		fct.Prtln("Failed to sign transaction")
	}
	if !valid {
		fct.Prtln("Transaction is not valid")
	}
	if err := fs.Validate(len(fs.GetCurrentBlock().GetTransactions()), t); err != nil || err1 != nil {

		fs.GetDB().Put(fct.DB_BAD_TRANS, t.GetHash(), t)

		fs.stats.badAddresses += 1

		str := []byte(err.Error())[:10]
		if bytes.Compare(str, []byte("The inputs")) != 0 {
			str = []byte(err.Error())[:30]
		}
		fs.stats.errors[string(str)] += 1
		fs.stats.full[string(str)] = err.Error()

		return fs.newTransaction(maxIn, maxOut)
	}
	return t
}