예제 #1
0
// Initialize Factoid Block Chain from database
func initFctChain() {

	//Initialize the Admin Chain ID
	fchain = new(common.FctChain)
	fchain.ChainID = new(common.Hash)
	fchain.ChainID.SetBytes(fct.FACTOID_CHAINID)

	// get all aBlocks from db
	fBlocks, _ := db.FetchAllFBlocks()
	sort.Sort(util.ByFBlockIDAccending(fBlocks))

	// double check the block ids
	for i := 0; i < len(fBlocks); i = i + 1 {
		if uint32(i) != fBlocks[i].GetDBHeight() {
			panic(errors.New("BlockID does not equal index for chain:" +
				fchain.ChainID.String() + " block:" +
				fmt.Sprintf("%v", fBlocks[i].GetDBHeight())))
		} else {
			FactoshisPerCredit = fBlocks[i].GetExchRate()
			common.FactoidState.SetFactoshisPerEC(FactoshisPerCredit)
			// initialize the FactoidState in sequence
			err := common.FactoidState.AddTransactionBlock(fBlocks[i])
			if err != nil {
				panic("Failed to rebuild factoid state: " + err.Error())
			}
		}
	}

	//Create an empty block and append to the chain
	if len(fBlocks) == 0 || dchain.NextDBHeight == 0 {
		common.FactoidState.SetFactoshisPerEC(FactoshisPerCredit)
		fchain.NextBlockHeight = 0
		// func GetGenesisFBlock(ftime uint64, ExRate uint64, addressCnt int, Factoids uint64 ) IFBlock {
		//fchain.NextBlock = block.GetGenesisFBlock(0, FactoshisPerCredit, 10, 200000000000)
		fchain.NextBlock = block.GetGenesisFBlock()
		fmt.Println(fchain.NextBlock)
		gb := fchain.NextBlock

		// If a client, this block is going to get downloaded and added.  Don't do it twice.
		if nodeMode == common.SERVER_NODE {
			err := common.FactoidState.AddTransactionBlock(gb)
			if err != nil {
				panic(err)
			}
		}

	} else {
		fchain.NextBlockHeight = dchain.NextDBHeight
		common.FactoidState.ProcessEndOfBlock2(dchain.NextDBHeight)
		fchain.NextBlock = common.FactoidState.GetCurrentBlock()
	}

	exportFctChain(fchain)

}
예제 #2
0
// build Genesis blocks
func buildGenesisBlocks() error {
	//Set the timestamp for the genesis block
	t, err := time.Parse(time.RFC3339, common.GENESIS_BLK_TIMESTAMP)
	if err != nil {
		panic("Not able to parse the genesis block time stamp")
	}
	dchain.NextBlock.Header.Timestamp = uint32(t.Unix() / 60)

	// Allocate the first two dbentries for ECBlock and Factoid block
	dchain.AddDBEntry(&common.DBEntry{}) // AdminBlock
	dchain.AddDBEntry(&common.DBEntry{}) // ECBlock
	dchain.AddDBEntry(&common.DBEntry{}) // Factoid block

	// Entry Credit Chain
	cBlock := newEntryCreditBlock(ecchain)
	procLog.Debugf("buildGenesisBlocks: cBlock=%s\n", spew.Sdump(cBlock))
	dchain.AddECBlockToDBEntry(cBlock)
	exportECChain(ecchain)

	// Admin chain
	aBlock := newAdminBlock(achain)
	procLog.Debugf("buildGenesisBlocks: aBlock=%s\n", spew.Sdump(aBlock))
	dchain.AddABlockToDBEntry(aBlock)
	exportAChain(achain)

	// factoid Genesis Address
	//fchain.NextBlock = block.GetGenesisFBlock(0, FactoshisPerCredit, 10, 200000000000)
	fchain.NextBlock = block.GetGenesisFBlock()
	FBlock := newFactoidBlock(fchain)
	dchain.AddFBlockToDBEntry(FBlock)
	exportFctChain(fchain)

	// Directory Block chain
	procLog.Debug("in buildGenesisBlocks")
	dbBlock := newDirectoryBlock(dchain)

	// Check block hash if genesis block
	if dbBlock.DBHash.String() != common.GENESIS_DIR_BLOCK_HASH {
		//Panic for Milestone 1
		panic("\nGenesis block hash expected: " + common.GENESIS_DIR_BLOCK_HASH +
			"\nGenesis block hash found:    " + dbBlock.DBHash.String() + "\n")
	}

	exportDChain(dchain)

	// place an anchor into btc
	placeAnchor(dbBlock)

	return nil
}
예제 #3
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
}