Consensus adjustements for hardfork, fix private key calculation from seed

This commit is contained in:
DataHoarder 2023-03-19 00:25:52 +01:00
parent f9fb96ef87
commit 28a417bccd
Signed by: DataHoarder
SSH key fingerprint: SHA256:EnPQOqPpbCa7nzalCEJY2sd9iPluFIBuJu2rDFalACI
8 changed files with 29 additions and 12 deletions

View file

@ -198,10 +198,10 @@ func (b *Block) HeaderBlob() []byte {
}
// SideChainHashingBlob Same as MarshalBinary but with nonce set to 0
func (b *Block) SideChainHashingBlob() (buf []byte, err error) {
func (b *Block) SideChainHashingBlob(zeroTemplateId bool) (buf []byte, err error) {
var txBuf []byte
if txBuf, err = b.Coinbase.SideChainHashingBlob(); err != nil {
if txBuf, err = b.Coinbase.SideChainHashingBlob(zeroTemplateId); err != nil {
return nil, err
}
buf = make([]byte, 0, 1+1+binary.MaxVarintLen64+types.HashSize+4+len(txBuf)+binary.MaxVarintLen64+types.HashSize*len(b.Transactions))

View file

@ -168,7 +168,7 @@ func (c *CoinbaseTransaction) OutputsBlob() ([]byte, error) {
return c.Outputs.MarshalBinary()
}
func (c *CoinbaseTransaction) SideChainHashingBlob() ([]byte, error) {
func (c *CoinbaseTransaction) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
buf := new(bytes.Buffer)
varIntBuf := make([]byte, binary.MaxVarintLen64)
@ -182,7 +182,7 @@ func (c *CoinbaseTransaction) SideChainHashingBlob() ([]byte, error) {
outputs, _ := c.Outputs.MarshalBinary()
_, _ = buf.Write(outputs)
txExtra, _ := c.Extra.SideChainHashingBlob()
txExtra, _ := c.Extra.SideChainHashingBlob(zeroTemplateId)
_, _ = buf.Write(varIntBuf[:binary.PutUvarint(varIntBuf, uint64(len(txExtra)))])
_, _ = buf.Write(txExtra)
_ = binary.Write(buf, binary.BigEndian, c.ExtraBaseRCT)

View file

@ -52,13 +52,13 @@ func (t *ExtraTags) MarshalBinary() ([]byte, error) {
return buf, nil
}
func (t *ExtraTags) SideChainHashingBlob() ([]byte, error) {
func (t *ExtraTags) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
if t == nil {
return nil, nil
}
buf := make([]byte, 0, types.HashSize*4)
for _, tag := range *t {
if b, err := tag.SideChainHashingBlob(); err != nil {
if b, err := tag.SideChainHashingBlob(zeroTemplateId); err != nil {
return nil, err
} else {
buf = append(buf, b...)
@ -109,13 +109,13 @@ func (t *ExtraTag) MarshalBinary() ([]byte, error) {
return buf, nil
}
func (t *ExtraTag) SideChainHashingBlob() ([]byte, error) {
func (t *ExtraTag) SideChainHashingBlob(zeroTemplateId bool) ([]byte, error) {
buf := make([]byte, 0, len(t.Data)+1+binary.MaxVarintLen64)
buf = append(buf, t.Tag)
if t.VarIntLength > 0 {
buf = binary.AppendUvarint(buf, t.VarIntLength)
}
if t.Tag == TxExtraTagMergeMining {
if zeroTemplateId && t.Tag == TxExtraTagMergeMining {
buf = append(buf, make([]byte, len(t.Data))...)
} else if t.Tag == TxExtraTagNonce {
b := make([]byte, len(t.Data))

View file

@ -9,7 +9,7 @@ import (
func CalculateTransactionPrivateKeySeed(main, side []byte) types.Hash {
return crypto.PooledKeccak256(
// domain
[]byte("tx_key_seed"), //TODO: check for null termination
[]byte("tx_key_seed"), []byte{0},
main,
side,
)

View file

@ -40,6 +40,8 @@ func (c *SideChain) saveBlock(block *PoolBlock) {
go func() {
c.server.Store(block)
return
//TODO: make this a worker with a queue?
if !block.Verified.Load() || block.Invalid.Load() {

View file

@ -153,7 +153,7 @@ func (c *Consensus) verify() bool {
func (c *Consensus) CalculateSideTemplateId(share *PoolBlock) types.Hash {
mainData, _ := share.Main.SideChainHashingBlob()
mainData, _ := share.Main.SideChainHashingBlob(true)
sideData, _ := share.Side.MarshalBinary(share.ShareVersion())
return c.CalculateSideChainIdFromBlobs(mainData, sideData)

View file

@ -525,7 +525,7 @@ func (b *PoolBlock) GetPrivateKeySeed() types.Hash {
func (b *PoolBlock) CalculateTransactionPrivateKeySeed() types.Hash {
if b.ShareVersion() > ShareVersion_V1 {
mainData, _ := b.Main.SideChainHashingBlob()
mainData, _ := b.Main.SideChainHashingBlob(false)
sideData, _ := b.Side.MarshalBinary(b.ShareVersion())
return p2poolcrypto.CalculateTransactionPrivateKeySeed(
mainData,

View file

@ -93,6 +93,12 @@ func (c *SideChain) PreprocessBlock(block *PoolBlock) (missingBlocks []types.Has
c.sidechainLock.RLock()
defer c.sidechainLock.RUnlock()
if block.ShareVersion() > ShareVersion_V1 && bytes.Compare(block.Side.CoinbasePrivateKey.AsSlice(), types.ZeroHash[:]) == 0 {
//Fill Private Key
kP := c.derivationCache.GetDeterministicTransactionKey(block.GetPrivateKeySeed(), block.Main.PreviousId)
block.Side.CoinbasePrivateKey = kP.PrivateKey.AsBytes()
}
if len(block.Main.Coinbase.Outputs) == 0 {
if outputs := c.getOutputs(block); outputs == nil {
return nil, errors.New("nil transaction outputs")
@ -235,7 +241,7 @@ func (c *SideChain) AddPoolBlockExternal(block *PoolBlock) (missingBlocks []type
if isHigher, err := block.IsProofHigherThanDifficultyWithError(c.getSeedByHeightFunc()); err != nil {
return nil, err
} else if !isHigher {
return nil, fmt.Errorf("not enough PoW for height = %d, mainchain height %d", block.Side.Height, block.Main.Coinbase.GenHeight)
return nil, fmt.Errorf("not enough PoW for id %s, height = %d, mainchain height %d", templateId.String(), block.Side.Height, block.Main.Coinbase.GenHeight)
}
}
@ -544,6 +550,15 @@ func (c *SideChain) verifyBlock(block *PoolBlock) (verification error, invalid e
txPrivateKeySlice := block.Side.CoinbasePrivateKey.AsSlice()
txPrivateKeyScalar := block.Side.CoinbasePrivateKey.AsScalar()
blob1, _ := block.Main.Coinbase.Outputs.MarshalBinary()
bouts := c.calculateOutputs(block)
blob2, _ := bouts.MarshalBinary()
if bytes.Compare(blob1, blob2) != 0 {
return nil, fmt.Errorf("invalid")
}
results := utils.SplitWork(-2, uint64(len(rewards)), func(workIndex uint64, workerIndex int) error {
out := block.Main.Coinbase.Outputs[workIndex]
if rewards[workIndex] != out.Reward {