Skip to content

Commit

Permalink
merge master into rollup FD-706
Browse files Browse the repository at this point in the history
  • Loading branch information
carryforward committed Oct 16, 2018
2 parents 1698137 + 035968e commit 6c6a9a1
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 43 deletions.
30 changes: 23 additions & 7 deletions activations/activationHeight.go
Expand Up @@ -4,6 +4,7 @@ package activations

import (
"fmt"
"math"
"os"

"github.com/FactomProject/factomd/common/globals"
Expand All @@ -12,9 +13,9 @@ import (
type ActivationType int

const (
_ ActivationType = iota // 0 Don't use ZERO
ELECTION_NO_SORT = iota // 1 -- this is a passing activation and this ID may be reused once that height is passes and the references are removed

_ ActivationType = iota // 0 Don't use ZERO
ELECTION_NO_SORT = iota // 1 -- this is a passing activation and this ID may be reused once that height is passes and the references are removed
TESTNET_COINBASE_PERIOD = iota // 2 -- this is a passing activation and this ID may be reused once that height is passes and the references are removed
//
ACTIVATION_TYPE_COUNT = iota - 1 // Always Last
)
Expand All @@ -23,6 +24,7 @@ type Activation struct {
Name string
Id ActivationType
Description string
DefaultHeight int // height of activation on nets not expressly listed (math.MaxInt32 means never)
ActivationHeight map[string]int // this maps a network Name to the height for that network for the feature to activate
}

Expand All @@ -33,14 +35,24 @@ func init() {

// unordered list of activations
var activations []Activation = []Activation{
Activation{"ElectionNoSort", ELECTION_NO_SORT, "Disable sorting of severs after elections",
Activation{"ElectionNoSort", ELECTION_NO_SORT,
"Disable sorting of severs after elections",
0, // active at the beginning of time unless overridden below
map[string]int{
"MAIN": 146060 + 8*24*10 + 1, // On 6/20/18 11:45 mainnet was 146060, we want activation at 6/28/18 at ~12pm
"TEST": 0, // On 6/20/18 11:45 testnet was 146060, we want activation at 6/22/18 at ~12pm
"LOCAL": 10, // Must be > 6 for TestActivationHeightElection to pass
"CUSTOM:fct_community_test": 33037 + 2*24*10 + 1, // On 6/22/18 11:45 testnet was 33037, we want activation at 6/24/18 at 12:00pm
},
},
Activation{"TestNetCoinBasePeriod", TESTNET_COINBASE_PERIOD,
"Change testnet coin base payout delay to 144 blocks",
math.MaxInt32, // inactive unless overridden below
map[string]int{
"MAIN": math.MaxInt32,
"LOCAL": math.MaxInt32,
"CUSTOM:fct_community_test": 45335, // Monday morning September 17
},
},
}

if ACTIVATION_TYPE_COUNT != len(activations) {
Expand Down Expand Up @@ -92,8 +104,12 @@ func IsActive(id ActivationType, height int) bool {

h, ok := a.ActivationHeight[netName]
if !ok {
fmt.Fprintf(os.Stderr, "Activation %s does not know network name \"%s\". Activating at 0.\n", id.String(), netName)
a.ActivationHeight[netName] = 0
a.ActivationHeight[netName] = a.DefaultHeight
if a.DefaultHeight != math.MaxInt32 {
fmt.Fprintf(os.Stderr, "Activation %s does not know network name \"%s\". Activating at %d.\n", id.String(), netName, a.DefaultHeight)
} else {
fmt.Fprintf(os.Stderr, "Activation %s does not know network name \"%s\". Never activating.\n", id.String(), netName)
}
return true
}

Expand Down
1 change: 0 additions & 1 deletion common/directoryBlock/directoryBlock.go
Expand Up @@ -445,7 +445,6 @@ func NewDirectoryBlock(prev interfaces.IDirectoryBlock) interfaces.IDirectoryBlo

newdb.Header = new(DBlockHeader)
newdb.GetHeader().SetVersion(constants.VERSION_0)

if prev != nil {
newdb.GetHeader().SetPrevFullHash(prev.GetFullHash())
newdb.GetHeader().SetPrevKeyMR(prev.GetKeyMR())
Expand Down
4 changes: 2 additions & 2 deletions common/messages/dbstate.go
Expand Up @@ -694,14 +694,14 @@ func (m *DBStateMsg) MarshalBinary() (rval []byte, err error) {

func (m *DBStateMsg) String() string {
data, _ := m.MarshalBinary()
return fmt.Sprintf("DBState: dbht:%3d [size: %11s] dblock %6x admin %6x fb %6x ec %6x hash %6x",
return fmt.Sprintf("DBState: dbht:%3d [size: %11s] dblock %6x admin %6x fb %6x ec %6x hash %6x ts:%s DB:%v",
m.DirectoryBlock.GetHeader().GetDBHeight(),
primitives.AddCommas(int64(len(data))),
m.DirectoryBlock.GetKeyMR().Bytes()[:3],
m.AdminBlock.GetHash().Bytes()[:3],
m.FactoidBlock.GetHash().Bytes()[:3],
m.EntryCreditBlock.GetHash().Bytes()[:3],
m.GetHash().Bytes()[:3])
m.GetHash().Bytes()[:3], m.DirectoryBlock.GetTimestamp().String(), m.IsInDB)
}

func (m *DBStateMsg) LogFields() log.Fields {
Expand Down
119 changes: 118 additions & 1 deletion engine/factomd_test.go
Expand Up @@ -15,6 +15,7 @@ import (
"time"

"github.com/FactomProject/factomd/activations"
"github.com/FactomProject/factomd/common/constants"
"github.com/FactomProject/factomd/common/globals"
"github.com/FactomProject/factomd/common/primitives"
"github.com/FactomProject/factomd/common/primitives/random"
Expand All @@ -25,14 +26,22 @@ import (

var _ = Factomd

// SetupSim()
// SetupSim takes care of your options, and setting up nodes
// pass in a string for nodes: 4 Leaders, 3 Audit, 4 Followers: "LLLLAAAFFFF" as the first argument
// Pass in the Network type ex. "LOCAL" as the second argument
// It has default but if you want just add it like "map[string]string{"--Other" : "Option"}" as the third argument
// Pass in t for the testing as the 4th argument

//
//EX. state0 := SetupSim("LLLLLLLLLLLLLLLAAAAAAAAAA", "LOCAL", map[string]string {"--controlpanelsetting" : "readwrite"}, t)
func SetupSim(GivenNodes string, NetworkType string, UserAddedOptions map[string]string, t *testing.T) *state.State {
return SetupSim2(GivenNodes, false, NetworkType, UserAddedOptions, t)
}

// SetupSim2()
// new entrypoint into SetupSim to allow specifying "tight" transactions, where EC are bought as needed rather than in
// large blocks.
func SetupSim2(GivenNodes string, tight bool, NetworkType string, UserAddedOptions map[string]string, t *testing.T) *state.State {
l := len(GivenNodes)
DefaultOptions := map[string]string{
"--db": "Map",
Expand Down Expand Up @@ -67,6 +76,10 @@ func SetupSim(GivenNodes string, NetworkType string, UserAddedOptions map[string
state0.MessageTally = true
time.Sleep(3 * time.Second)
StatusEveryMinute(state0)
if tight {
runCmd("Re")
}

creatingNodes(GivenNodes, state0)

t.Logf("Allocated %d nodes", l)
Expand All @@ -78,6 +91,19 @@ func SetupSim(GivenNodes string, NetworkType string, UserAddedOptions map[string
return state0
}

// Wait for a specific blocks
func WaitForBlock(s *state.State, newBlock int) {
fmt.Printf("WaitForBlocks(%d)\n", newBlock)
TimeNow(s)
sleepTime := time.Duration(globals.Params.BlkTime) * 1000 / 40 // Figure out how long to sleep in milliseconds
for i := int(s.LLeaderHeight); i < newBlock; i++ {
for int(s.LLeaderHeight) < i {
time.Sleep(sleepTime * time.Millisecond) // wake up and about 4 times per minute
}
TimeNow(s)
}
}

func creatingNodes(creatingNodes string, state0 *state.State) {
runCmd(fmt.Sprintf("g%d", len(creatingNodes)))
// Wait till all the entries from the g command are processed
Expand Down Expand Up @@ -382,6 +408,40 @@ func TestLoad(t *testing.T) {

} // testLoad(){...}

func TestLoad2(t *testing.T) {
if ranSimTest {
return
}

ranSimTest = true

state0 := SetupSim2("LLLAAAFFF", true, "LOCAL", map[string]string{}, t)

runCmd("7") // select node 1
runCmd("x") // take out 7 from the network
WaitBlocks(state0, 1)
WaitForMinute(state0, 1)

CheckAuthoritySet(3, 3, t)

runCmd("R30") // Feed load
WaitBlocks(state0, 3)
runCmd("Rt60")
runCmd("T20")
runCmd("R.5")
WaitBlocks(state0, 2)
runCmd("x")
WaitBlocks(state0, 3)
WaitMinutes(state0, 3)

ht7 := GetFnodes()[7].State.GetLLeaderHeight()
ht6 := GetFnodes()[6].State.GetLLeaderHeight()
if ht7 != ht6 {
t.Fatalf("Node 7 was at dbheight %d which didn't match Node 6 at dbheight %d", ht7, ht6)
}

} // testLoad(){...}

func TestMakeALeader(t *testing.T) {
if ranSimTest {
return
Expand Down Expand Up @@ -1280,6 +1340,63 @@ func TestDBSigElection(t *testing.T) {

}

func TestTestNetCoinBaseActivation(t *testing.T) {
if ranSimTest {
return
}
ranSimTest = true

// reach into the activation an hack the TESTNET_COINBASE_PERIOD to be early so I can check it worked.
activations.ActivationMap[activations.TESTNET_COINBASE_PERIOD].ActivationHeight["LOCAL"] = 22

state0 := SetupSim("LAF", "LOCAL", map[string]string{"--debuglog": "fault|badmsg|network|process|dbsig", "--faulttimeout": "10", "--blktime": "5"}, t)
CheckAuthoritySet(1, 1, t)
fmt.Println("Simulation configured")
nextBlock := uint32(11 + constants.COINBASE_DECLARATION) // first grant is at 11 so it pays at 21
fmt.Println("Wait till first grant should payout")
WaitForBlock(state0, int(nextBlock)) // wait for the first coin base payout to be generated
factoidState0 := state0.FactoidState.(*state.FactoidState)
CBT := factoidState0.GetCoinbaseTransaction(nextBlock, state0.GetLeaderTimestamp())
oldCBDelay := constants.COINBASE_DECLARATION
if oldCBDelay != 10 {
t.Fatalf("constants.COINBASE_DECLARATION = %d expect 10\n", constants.COINBASE_DECLARATION)
}
if len(CBT.GetOutputs()) != 1 {
t.Fatalf("Expected first payout at block %d\n", nextBlock)
} else {
fmt.Println("Got first payout")
}

fmt.Println("Wait till activation height")
WaitForBlock(state0, 25)
if constants.COINBASE_DECLARATION != 20 {
t.Fatalf("constants.COINBASE_DECLARATION = %d expect 140\n", constants.COINBASE_DECLARATION)
}

nextBlock += oldCBDelay + 1
fmt.Println("Wait till second grant should payout if the activation fails")
WaitForBlock(state0, int(nextBlock+1)) // next old payout passed activation (should not be paid)
CBT = factoidState0.GetCoinbaseTransaction(nextBlock, state0.GetLeaderTimestamp())
if len(CBT.GetOutputs()) != 0 {
t.Fatalf("because the payout delay changed there is no payout at block %d\n", nextBlock)
}

nextBlock += constants.COINBASE_DECLARATION - oldCBDelay + 1
fmt.Println("Wait till second grant should payout with the new activation height")
WaitForBlock(state0, int(nextBlock+1)) // next payout passed new activation (should be paid)
CBT = factoidState0.GetCoinbaseTransaction(nextBlock, state0.GetLeaderTimestamp())
if len(CBT.GetOutputs()) != 0 {
t.Fatalf("Expected first payout at block %d\n", nextBlock)
}

WaitForAllNodes(state0)
CheckAuthoritySet(1, 1, t) // check the authority set is as expected
t.Log("Shutting down the network")
for _, fn := range GetFnodes() {
fn.State.ShutdownChan <- 1
}
}

// Cheap tests for developing binary search commits algorithm

func TestPass(t *testing.T) {
Expand Down
12 changes: 6 additions & 6 deletions engine/loadcreate.go
Expand Up @@ -24,19 +24,18 @@ import (
)

type LoadGenerator struct {
State *state.State // Where we get balances
ECKey *primitives.PrivateKey // Entry Credit private key
ToSend int // How much to send
PerSecond atomic.AtomicInt // How much per second
stop chan bool // Stop the go routine
running atomic.AtomicBool // We are running
tight atomic.AtomicBool // Only allocate ECs as needed (more EC purchases)
txoffset int64 // Offset to be added to the timestamp of created tx to test time limits.
}

// NewLoadGenerator makes a new load generator. The state is used for funding the transaction
func NewLoadGenerator(s *state.State) *LoadGenerator {
lg := new(LoadGenerator)
lg.State = s
lg.ECKey, _ = primitives.NewPrivateKeyFromHex(ecSec)
lg.stop = make(chan bool, 5)

Expand Down Expand Up @@ -123,7 +122,8 @@ func (lg *LoadGenerator) NewRevealEntry(entry *entryBlock.Entry) *messages.Revea

var cnt int

func GetECs(s *state.State, tight bool, c int) {
func (lg *LoadGenerator) GetECs(tight bool, c int) {
s := fnodes[wsapiNode].State
outEC, _ := primitives.HexToHash("c23ae8eec2beb181a0da926bd2344e988149fbe839fbc7489f2096e7d6110243")
outAdd := factoid.NewAddress(outEC.Bytes())
ecBal := s.GetE(true, outAdd.Fixed())
Expand All @@ -145,7 +145,7 @@ func GetECs(s *state.State, tight bool, c int) {

os.Stderr.WriteString(fmt.Sprintf("%d purchases, buying %d and balance is %d \n", cnt, c, ecBal))

FundWallet(s, uint64(c)*ecPrice)
FundWalletTOFF(s, lg.txoffset, uint64(c)*ecPrice)

}

Expand All @@ -159,7 +159,7 @@ func (lg *LoadGenerator) NewCommitChain(entry *entryBlock.Entry) *messages.Commi
commit.Credits, _ = util.EntryCost(data)

commit.Credits += 10
GetECs(lg.State, lg.tight.Load(), int(commit.Credits))
lg.GetECs(lg.tight.Load(), int(commit.Credits))

commit.EntryHash = entry.GetHash()
var b6 primitives.ByteSlice6
Expand Down Expand Up @@ -188,7 +188,7 @@ func (lg *LoadGenerator) NewCommitEntry(entry *entryBlock.Entry) *messages.Commi
data, _ := entry.MarshalBinary()

commit.Credits, _ = util.EntryCost(data)
GetECs(lg.State, lg.tight.Load(), int(commit.Credits))
lg.GetECs(lg.tight.Load(), int(commit.Credits))

commit.EntryHash = entry.GetHash()
var b6 primitives.ByteSlice6
Expand Down
14 changes: 13 additions & 1 deletion engine/simAuthorities.go
Expand Up @@ -117,7 +117,15 @@ func copyOver(st *state.State) {
}
}

// FundWallet()
// Entry Point for no time offset on the transaction.
func FundWallet(st *state.State, amt uint64) (error, string) {
return FundWalletTOFF(st, 0, amt)
}

// FundWalletTOFF()
// Entry Point where test code allows the transaction to have a time offset from the current time.
func FundWalletTOFF(st *state.State, timeOffsetInMilliseconds int64, amt uint64) (error, string) {
inSec, _ := primitives.HexToHash("FB3B471B1DCDADFEB856BD0B02D8BF49ACE0EDD372A3D9F2A95B78EC12A324D6") // private key or FCT Source
outEC, _ := primitives.HexToHash("c23ae8eec2beb181a0da926bd2344e988149fbe839fbc7489f2096e7d6110243") // EC address

Expand All @@ -141,7 +149,11 @@ func FundWallet(st *state.State, amt uint64) (error, string) {

trans.AddRCD(rcd)
trans.AddAuthorization(rcd)
trans.SetTimestamp(primitives.NewTimestampNow())

// So what we are going to do is get the current time in ms, add to it the offset provided (usually zero, except
// for tests)
trans.SetTimestamp(primitives.NewTimestampFromMilliseconds(
uint64(primitives.NewTimestampNow().GetTimeMilli() + timeOffsetInMilliseconds)))

fee, err := trans.CalculateFee(st.GetFactoshisPerEC())
if err != nil {
Expand Down

0 comments on commit 6c6a9a1

Please sign in to comment.