stackitem: introduce Convertible interface

We have a lot of native contract types that are converted to stack items
before serialization, then deserialized as stack items and converted back to
regular structures. stackitem.Convertible allows to remove a lot of repetitive
io.Serializable code.

This also introduces to/from converter in testserdes which unfortunately
required to change util tests to avoid circular references.
This commit is contained in:
Roman Khimov 2021-07-17 18:37:33 +03:00
parent 2d993d0da5
commit aab18c3083
23 changed files with 223 additions and 339 deletions

View file

@ -361,24 +361,18 @@ func (bc *Blockchain) init() error {
if storedCS == nil {
return fmt.Errorf("native contract %s is not stored", md.Name)
}
w := io.NewBufBinWriter()
storedCS.EncodeBinary(w.BinWriter)
if w.Err != nil {
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, w.Err)
storedCSBytes, err := stackitem.SerializeConvertible(storedCS)
if err != nil {
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, err)
}
buff := w.Bytes()
storedCSBytes := make([]byte, len(buff))
copy(storedCSBytes, buff)
w.Reset()
autogenCS := &state.Contract{
ContractBase: md.ContractBase,
UpdateCounter: storedCS.UpdateCounter, // it can be restored only from the DB, so use the stored value.
}
autogenCS.EncodeBinary(w.BinWriter)
if w.Err != nil {
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, w.Err)
autogenCSBytes, err := stackitem.SerializeConvertible(autogenCS)
if err != nil {
return fmt.Errorf("failed to check native %s state against autogenerated one: %w", md.Name, err)
}
autogenCSBytes := w.Bytes()
if !bytes.Equal(storedCSBytes, autogenCSBytes) {
return fmt.Errorf("native %s: version mismatch (stored contract state differs from autogenerated one), "+
"try to resynchronize the node from the genesis", md.Name)