Skip to content

Commit

Permalink
Merge pull request #20 from make-software/feature/support_block_syste…
Browse files Browse the repository at this point in the history
…m_proposer

Add support for the system block proposer
  • Loading branch information
koltsov-iv authored Jul 18, 2023
2 parents 1987a8e + f764f8e commit 4697905
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 1 deletion.
82 changes: 82 additions & 0 deletions tests/data/block/block_switch_system_proposer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"hash": "b287dd3ae44e57e944bf357d50f8c09fa6a58cb3cdccebb94febf2733d243d92",
"header": {
"parent_hash": "3702837e19058988f12260689dc6cf6adf3f31d06d4b34109a4a4fda44c23e08",
"state_root_hash": "05294c6b79095e72c24544852b1d678350554e16bbd430adab4dd0b5be0bccfe",
"body_hash": "5187b7a8021bf4f2c004ea3a54cfece1754f11c7624d2363c7f4cf4fddd1441e",
"random_bit": false,
"accumulated_seed": "abd4677d96e41ffc598761b58e93ebd5ab91affcc1b7d09e4b3bc63044fcced0",
"era_end": {
"era_report": {
"equivocators": [],
"rewards": [],
"inactive_validators": []
},
"next_era_validator_weights": [
{
"validator": "0115c9b40c06ff99b0cbadf1140b061b5dbf92103e66a6330fbcc7768f5219c1ce",
"weight": "295643652543863089"
},
{
"validator": "011b19ef983c039a2a335f2f35199bf8cad5ba2c583bd709748feb76f24ffb1bab",
"weight": "294564238999375236"
},
{
"validator": "011d86fcc3e438fcb47d4d9af77e9db97ca1c322c3e87d5a4ea6f3386b9ddcd6ed",
"weight": "294159738231573499"
},
{
"validator": "017234b285929170324e1051ccd887dc08adf049650ecf5d383985b0b0048ab39b",
"weight": "284471020019645189"
},
{
"validator": "017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c",
"weight": "294691173297447085"
},
{
"validator": "019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d",
"weight": "294679465132340585"
},
{
"validator": "01cb8e121682e087058610828a6f75e8ca504321508243c7518a4047d3284f2f3c",
"weight": "292948235437478173"
}
]
},
"timestamp": "2023-05-11T18:24:49.664Z",
"era_id": 9128,
"height": 1749608,
"protocol_version": "1.5.0"
},
"body": {
"proposer": "00",
"deploy_hashes": [],
"transfer_hashes": []
},
"proofs": [
{
"public_key": "011b19ef983c039a2a335f2f35199bf8cad5ba2c583bd709748feb76f24ffb1bab",
"signature": "01f6bfd939b7797f1be4f16e597a115f38687745ad32dcd3402ef38c750b6abfb50c0918cb1e57ea25b174fa632a1f62000cc727aff703eb17c3b5f976ca17f304"
},
{
"public_key": "011d86fcc3e438fcb47d4d9af77e9db97ca1c322c3e87d5a4ea6f3386b9ddcd6ed",
"signature": "019a011ea3f5d5d5446748ae58c40f5d6f0f255dfd1a75161d84b2c280f79a523756fee665401617e765651c32dd4a10598a15e71ae08ee3b48479033db4d2f30c"
},
{
"public_key": "017234b285929170324e1051ccd887dc08adf049650ecf5d383985b0b0048ab39b",
"signature": "017664b8c0b2cdba2261ae1af6f213ad0f8812799e2fbd840b668799221c4f0a5951aa7f9e1828bbbe16fc51e1e94e5c1a935f31c3781feef7a36500c660774601"
},
{
"public_key": "017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c",
"signature": "01e921e323ce23a1e7cf9453e0efdc23c0ee9001d28eb8124da73e85f0fc5fe3f6cd22008aa7053cf5c8c20813230f414238b95032f98c0ce6e09e643dfc011009"
},
{
"public_key": "019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d",
"signature": "01fcdf5f457fbe2868e03a15bee5af2c15fa4d8fce05888fde0c7b080ffda418511c380a71c500097ff840e0e68ff0976e4c0ec74fd318554e8557a4d5b6042c06"
},
{
"public_key": "01cb8e121682e087058610828a6f75e8ca504321508243c7518a4047d3284f2f3c",
"signature": "014bee8a716df01a593a535ebf2dee20da400a99dffe1d56e07f2dfa5f947d4d5003e4ee51289e389998e4c9b45efe00a1193d7db79a67dd824d489ddf16ad820e"
}
]
}
52 changes: 52 additions & 0 deletions tests/types/block_proposer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package types

import (
"encoding/hex"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/make-software/casper-go-sdk/types"
)

func Test_BlockProposer_Scan_System(t *testing.T) {
res := &types.Proposer{}
hexData, err := hex.DecodeString("00")
require.NoError(t, err)
err = res.Scan(hexData)
require.NoError(t, err)
assert.True(t, res.IsSystem())
}

func Test_BlockProposer_Scan_PublicKey(t *testing.T) {
res := &types.Proposer{}
hexData, err := hex.DecodeString("015a372b0e230bf9393e2df0b3de857bb0e17370884bb881f840cb1482bb2922cf")
require.NoError(t, err)
err = res.Scan(hexData)
require.NoError(t, err)
assert.False(t, res.IsSystem())
publicKey, err := res.PublicKey()
require.NoError(t, err)
assert.Equal(t, "015a372b0e230bf9393e2df0b3de857bb0e17370884bb881f840cb1482bb2922cf", publicKey.ToHex())
}

func Test_BlockProposer_InvalidData(t *testing.T) {
res := &types.Proposer{}
err := res.Scan("0")
assert.Error(t, err)
}

func Test_BlockProposer_Value_System(t *testing.T) {
res, err := types.NewProposer("00")
require.NoError(t, err)
assert.True(t, res.IsSystem())
}

func Test_BlockProposer_Value_PublicKey(t *testing.T) {
res, err := types.NewProposer("015a372b0e230bf9393e2df0b3de857bb0e17370884bb881f840cb1482bb2922cf")
require.NoError(t, err)
pubKey, err := res.PublicKey()
require.NoError(t, err)
assert.Equal(t, "015a372b0e230bf9393e2df0b3de857bb0e17370884bb881f840cb1482bb2922cf", pubKey.ToHex())
}
43 changes: 43 additions & 0 deletions tests/types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/make-software/casper-go-sdk/types"
)
Expand Down Expand Up @@ -35,3 +36,45 @@ func Test_BlockSwitch_MarshalUnmarshal_ShouldReturnSameResult(t *testing.T) {
assert.NoError(t, err)
assert.JSONEq(t, string(fixture), string(result))
}

func Test_BlockSwitch_WithSystemProposal_MarshalUnmarshal_ShouldReturnSameResult(t *testing.T) {
fixture, err := os.ReadFile("../data/block/block_switch_system_proposer.json")
assert.NoError(t, err)

var block types.Block
err = json.Unmarshal(fixture, &block)
assert.NoError(t, err)

result, err := json.Marshal(block)
assert.NoError(t, err)
assert.JSONEq(t, string(fixture), string(result))
}

func Test_BlockSwitch_WithSystemProposal_IsSystem_ShouldReturnTrue(t *testing.T) {
fixture, err := os.ReadFile("../data/block/block_switch_system_proposer.json")
assert.NoError(t, err)

var block types.Block
err = json.Unmarshal(fixture, &block)
require.NoError(t, err)
assert.True(t, block.Body.Proposer.IsSystem())
_, err = block.Body.Proposer.PublicKey()
assert.Error(t, err)
pubKey := block.Body.Proposer.PublicKeyOptional()
assert.Nil(t, pubKey)
}

func Test_BlockProposal_PublicKey_ShouldWorkForNormalBlock(t *testing.T) {
fixture, err := os.ReadFile("../data/block/block_example.json")
assert.NoError(t, err)

var block types.Block
err = json.Unmarshal(fixture, &block)
require.NoError(t, err)
assert.False(t, block.Body.Proposer.IsSystem())
result, err := block.Body.Proposer.PublicKey()
assert.NoError(t, err)
assert.Equal(t, "019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d", result.String())
pubKey := block.Body.Proposer.PublicKeyOptional()
assert.Equal(t, "019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d", pubKey.String())
}
2 changes: 1 addition & 1 deletion types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type BlockBody struct {
// List of `Deploy` hashes included in the block
DeployHashes []key.Hash `json:"deploy_hashes"`
// Public key of the validator that proposed the block
Proposer keypair.PublicKey `json:"proposer"`
Proposer Proposer `json:"proposer"`
// List of `TransferHash` hashes included in the block
TransferHashes []key.Hash `json:"transfer_hashes"`
}
Expand Down
88 changes: 88 additions & 0 deletions types/block_proposer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package types

import (
"database/sql/driver"
"encoding/hex"
"encoding/json"
"errors"

"github.com/make-software/casper-go-sdk/types/keypair"
)

type Proposer struct {
isSystem bool
publicKey *keypair.PublicKey
}

func NewProposer(src string) (Proposer, error) {
var result Proposer
if src == "00" {
result.isSystem = true
return result, nil
}
pubKey, err := keypair.NewPublicKey(src)
if err != nil {
return result, err
}
result.publicKey = &pubKey
return result, nil
}

func (p Proposer) IsSystem() bool {
return p.isSystem
}

func (p Proposer) PublicKey() (keypair.PublicKey, error) {
if p.IsSystem() {
return keypair.PublicKey{}, errors.New("system proposer doesn't have a PublicKey")
}
return *p.publicKey, nil
}

func (p Proposer) PublicKeyOptional() *keypair.PublicKey {
return p.publicKey
}

func (p Proposer) MarshalJSON() ([]byte, error) {
if p.isSystem {
return []byte(`"00"`), nil
}
return json.Marshal(p.publicKey)
}

func (p *Proposer) UnmarshalJSON(bytes []byte) error {
var str string
err := json.Unmarshal(bytes, &str)
if err != nil {
return err
}
*p, err = NewProposer(str)
if err != nil {
return err
}
return nil
}

func (p *Proposer) Scan(value any) error {
b, ok := value.([]byte)
if !ok {
return errors.New("invalid scan value type")
}
if hex.EncodeToString(b) == "00" {
p.isSystem = true
return nil
}
var pubKey keypair.PublicKey
if err := pubKey.Scan(value); err != nil {
return err
}
p.publicKey = &pubKey
return nil
}

func (p Proposer) Value() (driver.Value, error) {
if p.isSystem {
return hex.DecodeString("00")
}
return p.publicKey.Value()
}

0 comments on commit 4697905

Please sign in to comment.