I have always struggled keeping go modules neatly separated and avoiding cyclic dependencies.
Right now I have code like this:
package chain
type Block struct{
Content []byte
Number int
}
var Chain []Block = make([]Block, 10)
func AddBlockToChain(block Block){
// do some checks
//...
// add to chain
Chain[block.Number] = block
}
func GetBlock(number int) Block {
// do some checks
// ...
// get from chain
return Chain[number]
}
To achieve consensus I need some extra info on the block. The info may be different depending on which consensus algorithm I use. I want the consensus algorithm to be interchangeable (e.g. by flag on start up).
It would be convenient to store the info as fields in the block, so that when I call GetBlock(3) or get a block from anywhere else I can not only access the block but also the info on what state of consensus this block is in at the moment.
On the other hand I wanted to keep data that is only relevant for a certain consensus algorithm separate from basic block data - maybe even in a separate package.
How should I design my program? Where should I keep data relevant for a certain consensus algorithm?
Some background info:
I am trying to build a block chain application from scratch. I have a "chain" module responsible for storing blocks of data and a "consensus" module responsible for creating consensus between multiple peers running an instance of my program on what that data is.