// New creates a transaction pool that is ready to receive transactions. func New(cs modules.ConsensusSet, g modules.Gateway, persistDir string) (*TransactionPool, error) { // Check that the input modules are non-nil. if cs == nil { return nil, errNilCS } if g == nil { return nil, errNilGateway } // Initialize a transaction pool. tp := &TransactionPool{ consensusSet: cs, gateway: g, knownObjects: make(map[ObjectID]TransactionSetID), transactionSets: make(map[TransactionSetID][]types.Transaction), transactionSetDiffs: make(map[TransactionSetID]modules.ConsensusChange), persistDir: persistDir, } // Open the tpool database. err := tp.initPersist() if err != nil { return nil, err } // Register RPCs g.RegisterRPC("RelayTransactionSet", tp.relayTransactionSet) return tp, nil }
// New creates a transaction pool that is ready to receive transactions. func New(cs modules.ConsensusSet, g modules.Gateway) (*TransactionPool, error) { // Check that the input modules are non-nil. if cs == nil { return nil, errNilCS } if g == nil { return nil, errNilGateway } // Initialize a transaction pool. tp := &TransactionPool{ consensusSet: cs, gateway: g, knownObjects: make(map[ObjectID]TransactionSetID), transactionSets: make(map[TransactionSetID][]types.Transaction), transactionSetDiffs: make(map[TransactionSetID]modules.ConsensusChange), // The consensus change index is intialized to '-1', which indicates // that no consensus changes have been sent yet. The first consensus // change will then have an index of '0'. consensusChangeIndex: -1, mu: sync.New(modules.SafeMutexDelay, 5), } // Register RPCs g.RegisterRPC("RelayTransactionSet", tp.RelayTransactionSet) g.RegisterRPC("RelayTransaction", tp.RelayTransaction) // COMPAT v0.3.3.3 // Subscribe the transaction pool to the consensus set. cs.ConsensusSetSubscribe(tp) return tp, nil }
// New returns a new ConsensusSet, containing at least the genesis block. If // there is an existing block database present in the persist directory, it // will be loaded. func New(gateway modules.Gateway, persistDir string) (*ConsensusSet, error) { // Check for nil dependencies. if gateway == nil { return nil, errNilGateway } // Create the genesis block. genesisBlock := types.Block{ Timestamp: types.GenesisTimestamp, Transactions: []types.Transaction{ {SiafundOutputs: types.GenesisSiafundAllocation}, }, } // Create the ConsensusSet object. cs := &ConsensusSet{ gateway: gateway, blockRoot: processedBlock{ Block: genesisBlock, ChildTarget: types.RootTarget, Depth: types.RootDepth, DiffsGenerated: true, }, dosBlocks: make(map[types.BlockID]struct{}), marshaler: encoding.StdGenericMarshaler{}, blockRuleHelper: stdBlockRuleHelper{}, blockValidator: NewBlockValidator(), persistDir: persistDir, } // Create the diffs for the genesis siafund outputs. for i, siafundOutput := range genesisBlock.Transactions[0].SiafundOutputs { sfid := genesisBlock.Transactions[0].SiafundOutputID(uint64(i)) sfod := modules.SiafundOutputDiff{ Direction: modules.DiffApply, ID: sfid, SiafundOutput: siafundOutput, } cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod) } // Initialize the consensus persistence structures. err := cs.initPersist() if err != nil { return nil, err } // Register RPCs gateway.RegisterRPC("SendBlocks", cs.sendBlocks) gateway.RegisterRPC("RelayBlock", cs.relayBlock) gateway.RegisterConnectCall("SendBlocks", cs.threadedReceiveBlocks) return cs, nil }
// New creates a transaction pool that is ready to receive transactions. func New(cs modules.ConsensusSet, g modules.Gateway) (tp *TransactionPool, err error) { // Check that the input modules are non-nil. if cs == nil { err = errors.New("transaction pool cannot use a nil state") return } if g == nil { err = errors.New("transaction pool cannot use a nil gateway") return } // Initialize a transaction pool. tp = &TransactionPool{ consensusSet: cs, gateway: g, transactions: make(map[crypto.Hash]struct{}), siacoinOutputs: make(map[types.SiacoinOutputID]types.SiacoinOutput), fileContracts: make(map[types.FileContractID]types.FileContract), siafundOutputs: make(map[types.SiafundOutputID]types.SiafundOutput), referenceSiacoinOutputs: make(map[types.SiacoinOutputID]types.SiacoinOutput), referenceFileContracts: make(map[types.FileContractID]types.FileContract), referenceSiafundOutputs: make(map[types.SiafundOutputID]types.SiafundOutput), mu: sync.New(modules.SafeMutexDelay, 1), } // Register RPCs g.RegisterRPC("RelayTransaction", tp.RelayTransaction) // Subscribe the transaction pool to the consensus set. cs.ConsensusSetSubscribe(tp) return }
// New creates a transaction pool that is ready to receive transactions. func New(cs modules.ConsensusSet, g modules.Gateway) (*TransactionPool, error) { // Check that the input modules are non-nil. if cs == nil { return nil, errNilCS } if g == nil { return nil, errNilGateway } // Initialize a transaction pool. tp := &TransactionPool{ consensusSet: cs, gateway: g, knownObjects: make(map[ObjectID]TransactionSetID), transactionSets: make(map[TransactionSetID][]types.Transaction), transactionSetDiffs: make(map[TransactionSetID]modules.ConsensusChange), // The consensus change index is intialized to '-1', which indicates // that no consensus changes have been sent yet. The first consensus // change will then have an index of '0'. consensusChangeIndex: -1, } // Register RPCs // TODO: rename RelayTransactionSet so that the conflicting RPC // RelayTransaction calls v0.4.6 clients and earlier are ignored. g.RegisterRPC("RelayTransactionSet", tp.relayTransactionSet) // Subscribe the transaction pool to the consensus set. err := cs.ConsensusSetPersistentSubscribe(tp, modules.ConsensusChangeID{}) if err != nil { return nil, errors.New("transactionpool subscription failed: " + err.Error()) } return tp, nil }
// New returns a new State, containing at least the genesis block. If there is // an existing block database present in saveDir, it will be loaded. Otherwise, // a new database will be created. func New(gateway modules.Gateway, saveDir string) (*State, error) { if gateway == nil { return nil, ErrNilGateway } // Create the State object. cs := &State{ blockMap: make(map[types.BlockID]*blockNode), dosBlocks: make(map[types.BlockID]struct{}), currentPath: make([]types.BlockID, 1), siacoinOutputs: make(map[types.SiacoinOutputID]types.SiacoinOutput), fileContracts: make(map[types.FileContractID]types.FileContract), siafundOutputs: make(map[types.SiafundOutputID]types.SiafundOutput), delayedSiacoinOutputs: make(map[types.BlockHeight]map[types.SiacoinOutputID]types.SiacoinOutput), gateway: gateway, mu: sync.New(modules.SafeMutexDelay, 1), } // Create the genesis block and add it as the BlockRoot. genesisBlock := types.Block{ Timestamp: types.GenesisTimestamp, Transactions: []types.Transaction{ {SiafundOutputs: types.GenesisSiafundAllocation}, }, } cs.blockRoot = &blockNode{ block: genesisBlock, childTarget: types.RootTarget, depth: types.RootDepth, diffsGenerated: true, } cs.blockMap[genesisBlock.ID()] = cs.blockRoot // Fill out the consensus information for the genesis block. cs.currentPath[0] = genesisBlock.ID() cs.siacoinOutputs[genesisBlock.MinerPayoutID(0)] = types.SiacoinOutput{ Value: types.CalculateCoinbase(0), UnlockHash: types.ZeroUnlockHash, } // Allocate the Siafund addresses by putting them all in a big transaction // and applying the diffs. for i, siafundOutput := range genesisBlock.Transactions[0].SiafundOutputs { sfid := genesisBlock.Transactions[0].SiafundOutputID(i) sfod := modules.SiafundOutputDiff{ Direction: modules.DiffApply, ID: sfid, SiafundOutput: siafundOutput, } cs.commitSiafundOutputDiff(sfod, modules.DiffApply) cs.blockRoot.siafundOutputDiffs = append(cs.blockRoot.siafundOutputDiffs, sfod) } // Send out genesis block update. cs.updateSubscribers(nil, []*blockNode{cs.blockRoot}) // Create the consensus directory. err := os.MkdirAll(saveDir, 0700) if err != nil { return nil, err } // During short tests, use an in-memory database. if build.Release == "testing" && testing.Short() { cs.db = persist.NilDB } else { // Otherwise, try to load an existing database from disk. err = cs.load(saveDir) if err != nil { return nil, err } } // Register RPCs gateway.RegisterRPC("SendBlocks", cs.sendBlocks) gateway.RegisterRPC("RelayBlock", cs.RelayBlock) gateway.RegisterConnectCall("SendBlocks", cs.receiveBlocks) // Spawn resynchronize loop. go cs.threadedResynchronize() return cs, nil }
// New returns a new ConsensusSet, containing at least the genesis block. If // there is an existing block database present in the persist directory, it // will be loaded. func New(gateway modules.Gateway, bootstrap bool, persistDir string) (*ConsensusSet, error) { // Check for nil dependencies. if gateway == nil { return nil, errNilGateway } // Create the ConsensusSet object. cs := &ConsensusSet{ gateway: gateway, blockRoot: processedBlock{ Block: types.GenesisBlock, ChildTarget: types.RootTarget, Depth: types.RootDepth, DiffsGenerated: true, }, dosBlocks: make(map[types.BlockID]struct{}), marshaler: encoding.StdGenericMarshaler{}, blockRuleHelper: stdBlockRuleHelper{}, blockValidator: NewBlockValidator(), persistDir: persistDir, } // Create the diffs for the genesis siafund outputs. for i, siafundOutput := range types.GenesisBlock.Transactions[0].SiafundOutputs { sfid := types.GenesisBlock.Transactions[0].SiafundOutputID(uint64(i)) sfod := modules.SiafundOutputDiff{ Direction: modules.DiffApply, ID: sfid, SiafundOutput: siafundOutput, } cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod) } // Initialize the consensus persistence structures. err := cs.initPersist() if err != nil { return nil, err } go func() { // Sync with the network. Don't sync if we are testing because // typically we don't have any mock peers to synchronize with in // testing. if bootstrap { // We are in a virgin goroutine right now, so calling the threaded // function without a goroutine is okay. err = cs.threadedInitialBlockchainDownload() if err != nil { return } } // threadedInitialBlockchainDownload will release the threadgroup 'Add' // it was holding, so another needs to be grabbed to finish off this // goroutine. err = cs.tg.Add() if err != nil { return } defer cs.tg.Done() // Register RPCs gateway.RegisterRPC("SendBlocks", cs.rpcSendBlocks) gateway.RegisterRPC("RelayBlock", cs.rpcRelayBlock) // COMPATv0.5.1 gateway.RegisterRPC("RelayHeader", cs.threadedRPCRelayHeader) gateway.RegisterRPC("SendBlk", cs.rpcSendBlk) gateway.RegisterConnectCall("SendBlocks", cs.threadedReceiveBlocks) cs.tg.OnStop(func() { cs.gateway.UnregisterRPC("SendBlocks") cs.gateway.UnregisterRPC("RelayBlock") cs.gateway.UnregisterRPC("RelayHeader") cs.gateway.UnregisterRPC("SendBlk") cs.gateway.UnregisterConnectCall("SendBlocks") }) // Mark that we are synced with the network. cs.mu.Lock() cs.synced = true cs.mu.Unlock() }() return cs, nil }
// New returns a new ConsensusSet, containing at least the genesis block. If // there is an existing block database present in saveDir, it will be loaded. // Otherwise, a new database will be created. func New(gateway modules.Gateway, saveDir string) (*ConsensusSet, error) { if gateway == nil { return nil, ErrNilGateway } // Create the genesis block. genesisBlock := types.Block{ Timestamp: types.GenesisTimestamp, Transactions: []types.Transaction{ {SiafundOutputs: types.GenesisSiafundAllocation}, }, } // Create the ConsensusSet object. cs := &ConsensusSet{ gateway: gateway, blockRoot: processedBlock{ Block: genesisBlock, ChildTarget: types.RootTarget, Depth: types.RootDepth, DiffsGenerated: true, }, dosBlocks: make(map[types.BlockID]struct{}), mu: sync.New(modules.SafeMutexDelay, 1), } // Allocate the Siafund addresses by putting them all in a big transaction inside the genesis block for i, siafundOutput := range genesisBlock.Transactions[0].SiafundOutputs { sfid := genesisBlock.Transactions[0].SiafundOutputID(i) sfod := modules.SiafundOutputDiff{ Direction: modules.DiffApply, ID: sfid, SiafundOutput: siafundOutput, } cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod) } // Create the consensus directory. err := os.MkdirAll(saveDir, 0700) if err != nil { return nil, err } // Try to load an existing database from disk. err = cs.load(saveDir) if err != nil { return nil, err } // Send the genesis block to subscribers. cs.updateSubscribers(nil, []*processedBlock{&cs.blockRoot}) // Send any blocks that were loaded from disk to subscribers. cs.loadDiffs() // Register RPCs gateway.RegisterRPC("SendBlocks", cs.sendBlocks) gateway.RegisterRPC("RelayBlock", cs.RelayBlock) gateway.RegisterConnectCall("SendBlocks", cs.receiveBlocks) return cs, nil }
// New returns a new ConsensusSet, containing at least the genesis block. If // there is an existing block database present in the persist directory, it // will be loaded. func New(gateway modules.Gateway, persistDir string) (*ConsensusSet, error) { // Check for nil dependencies. if gateway == nil { return nil, errNilGateway } // Create the ConsensusSet object. cs := &ConsensusSet{ gateway: gateway, blockRoot: processedBlock{ Block: types.GenesisBlock, ChildTarget: types.RootTarget, Depth: types.RootDepth, DiffsGenerated: true, }, dosBlocks: make(map[types.BlockID]struct{}), marshaler: encoding.StdGenericMarshaler{}, blockRuleHelper: stdBlockRuleHelper{}, blockValidator: NewBlockValidator(), persistDir: persistDir, } // Create the diffs for the genesis siafund outputs. for i, siafundOutput := range types.GenesisBlock.Transactions[0].SiafundOutputs { sfid := types.GenesisBlock.Transactions[0].SiafundOutputID(uint64(i)) sfod := modules.SiafundOutputDiff{ Direction: modules.DiffApply, ID: sfid, SiafundOutput: siafundOutput, } cs.blockRoot.SiafundOutputDiffs = append(cs.blockRoot.SiafundOutputDiffs, sfod) } // Initialize the consensus persistence structures. err := cs.initPersist() if err != nil { return nil, err } go func() { // Sync with the network. Don't sync if we are testing because typically we // don't have any mock peers to synchronize with in testing. // TODO: figure out a better way to conditionally do IBD. Otherwise this block will never be tested. if build.Release != "testing" { cs.threadedInitialBlockchainDownload() } // Register RPCs gateway.RegisterRPC("SendBlocks", cs.rpcSendBlocks) gateway.RegisterRPC("RelayBlock", cs.rpcRelayBlock) // COMPATv0.5.1 gateway.RegisterRPC("RelayHeader", cs.rpcRelayHeader) gateway.RegisterRPC("SendBlk", cs.rpcSendBlk) gateway.RegisterConnectCall("SendBlocks", cs.threadedReceiveBlocks) // Mark that we are synced with the network. cs.mu.Lock() cs.synced = true cs.mu.Unlock() }() return cs, nil }