You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/10/22 11:47:28 UTC

ignite git commit: IGNITE-1651: Added version to portable object.

Repository: ignite
Updated Branches:
  refs/heads/ignite-1282 dedf283a5 -> d85fa945f


IGNITE-1651: Added version to portable object.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d85fa945
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d85fa945
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d85fa945

Branch: refs/heads/ignite-1282
Commit: d85fa945f7d8558bb22ac60a69cd8a3ea49c87cb
Parents: dedf283
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Thu Oct 22 12:48:11 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Thu Oct 22 12:48:11 2015 +0300

----------------------------------------------------------------------
 .../portable/GridPortableMarshaller.java        |  18 ++-
 .../portable/PortableClassDescriptor.java       |   1 +
 .../internal/portable/PortableObjectImpl.java   |   4 +-
 .../portable/PortableObjectOffheapImpl.java     |   4 +-
 .../internal/portable/PortableReaderExImpl.java |  12 +-
 .../ignite/internal/portable/PortableUtils.java |  23 +++-
 .../portable/builder/PortableBuilderImpl.java   |   7 ++
 .../portable/builder/PortableBuilderReader.java |   8 ++
 .../GridPortableMarshallerSelfTest.java         |  15 +--
 .../src/portable_reader_writer_test.cpp         | 119 ++++++++++---------
 .../ignite/impl/portable/portable_common.h      |  11 +-
 .../ignite/impl/portable/portable_reader_impl.h |  36 ++++--
 .../ignite/impl/portable/portable_writer_impl.h |   5 +-
 .../Impl/Portable/PortableBuilderImpl.cs        |  10 +-
 .../Impl/Portable/PortableReaderImpl.cs         |   9 +-
 .../Impl/Portable/PortableUserObject.cs         |   6 +-
 .../Impl/Portable/PortableUtils.cs              |  34 +++++-
 .../Impl/Portable/PortableWriterImpl.cs         |   9 +-
 .../Impl/Portable/PortablesImpl.cs              |   1 +
 19 files changed, 216 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java
index c7a9e6f..20e8693 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java
@@ -186,23 +186,29 @@ public class GridPortableMarshaller {
     /** */
     public static final int UNREGISTERED_TYPE_ID = 0;
 
+    /** Protocol version. */
+    public static final byte PROTO_VER = 1;
+
+    /** Protocol version position. */
+    public static final int PROTO_VER_POS = 1;
+
     /** */
-    public static final int TYPE_ID_POS = 2;
+    public static final int TYPE_ID_POS = 3;
 
     /** */
-    public static final int HASH_CODE_POS = 6;
+    public static final int HASH_CODE_POS = 7;
 
     /** */
-    public static final int TOTAL_LEN_POS = 10;
+    public static final int TOTAL_LEN_POS = 11;
 
     /** */
-    public static final byte RAW_DATA_OFF_POS = 14;
+    public static final byte RAW_DATA_OFF_POS = 15;
 
     /** */
-    public static final int CLS_NAME_POS = 18;
+    public static final int CLS_NAME_POS = 19;
 
     /** */
-    public static final byte DFLT_HDR_LEN = 18;
+    public static final byte DFLT_HDR_LEN = 19;
 
     /** */
     private final PortableContext ctx;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
index a2b4b74..05a7f13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
@@ -653,6 +653,7 @@ public class PortableClassDescriptor {
         int pos = writer.position();
 
         writer.doWriteByte(GridPortableMarshaller.OBJ);
+        writer.doWriteByte(GridPortableMarshaller.PROTO_VER);
         writer.doWriteBoolean(userType);
         writer.doWriteInt(registered ? typeId : GridPortableMarshaller.UNREGISTERED_TYPE_ID);
         writer.doWriteInt(obj instanceof CacheObjectImpl ? 0 : obj.hashCode());

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
index 47ff1ab..b156eda 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
@@ -219,7 +219,7 @@ public final class PortableObjectImpl extends PortableObjectEx implements Extern
 
     /** {@inheritDoc} */
     @Override public int typeId() {
-        return PRIM.readInt(arr, start + 2);
+        return PRIM.readInt(arr, start + GridPortableMarshaller.TYPE_ID_POS);
     }
 
     /** {@inheritDoc} */
@@ -286,7 +286,7 @@ public final class PortableObjectImpl extends PortableObjectEx implements Extern
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        return PRIM.readInt(arr, start + 6);
+        return PRIM.readInt(arr, start + GridPortableMarshaller.HASH_CODE_POS);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
index ba8ee83..0dc8612 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
@@ -87,7 +87,7 @@ public class PortableObjectOffheapImpl extends PortableObjectEx implements Exter
 
     /** {@inheritDoc} */
     @Override public int typeId() {
-        return UNSAFE.getInt(ptr + start + 2);
+        return UNSAFE.getInt(ptr + start + GridPortableMarshaller.TYPE_ID_POS);
     }
 
     /** {@inheritDoc} */
@@ -97,7 +97,7 @@ public class PortableObjectOffheapImpl extends PortableObjectEx implements Exter
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        return UNSAFE.getInt(ptr + start + 6);
+        return UNSAFE.getInt(ptr + start + GridPortableMarshaller.HASH_CODE_POS);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
index 4ad125a..015ed6c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderExImpl.java
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.util.GridEnumCache;
 import org.apache.ignite.internal.util.lang.GridMapEntry;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.portable.PortableMarshaller;
 import org.apache.ignite.portable.PortableException;
 import org.apache.ignite.portable.PortableInvalidClassException;
 import org.apache.ignite.portable.PortableObject;
@@ -197,6 +198,9 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
             // skip obj type byte
             rawOff++;
 
+        // Validate protocol version.
+        PortableUtils.checkProtocolVersion(doReadByte(true));
+
         // skip user flag
         rawOff += 1;
 
@@ -1737,6 +1741,8 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
                 return unmarshal(false);
 
             case OBJ:
+                PortableUtils.checkProtocolVersion(doReadByte(raw));
+
                 PortableObjectEx po;
 
                 if (detach) {
@@ -2143,6 +2149,8 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
 
                 assert typeId != UNREGISTERED_TYPE_ID;
 
+                PortableUtils.checkProtocolVersion(doReadByte(true));
+
                 boolean userType = doReadBoolean(true);
 
                 // Skip typeId and hash code.
@@ -2362,9 +2370,9 @@ public class PortableReaderExImpl implements PortableReader, PortableRawReaderEx
         boolean dateObj = in.readByte() == DATE;
 
         if (!dateObj) {
-            in.position(start + 2);
+            in.position(start + GridPortableMarshaller.TYPE_ID_POS);
 
-            int typeId = in.readInt(start + 2);
+            int typeId = in.readInt(start + GridPortableMarshaller.TYPE_ID_POS);
 
             return ctx.isUseTimestamp(typeId);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
index 7259cc9..10970a0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
@@ -17,6 +17,13 @@
 
 package org.apache.ignite.internal.portable;
 
+import org.apache.ignite.internal.portable.builder.PortableLazyValue;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.portable.PortableException;
+import org.apache.ignite.portable.PortableObject;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentHashMap8;
+
 import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.util.Collection;
@@ -33,11 +40,6 @@ import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentSkipListSet;
-import org.apache.ignite.internal.portable.builder.PortableLazyValue;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.portable.PortableObject;
-import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
 
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN_ARR;
@@ -64,6 +66,7 @@ import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT_ARR;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING;
@@ -466,4 +469,14 @@ public class PortableUtils {
 
         return U.newHashSet(set.size());
     }
+
+    /**
+     * Check protocol version.
+     *
+     * @param protoVer Protocol version.
+     */
+    public static void checkProtocolVersion(byte protoVer) {
+        if (PROTO_VER != protoVer)
+            throw new PortableException("Unsupported protocol version: " + protoVer);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
index b2e4c0d..00fc866 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
@@ -40,6 +40,8 @@ import org.apache.ignite.portable.*;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLS_NAME_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_CODE_POS;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.RAW_DATA_OFF_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.TOTAL_LEN_POS;
 import static org.apache.ignite.internal.portable.GridPortableMarshaller.TYPE_ID_POS;
@@ -137,6 +139,10 @@ public class PortableBuilderImpl implements PortableBuilder {
         this.reader = reader;
         this.start = start;
 
+        byte ver = reader.readByteAbsolute(start + PROTO_VER_POS);
+
+        PortableUtils.checkProtocolVersion(ver);
+
         int typeId = reader.readIntAbsolute(start + TYPE_ID_POS);
         ctx = reader.portableContext();
         hashCode = reader.readIntAbsolute(start + HASH_CODE_POS);
@@ -194,6 +200,7 @@ public class PortableBuilderImpl implements PortableBuilder {
      */
     void serializeTo(PortableWriterExImpl writer, PortableBuilderSerializer serializer) {
         writer.doWriteByte(GridPortableMarshaller.OBJ);
+        writer.doWriteByte(PROTO_VER);
         writer.doWriteBoolean(true);
         writer.doWriteInt(registeredType ? typeId : UNREGISTERED_TYPE_ID);
         writer.doWriteInt(hashCode);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
index 45355d7..31a3c11 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
@@ -124,6 +124,14 @@ class PortableBuilderReader {
 
     /**
      * @param pos Position in the source array.
+     * @return Read byte value.
+     */
+    public byte readByteAbsolute(int pos) {
+        return PRIM.readByte(arr, pos);
+    }
+
+    /**
+     * @param pos Position in the source array.
      * @return Read int value.
      */
     public int readIntAbsolute(int pos) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
index 21fc81c..7f1ca6b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java
@@ -747,8 +747,9 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         byte[] arr = new byte[20];
 
         arr[0] = 103;
+        arr[1] = 1;
 
-        U.intToBytes(Integer.reverseBytes(11111), arr, 2);
+        U.intToBytes(Integer.reverseBytes(11111), arr, 3);
 
         final PortableObject po = new PortableObjectImpl(initPortableContext(new PortableMarshaller()), arr, 0);
 
@@ -877,8 +878,8 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         PortableObject po1 = marshal(obj1, marsh);
 
         assertEquals(11111, po1.typeId());
-        assertEquals(22222, intFromPortable(po1, 18));
-        assertEquals(33333, intFromPortable(po1, 31));
+        assertEquals(22222, intFromPortable(po1, 19));
+        assertEquals(33333, intFromPortable(po1, 32));
 
         assertEquals(10, po1.<CustomMappedObject1>deserialize().val1);
         assertEquals("str", po1.<CustomMappedObject1>deserialize().val2);
@@ -936,8 +937,8 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         PortableObject po1 = marshal(obj1, marsh);
 
         assertEquals(11111, po1.typeId());
-        assertEquals(22222, intFromPortable(po1, 18));
-        assertEquals(33333, intFromPortable(po1, 31));
+        assertEquals(22222, intFromPortable(po1, 19));
+        assertEquals(33333, intFromPortable(po1, 32));
 
         assertEquals(10, po1.<CustomMappedObject1>deserialize().val1);
         assertEquals("str1", po1.<CustomMappedObject1>deserialize().val2);
@@ -947,8 +948,8 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest {
         PortableObject po2 = marshal(obj2, marsh);
 
         assertEquals(44444, po2.typeId());
-        assertEquals(55555, intFromPortable(po2, 18));
-        assertEquals(66666, intFromPortable(po2, 31));
+        assertEquals(55555, intFromPortable(po2, 19));
+        assertEquals(66666, intFromPortable(po2, 32));
 
         assertEquals(20, po2.<CustomMappedObject2>deserialize().val1);
         assertEquals("str2", po2.<CustomMappedObject2>deserialize().val2);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
index 0825ecc..1b7c319 100644
--- a/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
+++ b/modules/platforms/cpp/core-test/src/portable_reader_writer_test.cpp
@@ -41,7 +41,7 @@ void CheckPrimitive(T val)
     InteropUnpooledMemory mem(1024);
 
     InteropOutputStream out(&mem);
-    out.Position(18);
+    out.Position(19);
 
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
@@ -63,7 +63,7 @@ void CheckPrimitive(T val)
 
     InteropInputStream in(&mem);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
     PortableReader reader(&readerImpl);
@@ -101,7 +101,7 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
     PortableReader reader(&readerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     try
     {
@@ -125,17 +125,17 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
     out.Synchronize();
     in.Synchronize();
     
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == -1);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == -1);
 
     T arr1[2];
     arr1[0] = dflt;
     arr1[1] = dflt;
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == -1);
 
     BOOST_REQUIRE(arr1[0] == dflt);
@@ -146,68 +146,68 @@ void CheckPrimitiveArray(T dflt, T val1, T val2)
     arr2[0] = val1;
     arr2[1] = val2;
 
-    out.Position(18);
+    out.Position(19);
     
     WriteArray<T>(writer, fieldName, arr2, 0);
 
     out.Synchronize();
     in.Synchronize();
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 0);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 0);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 0);
     BOOST_REQUIRE(arr1[0] == dflt);
     BOOST_REQUIRE(arr1[1] == dflt);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 0);
     BOOST_REQUIRE(arr1[0] == dflt);
     BOOST_REQUIRE(arr1[1] == dflt);
 
     // 3. Partial array write.
-    out.Position(18);
+    out.Position(19);
     
     WriteArray<T>(writer, fieldName, arr2, 1);
 
     out.Synchronize();
     in.Synchronize();
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 1);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 1);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 0) == 1);
     BOOST_REQUIRE(arr1[0] == dflt);
     BOOST_REQUIRE(arr1[1] == dflt);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 1) == 1);
     BOOST_REQUIRE(arr1[0] == val1);
     BOOST_REQUIRE(arr1[1] == dflt);
     arr1[0] = dflt;
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, arr1, 2) == 1);
     BOOST_REQUIRE(arr1[0] == val1);
     BOOST_REQUIRE(arr1[1] == dflt);
     arr1[0] = dflt;
 
     // 4. Full array write.
-    out.Position(18);
+    out.Position(19);
     
     WriteArray<T>(writer, fieldName, arr2, 2);
 
     out.Synchronize();
     in.Synchronize();
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 0) == 2);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(ReadArray<T>(reader, fieldName, NULL, 2) == 2);
 
     try
@@ -410,7 +410,7 @@ void CheckCollectionEmpty(CollectionType* colType)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableCollectionWriter<PortableInner> colWriter = colType ?
         writer.WriteCollection<PortableInner>("field1", *colType) : writer.WriteCollection<PortableInner>("field1");
@@ -449,7 +449,7 @@ void CheckCollectionEmpty(CollectionType* colType)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -490,7 +490,7 @@ void CheckCollection(CollectionType* colType)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableCollectionWriter<PortableInner> colWriter = colType ?
         writer.WriteCollection<PortableInner>("field1", *colType) : writer.WriteCollection<PortableInner>("field1");
@@ -533,7 +533,7 @@ void CheckCollection(CollectionType* colType)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -635,7 +635,7 @@ void CheckMapEmpty(MapType* mapType)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableMapWriter<int8_t, PortableInner> mapWriter = mapType ?
         writer.WriteMap<int8_t, PortableInner>("field1", *mapType) : writer.WriteMap<int8_t, PortableInner>("field1");
@@ -674,7 +674,7 @@ void CheckMapEmpty(MapType* mapType)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -718,7 +718,7 @@ void CheckMap(MapType* mapType)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableMapWriter<int8_t, PortableInner> mapWriter = mapType ?
         writer.WriteMap<int8_t, PortableInner>("field1", *mapType) : writer.WriteMap<int8_t, PortableInner>("field1");
@@ -761,7 +761,7 @@ void CheckMap(MapType* mapType)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -916,7 +916,7 @@ BOOST_AUTO_TEST_CASE(TestGuidNull)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     try
     {
@@ -937,7 +937,7 @@ BOOST_AUTO_TEST_CASE(TestGuidNull)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 100, 100);
     PortableReader reader(&readerImpl);
     
-    in.Position(18);
+    in.Position(19);
 
     try
     {
@@ -965,7 +965,7 @@ BOOST_AUTO_TEST_CASE(TestString) {
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     const char* writeVal1 = "testtest";
     const char* writeVal2 = "test";
@@ -1016,7 +1016,7 @@ BOOST_AUTO_TEST_CASE(TestString) {
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     try
     {
@@ -1077,7 +1077,7 @@ BOOST_AUTO_TEST_CASE(TestStringArrayNull)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
@@ -1088,7 +1088,7 @@ BOOST_AUTO_TEST_CASE(TestStringArrayNull)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1133,7 +1133,7 @@ BOOST_AUTO_TEST_CASE(TestStringArrayEmpty)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableStringArrayWriter arrWriter = writer.WriteStringArray("field1");
     
@@ -1199,7 +1199,7 @@ BOOST_AUTO_TEST_CASE(TestStringArrayEmpty)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1248,7 +1248,7 @@ BOOST_AUTO_TEST_CASE(TestStringArray)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableStringArrayWriter arrWriter = writer.WriteStringArray("field1");
 
@@ -1320,7 +1320,7 @@ BOOST_AUTO_TEST_CASE(TestStringArray)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableStringArrayReader arrReader = reader.ReadStringArray("field1");
 
@@ -1416,7 +1416,7 @@ BOOST_AUTO_TEST_CASE(TestObject)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteObject("field1", writeVal1);
     writer.WriteObject("field2", writeVal2);
@@ -1428,7 +1428,7 @@ BOOST_AUTO_TEST_CASE(TestObject)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableInner readVal1 = reader.ReadObject<PortableInner>("field1");
     BOOST_REQUIRE(writeVal1.GetValue() == readVal1.GetValue());
@@ -1453,7 +1453,7 @@ BOOST_AUTO_TEST_CASE(TestNestedObject)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteObject("field1", writeVal1);
     writer.WriteObject("field2", writeVal2);
@@ -1465,7 +1465,7 @@ BOOST_AUTO_TEST_CASE(TestNestedObject)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableOuter readVal1 = reader.ReadObject<PortableOuter>("field1");
     BOOST_REQUIRE(writeVal1.GetValue() == readVal1.GetValue());
@@ -1490,7 +1490,7 @@ BOOST_AUTO_TEST_CASE(TestArrayNull)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
@@ -1501,7 +1501,7 @@ BOOST_AUTO_TEST_CASE(TestArrayNull)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1533,7 +1533,7 @@ BOOST_AUTO_TEST_CASE(TestArrayEmpty)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableArrayWriter<PortableInner> arrWriter = writer.WriteArray<PortableInner>("field1");
 
@@ -1571,7 +1571,7 @@ BOOST_AUTO_TEST_CASE(TestArrayEmpty)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1607,7 +1607,7 @@ BOOST_AUTO_TEST_CASE(TestArray)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableArrayWriter<PortableInner> arrWriter = writer.WriteArray<PortableInner>("field1");
 
@@ -1649,7 +1649,7 @@ BOOST_AUTO_TEST_CASE(TestArray)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableArrayReader<PortableInner> arrReader = reader.ReadArray<PortableInner>("field1");
 
@@ -1693,7 +1693,7 @@ BOOST_AUTO_TEST_CASE(TestCollectionNull)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
@@ -1704,7 +1704,7 @@ BOOST_AUTO_TEST_CASE(TestCollectionNull)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableCollectionReader<PortableInner> colReader = reader.ReadCollection<PortableInner>("field1");
 
@@ -1773,7 +1773,7 @@ BOOST_AUTO_TEST_CASE(TestMapNull)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     writer.WriteNull("field1");
     writer.WriteInt8("field2", 1);
@@ -1784,7 +1784,7 @@ BOOST_AUTO_TEST_CASE(TestMapNull)
     PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 1000);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableMapReader<int8_t, PortableInner> mapReader = reader.ReadMap<int8_t, PortableInner>("field1");
 
@@ -1844,7 +1844,7 @@ BOOST_AUTO_TEST_CASE(TestRawMode)
     PortableWriterImpl writerImpl(&out, &idRslvr, NULL, NULL);
     PortableWriter writer(&writerImpl);
 
-    out.Position(18);
+    out.Position(19);
 
     PortableRawWriter rawWriter = writer.RawWriter();
 
@@ -1866,10 +1866,10 @@ BOOST_AUTO_TEST_CASE(TestRawMode)
     out.Synchronize();
 
     InteropInputStream in(&mem);
-    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 18);
+    PortableReaderImpl readerImpl(&in, &idRslvr, 0, true, idRslvr.GetTypeId(), 0, 1000, 19);
     PortableReader reader(&readerImpl);
 
-    in.Position(18);
+    in.Position(19);
 
     PortableRawReader rawReader = reader.RawReader();
 
@@ -1908,6 +1908,7 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
 
     int32_t pos = in.Position();
     in.ReadInt8(); // We do not need a header here.
+    in.ReadInt8(); // We do not need proto ver here.
     bool usrType = in.ReadBool();
     int32_t typeId = in.ReadInt32();
     int32_t hashCode = in.ReadInt32();
@@ -1924,34 +1925,34 @@ BOOST_AUTO_TEST_CASE(TestFieldSeek)
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
 
     // 2. Counter closkwise.
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     // 3. Same field twice.
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     
     // 4. Read missing field in between.
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
     BOOST_REQUIRE(reader.ReadInt32("missing") == 0);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
 
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val2") == 2);
     BOOST_REQUIRE(reader.ReadInt32("missing") == 0);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     // 5. Invalid field type.
-    in.Position(18);
+    in.Position(19);
     BOOST_REQUIRE(reader.ReadInt32("val1") == 1);
 
     try

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
index 622cb54..9efaa28 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_common.h
@@ -35,8 +35,17 @@ namespace ignite
             /** Header: fulle form. */
             const int8_t IGNITE_HDR_FULL = 103;
 
+            /** Portable protocol version.  */
+            const int8_t IGNITE_PROTO_VER = 1;
+
             /** Full header length. */
-            const int32_t IGNITE_FULL_HDR_LEN = 18;
+            const int32_t IGNITE_FULL_HDR_LEN = 19;
+
+            /** Header offset: length. */
+            const int32_t IGNITE_OFFSET_LEN = 11;
+
+            /** Header offset: raw offset. */
+            const int32_t IGNITE_OFFSET_RAW = 15;
 
             /** Type: object. */
             const int8_t IGNITE_TYPE_OBJECT = IGNITE_HDR_FULL;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
index 5050a04..08b8fe1 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_reader_impl.h
@@ -747,22 +747,34 @@ namespace ignite
                     }
                     else
                     {
-                        bool usrType = stream->ReadBool();
-                        int32_t typeId = stream->ReadInt32();
-                        int32_t hashCode = stream->ReadInt32();
-                        int32_t len = stream->ReadInt32();
-                        int32_t rawOff = stream->ReadInt32();
+                        if (hdr != IGNITE_HDR_FULL) {
+                            IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, "Unexpected header during deserialization: ", hdr);
+                        }
+                        else {
+                            int8_t protoVer = stream->ReadInt8();
 
-                        ignite::portable::PortableType<T> type;
-                        TemplatedPortableIdResolver<T> idRslvr(type);
-                        PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType, typeId, hashCode, len, rawOff);
-                        ignite::portable::PortableReader reader(&readerImpl);
+                            if (protoVer != IGNITE_PROTO_VER) {
+                                IGNITE_ERROR_2(ignite::IgniteError::IGNITE_ERR_PORTABLE, "Unsupported portable protocol version: ", protoVer);
+                            }
+                            else {
+                                bool usrType = stream->ReadBool();
+                                int32_t typeId = stream->ReadInt32();
+                                int32_t hashCode = stream->ReadInt32();
+                                int32_t len = stream->ReadInt32();
+                                int32_t rawOff = stream->ReadInt32();
 
-                        T val = type.Read(reader);
+                                ignite::portable::PortableType<T> type;
+                                TemplatedPortableIdResolver<T> idRslvr(type);
+                                PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType, typeId, hashCode, len, rawOff);
+                                ignite::portable::PortableReader reader(&readerImpl);
 
-                        stream->Position(pos + len);
+                                T val = type.Read(reader);
 
-                        return val;
+                                stream->Position(pos + len);
+
+                                return val;
+                            }
+                        }
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
index 0259a7e..2d94dbf 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/portable/portable_writer_impl.h
@@ -608,6 +608,7 @@ namespace ignite
                         int32_t pos = stream->Position();
 
                         stream->WriteInt8(IGNITE_HDR_FULL);
+                        stream->WriteInt8(IGNITE_PROTO_VER);
                         stream->WriteBool(true);
                         stream->WriteInt32(idRslvr.GetTypeId());
                         stream->WriteInt32(type.GetHashCode(obj));
@@ -618,8 +619,8 @@ namespace ignite
 
                         int32_t len = stream->Position() - pos;
 
-                        stream->WriteInt32(pos + 10, len);
-                        stream->WriteInt32(pos + 14, writerImpl.GetRawPosition() - pos);
+                        stream->WriteInt32(pos + IGNITE_OFFSET_LEN, len);
+                        stream->WriteInt32(pos + IGNITE_OFFSET_RAW, writerImpl.GetRawPosition() - pos);
 
                         if (metaMgr)
                             metaMgr->SubmitHandler(type.GetTypeName(), idRslvr.GetTypeId(), metaHnd.Get());

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
index c65038c..69c2811 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableBuilderImpl.cs
@@ -36,10 +36,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
         /** Cached dictionary with no values. */
         private static readonly IDictionary<int, object> EmptyVals = new Dictionary<int, object>();
-
-        /** Offset: length. */
-        private const int OffsetLen = 10;
-
+        
         /** Portables. */
         private readonly PortablesImpl _portables;
 
@@ -387,6 +384,8 @@ namespace Apache.Ignite.Core.Impl.Portable
             }
             else if (inHdr == PortableUtils.HdrFull)
             {
+                PortableUtils.ValidateProtocolVersion(inStream);
+
                 byte inUsrFlag = inStream.ReadByte();
                 int inTypeId = inStream.ReadInt();
                 int inHash = inStream.ReadInt();
@@ -407,6 +406,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                     {
                         // New object, write in full form.
                         outStream.WriteByte(PortableUtils.HdrFull);
+                        outStream.WriteByte(PortableUtils.ProtoVer);
                         outStream.WriteByte(inUsrFlag);
                         outStream.WriteInt(inTypeId);
                         outStream.WriteInt(changeHash ? hash : inHash);
@@ -491,7 +491,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                         // Write length and raw data offset.
                         int outResPos = outStream.Position;
 
-                        outStream.Seek(outStartPos + OffsetLen, SeekOrigin.Begin);
+                        outStream.Seek(outStartPos + PortableUtils.OffsetLen, SeekOrigin.Begin);
 
                         outStream.WriteInt(outResPos - outStartPos); // Length.
                         outStream.WriteInt(rawPos - outStartPos); // Raw offset.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
index fe5f5c9..ff9aa34 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableReaderImpl.cs
@@ -672,7 +672,7 @@ namespace Apache.Ignite.Core.Impl.Portable
                 if (!doDetach)
                     return GetPortableUserObject(pos, pos, Stream.Array());
                 
-                Stream.Seek(pos + 10, SeekOrigin.Begin);
+                Stream.Seek(pos + PortableUtils.OffsetLen, SeekOrigin.Begin);
 
                 var len = Stream.ReadInt();
 
@@ -692,6 +692,9 @@ namespace Apache.Ignite.Core.Impl.Portable
         [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "hashCode")]
         private T ReadFullObject<T>(int pos)
         {
+            // Validate protocol version.
+            PortableUtils.ValidateProtocolVersion(Stream);
+
             // Read header.
             bool userType = Stream.ReadBool();
             int typeId = Stream.ReadInt();
@@ -883,7 +886,7 @@ namespace Apache.Ignite.Core.Impl.Portable
         {
             // This method is expected to be called when stream pointer is set either before
             // the field or on raw data offset.
-            int start = _curPos + 18;
+            int start = _curPos + PortableUtils.FullHdrLen;
             int end = _curPos + _curRawOffset;
 
             int initial = Stream.Position;
@@ -1005,7 +1008,7 @@ namespace Apache.Ignite.Core.Impl.Portable
         /// <param name="bytes">Bytes.</param>
         private PortableUserObject GetPortableUserObject(int pos, int offs, byte[] bytes)
         {
-            Stream.Seek(pos + 2, SeekOrigin.Begin);
+            Stream.Seek(pos + PortableUtils.OffsetTypeId, SeekOrigin.Begin);
 
             var id = Stream.ReadInt();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
index 891f261..9df180d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUserObject.cs
@@ -186,7 +186,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             {
                 IPortableStream stream = new PortableHeapStream(_data);
 
-                stream.Seek(_offset + 14, SeekOrigin.Begin);
+                stream.Seek(_offset + PortableUtils.OffsetRaw, SeekOrigin.Begin);
 
                 int rawDataOffset = stream.ReadInt();
 
@@ -256,12 +256,12 @@ namespace Apache.Ignite.Core.Impl.Portable
 
                     // 4. Check if objects have the same raw data.
                     IPortableStream stream = new PortableHeapStream(_data);
-                    stream.Seek(_offset + 10, SeekOrigin.Begin);
+                    stream.Seek(_offset + PortableUtils.OffsetLen, SeekOrigin.Begin);
                     int len = stream.ReadInt();
                     int rawOffset = stream.ReadInt();
 
                     IPortableStream thatStream = new PortableHeapStream(that._data);
-                    thatStream.Seek(_offset + 10, SeekOrigin.Begin);
+                    thatStream.Seek(_offset + PortableUtils.OffsetLen, SeekOrigin.Begin);
                     int thatLen = thatStream.ReadInt();
                     int thatRawOffset = thatStream.ReadInt();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
index c7be496..15466d5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableUtils.cs
@@ -27,6 +27,7 @@ namespace Apache.Ignite.Core.Impl.Portable
     using System.Reflection;
     using System.Runtime.InteropServices;
     using System.Runtime.Serialization.Formatters.Binary;
+    using System.Security.Policy;
     using System.Text;
     using Apache.Ignite.Core.Impl.Common;
     using Apache.Ignite.Core.Impl.Portable.IO;
@@ -48,9 +49,24 @@ namespace Apache.Ignite.Core.Impl.Portable
 
         /** Header of object in fully serialized form. */
         public const byte HdrFull = 103;
-        
+
+        /** Protocol versnion. */
+        public const byte ProtoVer = 1;
+
         /** Full header length. */
-        public const int FullHdrLen = 18;
+        public const int FullHdrLen = 19;
+
+        /** Offset: hash code. */
+        public const int OffsetTypeId = 3;
+
+        /** Offset: hash code. */
+        public const int OffsetHashCode = 7;
+
+        /** Offset: length. */
+        public const int OffsetLen = 11;
+
+        /** Offset: raw data offset. */
+        public const int OffsetRaw = 15;
 
         /** Type: object. */
         public const byte TypeObject = HdrFull;
@@ -1763,7 +1779,7 @@ namespace Apache.Ignite.Core.Impl.Portable
          */
         public static IDictionary<int, int> ObjectFields(IPortableStream stream, int typeId, int rawDataOffset)
         {
-            int endPos = stream.Position + rawDataOffset - 18;
+            int endPos = stream.Position + rawDataOffset - FullHdrLen;
 
             // First loop detects amount of fields in the object.
             int retPos = stream.Position;
@@ -2011,6 +2027,18 @@ namespace Apache.Ignite.Core.Impl.Portable
             return null;
         }
 
+        /// <summary>
+        /// Validate protocol version.
+        /// </summary>
+        /// <param name="stream">Stream.</param>
+        public static void ValidateProtocolVersion(IPortableStream stream)
+        {
+            byte ver = stream.ReadByte();
+
+            if (ver != ProtoVer)
+                throw new PortableException("Unsupported protocol version: " + ver);
+        }
+
         /**
          * <summary>Convert date to Java ticks.</summary>
          * <param name="date">Date</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
index b490460..5a66a0f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs
@@ -1191,6 +1191,7 @@ namespace Apache.Ignite.Core.Impl.Portable
 
                 // Write header.
                 _stream.WriteByte(PU.HdrFull);
+                _stream.WriteByte(PU.ProtoVer);
                 _stream.WriteBool(desc.UserType);
                 _stream.WriteInt(desc.TypeId);
                 _stream.WriteInt(obj.GetHashCode());
@@ -1226,12 +1227,12 @@ namespace Apache.Ignite.Core.Impl.Portable
                 // Calculate and write length.
                 int len = _stream.Position - pos;
 
-                _stream.WriteInt(pos + 10, len);
-
+                _stream.WriteInt(pos + PU.OffsetLen, len);
+                
                 if (_curRawPos != 0)
-                    _stream.WriteInt(pos + 14, (int)(_curRawPos - pos));
+                    _stream.WriteInt(pos + PU.OffsetRaw, (int)(_curRawPos - pos));
                 else
-                    _stream.WriteInt(pos + 14, len);
+                    _stream.WriteInt(pos + PU.OffsetRaw, len);
 
                 // Apply structure updates if any.
                 if (_curStructUpdates != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d85fa945/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
index 5b73171..451386b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortablesImpl.cs
@@ -167,6 +167,7 @@ namespace Apache.Ignite.Core.Impl.Portable
             PortableHeapStream stream = new PortableHeapStream(18);
 
             stream.WriteByte(PortableUtils.HdrFull);
+            stream.WriteByte(PortableUtils.ProtoVer);
             stream.WriteBool(true);
             stream.WriteInt(desc.TypeId);
             stream.WriteInt(0); // Hash.